public void TestBorrowLeft() { using (var pageStore = TestUtils.CreateEmptyPageStore("TestBorrowLeft.data")) { var tree = new BPlusTree(pageStore); var buff = new byte[_config.ValueSize]; var txnId = 0ul; for (int j = _config.LeafLoadFactor; j >= 0; j--) { tree.Insert(txnId, (ulong)j, BitConverter.GetBytes((ulong)j)); } tree.Delete(txnId, (ulong)(_config.LeafLoadFactor - 1), null); tree.Delete(txnId, (ulong)(_config.LeafLoadFactor - 2), null); // This should force a borrow from the left node for (int i = 0; i <= _config.LeafLoadFactor; i++) { Assert.IsTrue( i == (_config.LeafLoadFactor - 1) ^ i == (_config.LeafLoadFactor - 2) ^ tree.Search((ulong)i, buff, null), "Could not find entry for key {0}", i); } } }
public void TestBorrowRight() { using (var pageStore = TestUtils.CreateEmptyPageStore("TestBorrowRight.data")) { var txnId = 0ul; var tree = new BPlusTree(txnId, pageStore); var config = tree.Configuration; var buff = new byte[config.ValueSize]; for (int i = 0; i <= config.LeafLoadFactor; i++) { tree.Insert(txnId, (ulong)i, BitConverter.GetBytes((ulong)i)); } //Console.WriteLine("Before deletes:"); //tree.DumpStructure(); tree.Delete(txnId, 13ul, null); tree.Delete(txnId, 12ul, null); // Should force a borrow frrom the right node //Console.WriteLine("After Deletes"); //tree.DumpStructure(); for (int i = 0; i <= config.LeafLoadFactor; i++) { Assert.IsTrue(i == 12 ^ i == 13 ^ tree.Search((ulong)i, buff, null), "Could not find entry for key {0}", i); } } }
public void TestMergeRight() { using (var pageStore = TestUtils.CreateEmptyPageStore("TestMergeRight.data")) { var tree = new BPlusTree(pageStore); var testBytes = new byte[] { 1, 2, 3, 4 }; var buff = new byte[_config.ValueSize]; var txnId = 0ul; for (int i = 0; i < _config.LeafLoadFactor * _config.InternalBranchFactor; i++) { try { tree.Insert(txnId, (ulong)i, testBytes); } catch (Exception ex) { Assert.Fail("Insert failed for key {0} with exception {1}", i, ex); } } var rootNode = tree.GetNode(tree.RootId, null); var childId = (rootNode as InternalNode).GetChildNodeId(rootNode.RightmostKey); var child = tree.GetNode(childId, null) as InternalNode; var childLeftmostKey = BitConverter.ToUInt64(child.LeftmostKey, 0); var grandchild = tree.GetNode(child.GetChildNodeId(BitConverter.GetBytes(childLeftmostKey - 1)), null) as LeafNode; var deleteFrom = BitConverter.ToUInt64(grandchild.LeftmostKey, 0); var findChildId = (rootNode as InternalNode).GetChildNodeId(BitConverter.GetBytes(deleteFrom)); Assert.AreEqual(child.PageId, findChildId, "Incorrect node id returned for key {0}", deleteFrom); for (ulong i = 0; i < 4; i++) { var deleteKey = deleteFrom + i; tree.Delete(txnId, deleteKey, null); // Should be enough to force a right merge } for (ulong i = 0; i < (ulong)(_config.LeafLoadFactor * _config.InternalBranchFactor); i++) { Assert.IsTrue(tree.Search(i, buff, null) ^ (i - deleteFrom >= 0 && i - deleteFrom < 4), "Could not find key {0}. deleteFrom={1}", i, deleteFrom); } deleteFrom = (ulong)(_config.LeafLoadFactor * _config.InternalBranchFactor) - 5; for (ulong i = 0; i < 4; i++) { var deleteKey = deleteFrom + i; tree.Delete(txnId, deleteKey, null); } } }
public void TestMergeLeft() { using (var pageStore = TestUtils.CreateEmptyPageStore("TestMergeLeft.data")) { var tree = new BPlusTree(pageStore); var testBytes = new byte[] { 1, 2, 3, 4 }; var buff = new byte[_config.ValueSize]; var txnId = 0ul; for (int i = 0; i < _config.LeafLoadFactor * _config.InternalBranchFactor; i++) { tree.Insert(txnId, (ulong)i, testBytes); } ulong delFrom = (ulong)(_config.LeafLoadFactor * _config.InternalBranchFactor) - 1; ulong delRange = ((ulong)_config.LeafLoadFactor / 2) + 2; for (ulong i = 0; i < delRange; i++) { tree.Delete(txnId, delFrom - i, null); // Should be enough to force a left merge } for (ulong i = 0; i < delFrom; i++) { Assert.IsTrue((delFrom - i < delRange) ^ tree.Search(i, buff, null), "Failed to find key {0} after deletes", i); } } }
public void TestInsertAndDeleteInReverseOrder() { const string pageStoreName = "TestInsertAndDeleteInReverseOrder.data"; var value = new byte[64]; ulong rootPageId; const int keyCount = 20000; using (var pageStore = TestUtils.CreateEmptyPageStore(pageStoreName)) { var tree = new BPlusTree(pageStore); for (int i = 0; i < keyCount; i++) { tree.Insert(0, (ulong)i, value); } rootPageId = tree.Save(0, null); pageStore.Commit(0, null); } using (var pageStore = TestUtils.OpenPageStore(pageStoreName, false)) { var tree = new BPlusTree(pageStore, rootPageId); for (int i = keyCount - 1; i >= 0; i--) { tree.Delete(1, (ulong)i, null); } rootPageId = tree.Save(1, null); pageStore.Commit(0, null); } using (var pageStore = TestUtils.OpenPageStore(pageStoreName, false)) { var tree = new BPlusTree(pageStore, rootPageId); Assert.AreEqual(0, tree.Scan(null).Count(), "Expected and empty tree after all deletes"); } }
public void DeleteFromTreeWithMergeBiggerChild() { var tree = new BPlusTree(10, "test"); tree.TryAppendElementToTree(5, "5"); tree.TryAppendElementToTree(15, "15"); tree.TryAppendElementToTree(20, "20"); tree.TryAppendElementToTree(25, "20"); tree.Delete(10); Assert.AreEqual(2, tree.Root.KeyValueDictionary.Count); Assert.AreEqual(15, tree.Root.KeyValueDictionary.ElementAt(0).Key); Assert.AreEqual(null, tree.Root.KeyValueDictionary.ElementAt(0).Value); Assert.AreEqual(20, tree.Root.KeyValueDictionary.ElementAt(1).Key); Assert.AreEqual(null, tree.Root.KeyValueDictionary.ElementAt(1).Value); Assert.AreEqual(5, tree.Root.Children[0].KeyValueDictionary.ElementAt(0).Key); Assert.AreEqual(15, tree.Root.Children[1].KeyValueDictionary.ElementAt(0).Key); Assert.AreEqual(20, tree.Root.Children[2].KeyValueDictionary.ElementAt(0).Key); Assert.AreEqual(25, tree.Root.Children[2].KeyValueDictionary.ElementAt(1).Key); Assert.AreEqual(null, tree.Root.Children[0].PreviousLeaf); Assert.AreEqual(tree.Root.Children[1], tree.Root.Children[0].NextLeaf); Assert.AreEqual(tree.Root.Children[0], tree.Root.Children[1].PreviousLeaf); Assert.AreEqual(tree.Root.Children[2], tree.Root.Children[1].NextLeaf); Assert.AreEqual(tree.Root.Children[1], tree.Root.Children[2].PreviousLeaf); Assert.AreEqual(null, tree.Root.Children[2].NextLeaf); }
public void TestBorrowRight() { using (var pageStore = TestUtils.CreateEmptyPageStore("TestBorrowRight.data")) { var tree = new BPlusTree(pageStore); var buff = new byte[_config.ValueSize]; var txnId = 0ul; for (int i = 0; i <= _config.LeafLoadFactor; i++) { tree.Insert(txnId, (ulong)i, BitConverter.GetBytes((ulong)i)); } tree.Delete(txnId, 13ul, null); tree.Delete(txnId, 12ul, null); // Should force a borrow frrom the right node for (int i = 0; i <= _config.LeafLoadFactor; i++) { Assert.IsTrue(i == 12 ^ i == 13 ^ tree.Search((ulong)i, buff, null)); } } }
public void Delete_TheOnlyKeyInTree_ExpectsNoNodeAndNoKeyAfter() { var tree = new BPlusTree <int, string>(3); tree.Insert(new KeyValuePair <int, string>(10, "A")); BTreeTestsUtils.HasBPlusTreeProperties(tree, 2, 1, 2); /* Deleting the only key in the only leaf node of the tree. */ Assert.IsTrue(tree.Delete(10)); BTreeTestsUtils.HasBPlusTreeProperties(tree, 0, 0, 0); }
public void Delete_TheOnlyKeyInLeafNode_ExpectsToTriggerLeftRotateAndReduceBy1Key() { var tree = new BPlusTree <int, string>(3); tree.Insert(new KeyValuePair <int, string>(10, "A")); tree.Insert(new KeyValuePair <int, string>(20, "B")); tree.Insert(new KeyValuePair <int, string>(30, "C")); BTreeTestsUtils.HasBPlusTreeProperties(tree, 4, 3, 3); Assert.IsTrue(tree.Delete(10)); BTreeTestsUtils.HasBPlusTreeProperties(tree, 3, 2, 3); }
public void Delete_NonExistingKey_ExpectsFailure() { var tree = new BPlusTree <int, string>(3); tree.Insert(new KeyValuePair <int, string>(10, "A")); tree.Insert(new KeyValuePair <int, string>(100, "B")); BTreeTestsUtils.HasBPlusTreeProperties(tree, 3, 2, 3); /* Deleting a non-existing key. */ Assert.IsFalse(tree.Delete(50)); BTreeTestsUtils.HasBPlusTreeProperties(tree, 3, 2, 3); }
public void Delete_BiggestKeyInTheOnlyLeafNodeOfTree_ExpectsToReduceBy1Key() { var tree = new BPlusTree <int, string>(3); tree.Insert(new KeyValuePair <int, string>(10, "A")); tree.Insert(new KeyValuePair <int, string>(100, "B")); BTreeTestsUtils.HasBPlusTreeProperties(tree, 3, 2, 3); /* Deleting 1 out of 2 keys in the only leaf node of the tree. */ Assert.IsTrue(tree.Delete(100)); BTreeTestsUtils.HasBPlusTreeProperties(tree, 2, 1, 2); }
public void DeleteFromTreeWithMergeMediumChild() { var tree = new BPlusTree(10, "10"); tree.TryAppendElementToTree(5, "5"); tree.TryAppendElementToTree(15, "15"); tree.TryAppendElementToTree(20, "20"); tree.TryAppendElementToTree(25, "25"); tree.TryAppendElementToTree(6, "6"); tree.TryAppendElementToTree(7, "7"); tree.Delete(5); tree.Delete(7); Assert.AreEqual(15, tree.Root.KeyValueDictionary.ElementAt(0).Key); Assert.AreEqual(10, tree.Root.Children[0].KeyValueDictionary.ElementAt(0).Key); Assert.AreEqual(20, tree.Root.Children[1].KeyValueDictionary.ElementAt(0).Key); Assert.AreEqual(6, tree.Root.Children[0].Children[0].KeyValueDictionary.ElementAt(0).Key); Assert.AreEqual(10, tree.Root.Children[0].Children[1].KeyValueDictionary.ElementAt(0).Key); Assert.AreEqual(15, tree.Root.Children[1].Children[0].KeyValueDictionary.ElementAt(0).Key); Assert.AreEqual(20, tree.Root.Children[1].Children[1].KeyValueDictionary.ElementAt(0).Key); Assert.AreEqual(25, tree.Root.Children[1].Children[1].KeyValueDictionary.ElementAt(1).Key); }
public void Delete_TheOnlyKeyInLeafNodeWithMinOneFullSibling_ExpectsToTriggerLeftRotate() { var tree = new BPlusTree <int, string>(3); tree.Insert(new KeyValuePair <int, string>(10, "A")); tree.Insert(new KeyValuePair <int, string>(20, "B")); tree.Insert(new KeyValuePair <int, string>(30, "C")); tree.Insert(new KeyValuePair <int, string>(40, "D")); BTreeTestsUtils.HasBPlusTreeProperties(tree, 6, 4, 4); Assert.IsTrue(tree.Delete(10)); BTreeTestsUtils.HasBPlusTreeProperties(tree, 5, 3, 4); }
public void Delete_KeyInFullLeaf_ExpectsToReduceBy1Key() { var tree = new BPlusTree <int, string>(3); tree.Insert(new KeyValuePair <int, string>(10, "A")); tree.Insert(new KeyValuePair <int, string>(20, "B")); tree.Insert(new KeyValuePair <int, string>(30, "C")); tree.Insert(new KeyValuePair <int, string>(40, "D")); BTreeTestsUtils.HasBPlusTreeProperties(tree, 6, 4, 4); Assert.IsTrue(tree.Delete(30)); BTreeTestsUtils.HasBPlusTreeProperties(tree, 5, 3, 4); }
public void InsertDelete(IList <int> datas) { var bTree = new BPlusTree <int>(); Console.WriteLine(); TestHepler.PrintList(datas, "InsertDeleteTestStartData"); for (int i = 0; i < datas.Count; i++) { var data = datas[i]; Console.Write("{0} ", data); if (data % 3 == 0) { bTree.Delete(data); var preData = int.MinValue; Console.WriteLine(); Console.WriteLine("InsertDeleteTest delete order start"); bTree.Order(bTree.Root, (d) => { Console.Write("{0}, ", d); Assert.IsTrue(preData <= d); preData = d; }); Console.WriteLine(); Console.WriteLine("InsertDeleteTest delete order end"); } else { bTree.Insert(data); var preData = int.MinValue; Console.WriteLine(); Console.WriteLine("InsertDeleteTest insert order start"); bTree.Order(bTree.Root, (d) => { Console.Write("{0}, ", d); Assert.IsTrue(preData <= d); preData = d; }); Console.WriteLine(); Console.WriteLine("InsertDeleteTest insert order end"); } } Console.WriteLine(); }
public void TestDeleteFromLeafRoot() { using (var pageStore = TestUtils.CreateEmptyPageStore("TestDeleteFromLeafRoot.data")) { var tree = new BPlusTree(pageStore); var txnId = 0ul; var buff = new byte[_config.ValueSize]; tree.Insert(txnId, 1ul, TestUtils.StringToByteArray("one")); tree.Insert(txnId, 2ul, TestUtils.StringToByteArray("two")); tree.Insert(txnId, 3ul, TestUtils.StringToByteArray("three")); tree.Delete(txnId, 2ul, null); Assert.IsTrue(tree.Search(1ul, buff, null)); TestUtils.AssertBuffersEqual(TestUtils.StringToByteArray("one"), buff); Assert.IsTrue(tree.Search(3ul, buff, null)); TestUtils.AssertBuffersEqual(TestUtils.StringToByteArray("three"), buff); Assert.IsFalse(tree.Search(2ul, buff, null)); } }
public void TestDeleteInRandomOrder() { const string pageStoreName = "DeleteInRandomOrder.data"; var value = new byte[64]; ulong rootPageId; const int keyCount = 20000; using (var pageStore = TestUtils.CreateEmptyPageStore(pageStoreName)) { var tree = new BPlusTree(pageStore); for (int i = 0; i < keyCount; i++) { tree.Insert(0, (ulong)i, value); } rootPageId = tree.Save(0, null); pageStore.Commit(0, null); } var deleteList = TestUtils.MakeRandomInsertList(20000).ToList(); using (var pageStore = TestUtils.OpenPageStore(pageStoreName, false)) { var tree = new BPlusTree(pageStore, rootPageId); for (int i = 0; i < deleteList.Count; i++) { Assert.IsTrue(tree.Search((ulong)deleteList[i], value, null), "Could not find key {0} before deletion", deleteList[i]); tree.Delete(1, (ulong)deleteList[i], null); Assert.IsFalse(tree.Search((ulong)deleteList[i], value, null), "Search returned key {0} after it was supposed to be deleted", deleteList[i]); } rootPageId = tree.Save(1, null); pageStore.Commit(1, null); } using (var pageStore = TestUtils.OpenPageStore(pageStoreName, false)) { var tree = new BPlusTree(pageStore, rootPageId); Assert.AreEqual(0, tree.Scan(null).Count(), "Expected and empty tree after all deletes"); } }
public void EmptyTreeTest() { var tree = new BPlusTree(5, "5"); tree.TryAppendElementToTree(10, "10"); tree.TryAppendElementToTree(15, "15"); tree.TryAppendElementToTree(20, "20"); tree.TryAppendElementToTree(25, "25"); tree.TryAppendElementToTree(30, "30"); tree.TryAppendElementToTree(35, "35"); tree.TryAppendElementToTree(40, "40"); tree.TryAppendElementToTree(45, "45"); tree.TryAppendElementToTree(50, "50"); tree.TryAppendElementToTree(55, "55"); tree.TryAppendElementToTree(41, "41"); tree.TryAppendElementToTree(42, "42"); tree.Delete(50); tree.Delete(55); tree.Delete(42); tree.Delete(41); tree.Delete(40); tree.Delete(45); tree.Delete(30); tree.Delete(35); tree.Delete(20); tree.Delete(25); tree.Delete(15); tree.Delete(10); tree.Delete(5); Assert.AreEqual(0, tree.Root.KeyValueDictionary.Count); Assert.AreEqual(0, tree.Root.Children.Count); }
public void Delete_TheBiggestKeyInLeftSubTree_ExpectsRightRotateAndToReduceBy1Key() { BTreeTestsUtils.HasBPlusTreeProperties(_tree, 25, 16, 17); Assert.IsTrue(_tree.Delete(150)); BTreeTestsUtils.HasBPlusTreeProperties(_tree, 24, 15, 17); }
public void TestInsertAndDeleteAllEntries() { var value = new byte[64]; ulong rootPageId; const int keyCount = 20000; using (var pageStore = TestUtils.CreateEmptyPageStore("TestInsertAndDeleteAllEntries.data")) { var tree = new BPlusTree(pageStore); for (int i = 0; i < keyCount; i++) { tree.Insert(0, (ulong)i, value); } rootPageId = tree.Save(0, null); pageStore.Commit(0, null); } using (var pageStore = TestUtils.OpenPageStore("TestInsertAndDeleteAllEntries.data", true)) { var tree = new BPlusTree(pageStore, rootPageId); for (int i = 0; i < keyCount; i++) { Assert.IsTrue(tree.Search((ulong)i, value, null), "Could not find key {0} after insert and save."); } } using (var pageStore = TestUtils.OpenPageStore("TestInsertAndDeleteAllEntries.data", false)) { var tree = new BPlusTree(pageStore, rootPageId); for (int i = 0; i < keyCount; i += 2) { tree.Delete(1ul, (ulong)i, null); Assert.IsFalse(tree.Search((ulong)i, value, null), "Still found entry for key {0} after delete", i); } rootPageId = tree.Save(1, null); pageStore.Commit(1, null); } using (var pageStore = TestUtils.OpenPageStore("TestInsertAndDeleteAllEntries.data", true)) { var tree = new BPlusTree(pageStore, rootPageId); for (int i = 1; i < keyCount; i += 2) { Assert.IsTrue(tree.Search((ulong)i, value, null), "Could not find key {0} after deletion of even numbered keys.", i); Assert.IsFalse(tree.Search((ulong)i - 1, value, null), "Found key {0} after deletion of even numbered keys", i - 1); } } using (var pageStore = TestUtils.OpenPageStore("TestInsertAndDeleteAllEntries.data", false)) { var tree = new BPlusTree(pageStore, rootPageId); for (int i = 1; i < keyCount; i += 2) { tree.Delete(2ul, (ulong)i, null); Assert.IsFalse(tree.Search((ulong)i, value, null), "Key {0} was still found by a search after it was deleted", i); } rootPageId = tree.Save(2, null); pageStore.Commit(2, null); } using (var pageStore = TestUtils.OpenPageStore("TestInsertAndDeleteAllEntries.data", true)) { var tree = new BPlusTree(pageStore, rootPageId); Console.WriteLine("After load\r\n"); tree.DumpStructure(); Assert.AreEqual(0, tree.Scan(null).Count(), "Expected an empty tree after deleting all odd-numbered entries"); } }