Skip to content

Commit

Permalink
fix: connecting sibling pointers when leaf node is removed
Browse files Browse the repository at this point in the history
  • Loading branch information
sepgh committed May 25, 2024
1 parent 618bdcf commit e8e4a57
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -471,12 +471,44 @@ private void merge(int table, InternalTreeNode parent, BaseTreeNode child, int i
child.setAsRoot();
parent.unsetAsRoot();
}
if (child.isLeaf()) {
assert child instanceof LeafTreeNode;
this.connectSiblings((LeafTreeNode) child, table);
}
TreeNodeIO.update(indexStorageManager, table, child);
TreeNodeIO.remove(indexStorageManager, table, parent);
}else{
TreeNodeIO.update(indexStorageManager, table, parent, child);
}
if (toRemove.isLeaf()) {
assert toRemove instanceof LeafTreeNode;
this.connectSiblings((LeafTreeNode) toRemove, table);
}
TreeNodeIO.remove(indexStorageManager, table, toRemove);
}

private void connectSiblings(LeafTreeNode toRemove, int table) throws ExecutionException, InterruptedException, IOException {
Optional<Pointer> optionalNextSiblingPointer = toRemove.getNextSiblingPointer(degree);
Optional<Pointer> optionalPreviousSiblingPointer = toRemove.getPreviousSiblingPointer(degree);
if (optionalNextSiblingPointer.isPresent()){
LeafTreeNode nextNode = (LeafTreeNode) TreeNodeIO.read(indexStorageManager, table, optionalNextSiblingPointer.get());
if (optionalPreviousSiblingPointer.isPresent()){
nextNode.setPreviousSiblingPointer(optionalPreviousSiblingPointer.get(), degree);
} else {
nextNode.setPreviousSiblingPointer(Pointer.empty(), degree);
}
TreeNodeIO.update(indexStorageManager, table, nextNode);
}

if (optionalPreviousSiblingPointer.isPresent()){
LeafTreeNode previousNode = (LeafTreeNode) TreeNodeIO.read(indexStorageManager, table, optionalPreviousSiblingPointer.get());
if (optionalNextSiblingPointer.isPresent()){
previousNode.setNextSiblingPointer(optionalNextSiblingPointer.get(), degree);
} else {
previousNode.setNextSiblingPointer(Pointer.empty(), degree);
}
TreeNodeIO.update(indexStorageManager, table, previousNode);
}

}

Expand Down
8 changes: 8 additions & 0 deletions src/main/java/com/github/sepgh/internal/tree/Pointer.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ public static Pointer fromBytes(byte[] bytes, int position){
);
}

public static Pointer empty(){
return new Pointer(
(byte) 0x00,
0,
0
);
}

public static Pointer fromBytes(byte[] bytes){
return Pointer.fromBytes(bytes, 0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,14 @@ public void testRemovingRoot() throws IOException, ExecutionException, Interrupt
Assertions.assertEquals(1, root.getKeyList(degree).size());
Assertions.assertEquals(10, root.getKeyList(degree).getFirst());

// Testing next / prev state
Pointer lastLeafFromLeftPointer = ((InternalTreeNode) TreeNodeIO.read(fileIndexStorageManager, 1, root.getChildrenList().getFirst())).getChildrenList().getLast();
Pointer firstLeafFromRightPointer = ((InternalTreeNode) TreeNodeIO.read(fileIndexStorageManager, 1, root.getChildrenList().getLast())).getChildrenList().getFirst();

Assertions.assertEquals(lastLeafFromLeftPointer, ((LeafTreeNode) TreeNodeIO.read(fileIndexStorageManager, 1, firstLeafFromRightPointer)).getPreviousSiblingPointer(degree).get());
Assertions.assertEquals(firstLeafFromRightPointer, ((LeafTreeNode) TreeNodeIO.read(fileIndexStorageManager, 1, lastLeafFromLeftPointer)).getNextSiblingPointer(degree).get());


Assertions.assertTrue(indexManager.removeIndex(1, 10));
Assertions.assertFalse(indexManager.removeIndex(1, 10));

Expand Down

0 comments on commit e8e4a57

Please sign in to comment.