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);
        }
Exemple #15
0
        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");
            }
        }