diff --git a/src/main/java/com/github/sepgh/internal/tree/BPlusTreeIndexManager.java b/src/main/java/com/github/sepgh/internal/tree/BPlusTreeIndexManager.java index c515de0..39bab85 100644 --- a/src/main/java/com/github/sepgh/internal/tree/BPlusTreeIndexManager.java +++ b/src/main/java/com/github/sepgh/internal/tree/BPlusTreeIndexManager.java @@ -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 optionalNextSiblingPointer = toRemove.getNextSiblingPointer(degree); + Optional 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); + } } diff --git a/src/main/java/com/github/sepgh/internal/tree/Pointer.java b/src/main/java/com/github/sepgh/internal/tree/Pointer.java index d356af3..652355e 100644 --- a/src/main/java/com/github/sepgh/internal/tree/Pointer.java +++ b/src/main/java/com/github/sepgh/internal/tree/Pointer.java @@ -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); } diff --git a/src/test/java/com/github/sepgh/internal/tree/removing/BPlusTreeIndexManagerTestCase.java b/src/test/java/com/github/sepgh/internal/tree/removing/BPlusTreeIndexManagerTestCase.java index 8dc34fb..c72d711 100644 --- a/src/test/java/com/github/sepgh/internal/tree/removing/BPlusTreeIndexManagerTestCase.java +++ b/src/test/java/com/github/sepgh/internal/tree/removing/BPlusTreeIndexManagerTestCase.java @@ -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));