Skip to content

Commit a84fa16

Browse files
committed
use simulated geometric process; update check-integrity test
Signed-off-by: Yuchen Liang <[email protected]>
1 parent 1ee6a50 commit a84fa16

File tree

3 files changed

+18
-28
lines changed

3 files changed

+18
-28
lines changed

src/include/primer/skiplist.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,6 @@ class SkipList {
109109
/** @brief Number of elements in the skip list. */
110110
size_t size_{0};
111111

112-
/**
113-
* @brief Geometric distribution for generating random level.
114-
*
115-
* Note: p=0.25 is a common choice for skip lists, also analyzed in Pugh's original paper.
116-
*/
117-
std::geometric_distribution<uint32_t> dist_{0.25};
118-
119112
/** @brief Random number generator. */
120113
std::mt19937 rng_{Seed};
121114

src/primer/skiplist.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,17 @@ SKIPLIST_TEMPLATE_ARGUMENTS void SkipList<K, Compare, MaxHeight, Seed>::Print()
109109

110110
/**
111111
* @brief Generate a random height. The height should be cappped at `MaxHeight`.
112-
*
113-
* Note: consider using `std::geometric_distribution` with the random number generator provided in header.
112+
* Note: we implement/simulate the geometric process to ensure platform independence.
114113
*/
115114
SKIPLIST_TEMPLATE_ARGUMENTS auto SkipList<K, Compare, MaxHeight, Seed>::RandomHeight() -> size_t {
116-
// Note: `std::geometric_distribution` generates a random integer
117-
// in the range [0,`std::numeric_limits<uint32_t>::max()`).
118-
// Increment 1 and apply `std::min` so that the result is in the
119-
// range of [1,`MaxHeight`).
120-
UNIMPLEMENTED("TODO(P0): Add implementation.");
115+
// Branching factor (1 in 4 chance), see Pugh's paper.
116+
static constexpr unsigned int branching_factor = 4;
117+
// Start with the minimum height
118+
size_t height = 1;
119+
while (height < MaxHeight && (rng_() % branching_factor == 0)) {
120+
height++;
121+
}
122+
return height;
121123
}
122124

123125
/**

test/primer/skiplist_test.cpp

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,28 +81,23 @@ TEST(SkipListTest, IntegrityCheckTest) {
8181
InstrumentedSkipList<int> list;
8282

8383
// All the keys we will insert into the skip list (1 to 20).
84-
std::vector<int> keys = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
84+
std::vector<int> keys = {12, 16, 2, 6, 15, 8, 13, 1, 11, 14, 0, 4, 19, 10, 9, 5, 7, 3, 17, 18};
8585

8686
// Heights of the nodes in the skip list.
8787
// These will not change since we fixed the seed of the random number generator.
88-
std::vector<uint32_t> heights = {3, 4, 1, 1, 2, 2, 2, 6, 1, 3, 3, 9, 3, 1, 1, 1, 2, 4, 5, 3};
88+
std::vector<uint32_t> heights = {2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 2, 1, 3, 1, 1, 2, 1, 1, 2, 3};
8989

90-
// Keys to insert in a shuffled order.
91-
auto shuffled_keys = keys;
92-
std::shuffle(shuffled_keys.begin(), shuffled_keys.end(), std::mt19937{0});
93-
94-
std::vector<uint32_t> shuffled_heights(20, 0);
95-
for (size_t i = 0; i < 20; ++i) {
96-
shuffled_heights[shuffled_keys[i]] = heights[i];
97-
}
98-
99-
// Insert the keys in a shuffled order.
100-
for (auto key : shuffled_keys) {
90+
// Insert the keys
91+
for (auto key : keys) {
10192
list.Insert(key);
10293
}
10394

95+
// Sort the keys
96+
std::sort(keys.begin(), keys.end());
97+
98+
list.Print();
10499
// Check that we construct the skip list as expected.
105-
list.CheckIntegrity(keys, shuffled_heights);
100+
list.CheckIntegrity(keys, heights);
106101
}
107102

108103
TEST(SkipListTest, InsertContainsTest1) {

0 commit comments

Comments
 (0)