Skip to content

Commit 7fab2aa

Browse files
Anirudh KanjaniAnirudh Kanjani
authored andcommitted
Handling duplicates
1 parent c4779a2 commit 7fab2aa

File tree

2 files changed

+60
-17
lines changed

2 files changed

+60
-17
lines changed

src/include/index/skiplist.h

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ class SkipList {
221221

222222
public:
223223

224-
SkipList(KeyComparator key_cmp_obj, KeyEqualityChecker key_eq_check_obj) :
225-
key_cmp_obj_(key_cmp_obj), key_eq_check_obj_(key_eq_check_obj) {
224+
SkipList(KeyComparator key_cmp_obj, KeyEqualityChecker key_eq_check_obj, bool is_unique) :
225+
key_cmp_obj_(key_cmp_obj), key_eq_check_obj_(key_eq_check_obj), is_unique_(is_unique) {
226226
// InitHeadTower();
227227
// No tower root needed or set for head tower
228228
root_ = new SKIPLISTHEADNODE_TYPE(nullptr, nullptr, nullptr, nullptr, 1);
@@ -308,9 +308,7 @@ class SkipList {
308308
int curr_level = reinterpret_cast<SKIPLISTHEADNODE_TYPE *>(curr_node)->GetLevel();
309309

310310
NodeNodePair node_node;
311-
// while (curr_level > level) {
312311

313-
// int curr_level = node_level.second;
314312
while (curr_level > level) { // search down to level v + 1
315313
if(traversal_mode == SKIPLISTNODE_TYPE::TraversalMode::GO_DOWN_ON_LEQ)
316314
node_node = SearchRightLEQ(key, curr_node);
@@ -326,8 +324,6 @@ class SkipList {
326324
node_node = SearchRightLEQ(key, curr_node);
327325
else if(traversal_mode == SKIPLISTNODE_TYPE::TraversalMode::GO_DOWN_ON_LT)
328326
node_node = SearchRightLT(key, curr_node);
329-
330-
331327
return node_node;
332328
}
333329

@@ -430,27 +426,70 @@ class SkipList {
430426
}
431427

432428

429+
bool DuplicateKeyValue(const NodeNodePair &arg_pair, const KeyType &key, const ValueType &value) {
430+
assert(arg_pair.first);
431+
if (arg_pair.second == nullptr) {
432+
return false;
433+
}
434+
SKIPLISTNODE_TYPE *curr_node = arg_pair.first, *next_node = arg_pair.second;
435+
while(next_node && key_cmp_obj_(next_node->GetKey(), key)<=0){
436+
/*
437+
* next_node has been marked for deletion,
438+
* help with the deletion and then
439+
* continue traversing.
440+
*/
441+
while(next_node!=nullptr && SKIPLISTNODE_TYPE::IsMarkedReference(next_node->GetTowerRoot()->GetSucc())){
442+
NodeStatusResultTuple tuple = TryFlagNode(curr_node, next_node);
443+
444+
StatusType status = std::get<1>(tuple);
445+
446+
if(status==StatusType::FLAGGED){
447+
HelpFlagged(curr_node, next_node);
448+
}
449+
next_node = curr_node->GetRight();
450+
}
451+
if (next_node && key_eq_check_obj_(next_node->GetKey(), key) &&
452+
val_eq_check_obj_(reinterpret_cast<SKIPLISTLEAFNODE_TYPE *>(next_node)->GetValue(), value)) {
453+
return true;
454+
}
455+
456+
if(next_node && key_cmp_obj_(next_node->GetKey(), key)<=0) {
457+
curr_node = next_node;
458+
next_node = curr_node->GetRight();
459+
}
460+
}
461+
return false;
462+
}
463+
433464

434465
bool Insert(const KeyType &key, const ValueType &value) {
435466

436467
int tower_height = 1, curr_level = 1;
437468

438469

439-
NodeNodePair node_node = SearchToLevel(key, 1, SKIPLISTNODE_TYPE::TraversalMode::GO_DOWN_ON_LEQ);
470+
NodeNodePair node_node;
471+
if (is_unique_) {
472+
node_node = SearchToLevel(key, 1, SKIPLISTNODE_TYPE::TraversalMode::GO_DOWN_ON_LEQ);
473+
} else {
474+
node_node = SearchToLevel(key, 1, SKIPLISTNODE_TYPE::TraversalMode::GO_DOWN_ON_LT);
475+
}
440476

441477

442478
SKIPLISTNODE_TYPE *inserted_node;
443479
SKIPLISTNODE_TYPE *prev_node = node_node.first, *next_node = node_node.second;
444480

445481
PL_ASSERT(prev_node);
446482

447-
448-
if(prev_node->GetTowerType() != SKIPLISTNODE_TYPE::TowerType::HEAD_TOWER) {
483+
if (is_unique_ && prev_node->GetTowerType() != SKIPLISTNODE_TYPE::TowerType::HEAD_TOWER) {
449484
if (key_eq_check_obj_(prev_node->GetKey(), key)) {
450485
return false; // DUPLICATE
451486
}
452487
}
453488

489+
if (is_unique_ == false && DuplicateKeyValue(node_node, key, value)) {
490+
return false;
491+
}
492+
454493
SKIPLISTNODE_TYPE *new_root_node = reinterpret_cast<SKIPLISTNODE_TYPE *>(
455494
new SKIPLISTLEAFNODE_TYPE(
456495
key, SKIPLISTNODE_TYPE::TowerType::MIDDLE_TOWER,
@@ -494,7 +533,7 @@ class SkipList {
494533
if(SKIPLISTNODE_TYPE::IsMarkedReference(tower_root->GetSucc())){
495534
if (inserted_node == new_node && new_node != tower_root) {
496535
//TODO(gandeevan): uncomment this later
497-
//DeleteNode(prev_node, new_node);
536+
// DeleteNode(prev_node, new_node);
498537
}
499538
return true;
500539
}
@@ -511,8 +550,11 @@ class SkipList {
511550

512551
// NOTE: Search being done for level 1, 2, ....n. This might hurt performance if not a lot of concurrency.
513552
// Should we also store the prev and curr at every level while doing searchtolevel?
514-
result_pair = SearchToLevel(key, curr_level, SKIPLISTNODE_TYPE::TraversalMode::GO_DOWN_ON_LEQ);
515-
553+
if (is_unique_) {
554+
result_pair = SearchToLevel(key, curr_level, SKIPLISTNODE_TYPE::TraversalMode::GO_DOWN_ON_LEQ);
555+
} else {
556+
result_pair = SearchToLevel(key, curr_level, SKIPLISTNODE_TYPE::TraversalMode::GO_DOWN_ON_LT);
557+
}
516558
prev_node = result_pair.first;
517559
next_node = result_pair.second;
518560
}
@@ -566,14 +608,13 @@ class SkipList {
566608

567609
bool Delete(const KeyType &key, const ValueType &value) {
568610

569-
(void) value;
570-
571611
NodeNodePair result = SearchToLevel(key, 1, SKIPLISTNODE_TYPE::TraversalMode::GO_DOWN_ON_LT);
572612
if (!key_eq_check_obj_(result.second->GetKey(), key)) {
573613
return false;
574614
}
575-
576-
615+
if (is_unique_ == false && !DuplicateKeyValue(result, key, value)) {
616+
return false;
617+
}
577618

578619
/* Unlinks the root node of the tower */
579620
SKIPLISTNODE_TYPE *root_node = DeleteNode(result.first, result.second);
@@ -691,6 +732,8 @@ class SkipList {
691732
SKIPLISTHEADNODE_TYPE *root_;
692733
const KeyComparator key_cmp_obj_;
693734
const KeyEqualityChecker key_eq_check_obj_;
735+
const ValueEqualityChecker val_eq_check_obj_;
736+
bool is_unique_;
694737
};
695738

696739
} // namespace index

src/index/skiplist_index.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ SKIPLIST_INDEX_TYPE::SkipListIndex(IndexMetadata *metadata)
2929
comparator{},
3030
// Key equality checker
3131
equals{},
32-
container(comparator, equals) {
32+
container(comparator, equals, HasUniqueKeys()) {
3333
return;
3434
}
3535

0 commit comments

Comments
 (0)