]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/util/heap_test.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
8 #include <gtest/gtest.h>
15 #include "port/stack_trace.h"
18 const int64_t FLAGS_iters
= 100000;
20 #include "util/gflags_compat.h"
21 DEFINE_int64(iters
, 100000, "number of pseudo-random operations in each test");
25 * Compares the custom heap implementation in util/heap.h against
26 * std::priority_queue on a pseudo-random sequence of operations.
29 namespace ROCKSDB_NAMESPACE
{
31 using HeapTestValue
= uint64_t;
32 using Params
= std::tuple
<size_t, HeapTestValue
, int64_t>;
34 class HeapTest
: public ::testing::TestWithParam
<Params
> {};
36 TEST_P(HeapTest
, Test
) {
37 // This test performs the same pseudorandom sequence of operations on a
38 // BinaryHeap and an std::priority_queue, comparing output. The three
39 // possible operations are insert, replace top and pop.
41 // Insert is chosen slightly more often than the others so that the size of
42 // the heap slowly grows. Once the size heats the MAX_HEAP_SIZE limit, we
43 // disallow inserting until the heap becomes empty, testing the "draining"
46 const auto MAX_HEAP_SIZE
= std::get
<0>(GetParam());
47 const auto MAX_VALUE
= std::get
<1>(GetParam());
48 const auto RNG_SEED
= std::get
<2>(GetParam());
50 BinaryHeap
<HeapTestValue
> heap
;
51 std::priority_queue
<HeapTestValue
> ref
;
53 std::mt19937
rng(static_cast<unsigned int>(RNG_SEED
));
54 std::uniform_int_distribution
<HeapTestValue
> value_dist(0, MAX_VALUE
);
56 bool draining
= false; // hit max size, draining until we empty the heap
58 for (int64_t i
= 0; i
< FLAGS_iters
; ++i
) {
63 if (!draining
&& (size
== 0 || std::bernoulli_distribution(0.4)(rng
))) {
65 HeapTestValue val
= value_dist(rng
);
69 if (size
== MAX_HEAP_SIZE
) {
73 } else if (std::bernoulli_distribution(0.5)(rng
)) {
75 HeapTestValue val
= value_dist(rng
);
76 heap
.replace_top(val
);
87 // After every operation, check that the public methods give the same
89 assert((size
== 0) == ref
.empty());
90 ASSERT_EQ(size
== 0, heap
.empty());
92 ASSERT_EQ(ref
.top(), heap
.top());
96 // Probabilities should be set up to occasionally hit the max heap size and
101 ASSERT_TRUE(heap
.empty());
104 // Basic test, MAX_VALUE = 3*MAX_HEAP_SIZE (occasional duplicates)
105 INSTANTIATE_TEST_CASE_P(Basic
, HeapTest
,
106 ::testing::Values(Params(1000, 3000,
107 0x1b575cf05b708945)));
108 // Mid-size heap with small values (many duplicates)
109 INSTANTIATE_TEST_CASE_P(SmallValues
, HeapTest
,
110 ::testing::Values(Params(100, 10, 0x5ae213f7bd5dccd0)));
111 // Small heap, large value range (no duplicates)
112 INSTANTIATE_TEST_CASE_P(SmallHeap
, HeapTest
,
113 ::testing::Values(Params(10, ULLONG_MAX
,
114 0x3e1fa8f4d01707cf)));
116 INSTANTIATE_TEST_CASE_P(TwoElementHeap
, HeapTest
,
117 ::testing::Values(Params(2, 5, 0x4b5e13ea988c6abc)));
119 INSTANTIATE_TEST_CASE_P(OneElementHeap
, HeapTest
,
120 ::testing::Values(Params(1, 3, 0x176a1019ab0b612e)));
122 } // namespace ROCKSDB_NAMESPACE
124 int main(int argc
, char** argv
) {
125 ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
126 ::testing::InitGoogleTest(&argc
, argv
);
128 GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc
, &argv
, true);
130 return RUN_ALL_TESTS();