YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/util/memory/tracked_shared_ptr-test.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) YugaByte, Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4
// in compliance with the License.  You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software distributed under the License
9
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10
// or implied.  See the License for the specific language governing permissions and limitations
11
// under the License.
12
//
13
14
#include <limits>
15
16
#include <gtest/gtest.h>
17
18
#include "yb/util/memory/tracked_shared_ptr.h"
19
#include "yb/util/memory/tracked_shared_ptr_impl.h"
20
#include "yb/util/random_util.h"
21
22
using std::numeric_limits;
23
24
namespace yb {
25
26
class TestObj {
27
 public:
28
11.0k
  TestObj(size_t index, size_t* counter) : index_(index), counter_(counter) {
29
11.0k
    ++(*counter_);
30
11.0k
  }
31
326k
  ~TestObj() { --(*counter_); }
32
2.00k
  size_t index() { return index_; }
33
34
8
  std::string ToString() const {
35
8
    return Format("TestObj { index: $0 }", index_);
36
8
  }
37
38
 private:
39
  size_t index_;
40
  size_t* counter_;
41
};
42
43
// Doesn't actually test dump, but gives some examples of output.
44
1
TEST(TrackedSharedPtr, DumpExample) {
45
1
  std::vector<TrackedSharedPtr<TestObj>> ptrs;
46
1
  size_t counter = 0;
47
1
  const TrackedSharedPtr<TestObj> p1 = std::make_shared<TestObj>(1, &counter);
48
1
  const TrackedSharedPtr<TestObj> p2 = std::make_shared<TestObj>(2, &counter);
49
1
  LOG(INFO) << "p1: " << AsString(p1);
50
1
  LOG(INFO) << "p2: " << AsString(p2);
51
1
  {
52
1
    const TrackedSharedPtr<TestObj> p1_2 = p1;
53
1
    LOG(INFO) << "p1_2: " << AsString(p1_2);
54
1
    TrackedSharedPtr<TestObj>::Dump();
55
1
  }
56
1
  TrackedSharedPtr<TestObj>::Dump();
57
1
}
58
59
// Performs random operations with tracked shared pointers and checks invariants.
60
1
TEST(TrackedSharedPtr, RandomOps) {
61
1
  static constexpr size_t kNumObjects = 1000;
62
1
  static constexpr size_t kNumIterations = 50000;
63
64
1
  size_t counter = { 0 };
65
66
1
  {
67
1
    std::vector<TrackedSharedPtr<TestObj>> ptrs;
68
1
    ptrs.reserve(kNumObjects);
69
70
1.00k
    for (size_t i = 0; i < kNumObjects; ++i) {
71
1.00k
      ptrs.push_back(std::make_shared<TestObj>(i, &counter));
72
1.00k
    }
73
1
    EXPECT_EQ(kNumObjects, counter);
74
1.00k
    for (size_t i = 0; i < kNumObjects; ++i) {
75
1.00k
      ASSERT_EQ(ptrs[i].get()->index(), i);
76
1.00k
    }
77
78
1
    std::mt19937 rng;
79
1
    Seed(&rng);
80
1
    std::uniform_int_distribution<size_t> random_op(0, 4);
81
1
    std::uniform_int_distribution<size_t> random_index(0, kNumObjects - 1);
82
83
50.0k
    for (size_t i = 0; i < kNumIterations; ++i) {
84
50.0k
      switch (random_op(rng)) {
85
9.98k
        case 0: {
86
          // Get.
87
9.98k
          auto i1 = random_index(rng);
88
9.98k
          ptrs[i1].get();
89
9.98k
          break;
90
0
        }
91
9.92k
        case 1: {
92
9.92k
          break;
93
0
        }
94
10.0k
        case 2: {
95
          // Reset.
96
10.0k
          auto i1 = random_index(rng);
97
10.0k
          ptrs[i1].reset(new TestObj(i1, &counter));
98
10.0k
          break;
99
0
        }
100
10.0k
        case 3: {
101
          // Assign.
102
10.0k
          auto i1 = random_index(rng);
103
10.0k
          auto i2 = random_index(rng);
104
10.0k
          ptrs[i1] = std::move(ptrs[i2]);
105
10.0k
          break;
106
0
        }
107
10.0k
        case 4: {
108
          // Move construction.
109
10.0k
          auto i1 = random_index(rng);
110
10.0k
          if (ptrs[i1]) {
111
5.33k
            TrackedSharedPtr<TestObj> ptr(std::move(ptrs[i1]));
112
5.33k
          }
113
10.0k
          break;
114
0
        }
115
0
        default:
116
0
          ASSERT_TRUE(false) << "Test internal error, missed case in switch";
117
0
          break;
118
50.0k
      }
119
50.0k
    }
120
1
  }
121
1
  EXPECT_EQ(0, counter);
122
1
  EXPECT_EQ(0, TrackedSharedPtr<TestObj>::num_instances());
123
1
  EXPECT_EQ(0, TrackedSharedPtr<TestObj>::num_references());
124
1
}
125
126
} // namespace yb