Skiplist::position_and_count fix
Summary: Fixed bug for SkipList::position_and_count for an item lesser then all skiplist elements. Reviewers: mislav.bradac Reviewed By: mislav.bradac Differential Revision: https://phabricator.memgraph.io/D629
This commit is contained in:
parent
31ee8a148f
commit
bb5d06e276
@ -621,7 +621,7 @@ class SkipList : private Lockable<lock_t> {
|
|||||||
// now we need to estimate the count of elements equal to item
|
// now we need to estimate the count of elements equal to item
|
||||||
// we'll do that by looking for the first element that is greater
|
// we'll do that by looking for the first element that is greater
|
||||||
// than item, and counting how far we have to look
|
// than item, and counting how far we have to look
|
||||||
|
|
||||||
// first find the rightmost (highest) succ that has value == item
|
// first find the rightmost (highest) succ that has value == item
|
||||||
int count_level = 0;
|
int count_level = 0;
|
||||||
for (int i = position_level; i >= 0; i--)
|
for (int i = position_level; i >= 0; i--)
|
||||||
@ -632,6 +632,10 @@ class SkipList : private Lockable<lock_t> {
|
|||||||
count_level = std::min(count_level, count_max_level);
|
count_level = std::min(count_level, count_max_level);
|
||||||
succ = succs[count_level];
|
succ = succs[count_level];
|
||||||
|
|
||||||
|
// it is possible that succ just became null (even though before
|
||||||
|
// it wasn't). that happens when item is lesser then all list elems
|
||||||
|
if (!succ) return std::make_pair(0, 0);
|
||||||
|
|
||||||
// now expand to the right as long as element value == item
|
// now expand to the right as long as element value == item
|
||||||
// at the same time accumulate count
|
// at the same time accumulate count
|
||||||
int count = 1 << count_level;
|
int count = 1 << count_level;
|
||||||
|
@ -87,3 +87,24 @@ TEST(SkiplistPosAndCount, DefaultSpeedAndAccuracy) {
|
|||||||
// estimations are always absolutely accurate
|
// estimations are always absolutely accurate
|
||||||
EXPECT_POS_COUNT(5000, 5000, 0, 0, 0);
|
EXPECT_POS_COUNT(5000, 5000, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define EXPECT_FOR_OUT_OF_RANGE(skiplist_size, value) \
|
||||||
|
{ \
|
||||||
|
auto sl = SkiplistRange(skiplist_size); \
|
||||||
|
auto position_and_count = sl->access().position_and_count(value); \
|
||||||
|
EXPECT_EQ(position_and_count.first, value < 0 ? 0 : skiplist_size); \
|
||||||
|
EXPECT_EQ(position_and_count.second, 0); \
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SkiplistPosAndCount, EdgeValues) {
|
||||||
|
// small list
|
||||||
|
EXPECT_FOR_OUT_OF_RANGE(100, -20);
|
||||||
|
EXPECT_FOR_OUT_OF_RANGE(100, -1);
|
||||||
|
EXPECT_FOR_OUT_OF_RANGE(100, 100);
|
||||||
|
EXPECT_FOR_OUT_OF_RANGE(100, 120);
|
||||||
|
// big list
|
||||||
|
EXPECT_FOR_OUT_OF_RANGE(100000, -20);
|
||||||
|
EXPECT_FOR_OUT_OF_RANGE(100000, -1);
|
||||||
|
EXPECT_FOR_OUT_OF_RANGE(100000, 100000);
|
||||||
|
EXPECT_FOR_OUT_OF_RANGE(100000, 100300);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user