Exemplo n.º 1
0
        public void TestCoalesceEmptyTree()
        {
            const string storeName = "Coalesce.EmptyTree.data";
            ulong srcRootId, coalescedRootId;
            using(var store = TestUtils.CreateEmptyPageStore(storeName))
            {
                var tree = new BPlusTree(store);
                srcRootId = tree.Save(0, null);
                store.Commit(0, null);
            }

            using(var store = TestUtils.OpenPageStore(storeName, false))
            {
                var sourceTree = new BPlusTree(store, srcRootId);
                Assert.AreEqual(0, sourceTree.Scan(null).Count());
                var builder = new BPlusTreeBuilder(store, sourceTree.Configuration);
                coalescedRootId = builder.Build(1, sourceTree.Scan(null));
                var coalescedTree = new BPlusTree(store, coalescedRootId);
                Assert.AreEqual(0, coalescedTree.Scan(null).Count());
                store.Commit(1ul, null);
            }

            using (var store = TestUtils.OpenPageStore(storeName, true))
            {
                var coalescedTree = new BPlusTree(store, coalescedRootId);
                Assert.AreEqual(0, coalescedTree.Scan(null).Count());                
            }
        }
Exemplo n.º 2
0
        public void TestInsertNoSplit()
        {
            using (var pageStore = TestUtils.CreateEmptyPageStore("TestInsertNoSplit.data"))
            {
                var tree = new BPlusTree(1, pageStore);
                tree.Insert(0, 5ul, TestUtils.StringToByteArray("five"));
                tree.Insert(0, 3ul, TestUtils.StringToByteArray("three"));
                var valueBuffer = new byte[tree.Configuration.ValueSize];
                Assert.IsTrue(tree.Search(5ul, valueBuffer, null), "Expected search for key 5 to return true");
                TestUtils.AssertBuffersEqual(TestUtils.StringToByteArray("five"), valueBuffer);
                Assert.IsTrue(tree.Search(3ul, valueBuffer, null), "Expected search for key 3 to return true");
                TestUtils.AssertBuffersEqual(TestUtils.StringToByteArray("three"), valueBuffer);
                Assert.IsFalse(tree.Search(2ul, valueBuffer, null), "Expected search for key 2 to return false");
                tree.Save(0, null);
                var root = tree.RootId;
                pageStore.Commit(1, null);

                tree = new BPlusTree(pageStore, root);
                Assert.IsTrue(tree.Search(5ul, valueBuffer, null), "Expected search for key 5 to return true");
                TestUtils.AssertBuffersEqual(TestUtils.StringToByteArray("five"), valueBuffer);
                Assert.IsTrue(tree.Search(3ul, valueBuffer, null), "Expected search for key 3 to return true");
                TestUtils.AssertBuffersEqual(TestUtils.StringToByteArray("three"), valueBuffer);
                Assert.IsFalse(tree.Search(2ul, valueBuffer, null), "Expected search for key 2 to return false");
            }
        }
Exemplo n.º 3
0
        public void TestBatchInsert()
        {
            const int target = 40000000;
            const int batchSize = 50000;
            const int batchCount = target/batchSize;
            // Tests insert of 40 million unique keys in batches of 50,000
            // Reports time for each batch to console.

#if SILVERLIGHT
            var persistenceManager = new IsolatedStoragePersistanceManager();
#else
            var persistenceManager = new FilePersistenceManager();
#endif
            // Create a test batch
            if (!File.Exists("C:\\brightstar\\testdata.dat"))
            {
                MakeTestData();
            }
            var testList = ReadTestData("c:\\brightstar\\testdata.dat");

            // Create empty store
            if (File.Exists("40m_batch.data")) File.Delete("40m_batch.data");
            var pageStore = new AppendOnlyFilePageStore(persistenceManager, "40m_batch.data", 4096, false, false);
            var tree = new BPlusTree(pageStore);
            ulong lastRoot = tree.RootId;
            tree.Save(0, null);
            pageStore.Commit(0ul, null);

            byte[] testBuffer = Encoding.UTF8.GetBytes("Test Buffer");
            var batchTimer = Stopwatch.StartNew();
            int insertedCount = 0;
            var txnId = 1ul;
            for (int i = 0; i < batchCount; i++)
            {
                tree = new BPlusTree(pageStore, lastRoot);
                foreach (var item in testList)
                {
                    var insertKey = (ulong) ((item*batchCount) + i);
                    try
                    {
                        tree.Insert(txnId, insertKey, testBuffer);
                        insertedCount++;
                    }
                    catch (Exception e)
                    {
                        Assert.Fail("Failed to add key {0}. Cause: {1}", insertKey, e);
                    }
                }
                long beforeSave = batchTimer.ElapsedMilliseconds;
                tree.Save(txnId, null);
                lastRoot = tree.RootId;
                pageStore.Commit(txnId, null);
                Console.WriteLine("{0},{1},{2}", insertedCount, beforeSave, batchTimer.ElapsedMilliseconds);
                txnId++;
            }
        }
Exemplo n.º 4
0
        public void TestCoalesceRootLeafNode()
        {
            const string storeName = "Coalesce.RootLeafNode.data";
            ulong srcRootId, targetRootId;
            var txnId = 0ul;
            using(var store = TestUtils.CreateEmptyPageStore(storeName))
            {
                var sourceTree = new BPlusTree(0, store);
                var config = sourceTree.Configuration;
                for (int i = 0; i < config.LeafLoadFactor; i++)
                {
                    sourceTree.Insert(txnId, (ulong)i, BitConverter.GetBytes((ulong)i));
                }
                sourceTree.DumpStructure();
                srcRootId = sourceTree.Save(txnId, null);
                store.Commit(txnId, null);
            }

            using(var store = TestUtils.OpenPageStore(storeName, false))
            {
                var sourceTree = new BPlusTree(store, srcRootId);
                var config = sourceTree.Configuration;
                var builder = new BPlusTreeBuilder(store, config);
                targetRootId = builder.Build(1, sourceTree.Scan(null));
                
                var targetTree = new BPlusTree(store, targetRootId);
                targetTree.DumpStructure();
                byte[] valueBuff = new byte[64];
                for(int i =0 ; i < config.LeafLoadFactor; i++)
                {
                    Assert.IsTrue(targetTree.Search((ulong)i, valueBuff, null));
                    Assert.AreEqual((ulong) i, BitConverter.ToUInt64(valueBuff, 0));
                }
                store.Commit(1, null);
            }

            using(var store = TestUtils.OpenPageStore(storeName, true))
            {
                var targetTree = new BPlusTree(store, targetRootId);
                var config = targetTree.Configuration;
                targetTree.DumpStructure();
                byte[] valueBuff = new byte[64];
                for (int i = 0; i < config.LeafLoadFactor; i++)
                {
                    Assert.IsTrue(targetTree.Search((ulong)i, valueBuff, null));
                    Assert.AreEqual((ulong)i, BitConverter.ToUInt64(valueBuff, 0));
                }
            }
        }
Exemplo n.º 5
0
 /// <summary>
 /// Dump a trace of the structure of this node to the console
 /// </summary>
 /// <param name="tree">The tree that contains this node</param>
 /// <param name="indentLevel">The indent level to use when writing the structure</param>
 public void DumpStructure(BPlusTree tree, int indentLevel)
 {
     var keyPrefix = new string(' ', indentLevel*4);
     var pointerPrefix = keyPrefix + "  ";
     INode childNode;
     for (int i = 0; i < _keyCount; i++)
     {
         Console.WriteLine("{0}PTR[{1}]: {2}", pointerPrefix, i, _childPointers[i]);
         childNode = tree.GetNode(_childPointers[i], null);
         childNode.DumpStructure(tree, indentLevel + 1);
         Console.WriteLine("{0}KEY[{1}]: {2}", keyPrefix, i, _keys[i].Dump());
     }
     Console.WriteLine("{0}PTR[{1}]: {2}", pointerPrefix, _keyCount, _childPointers[_keyCount]);
     childNode = tree.GetNode(_childPointers[_keyCount], null);
     childNode.DumpStructure(tree, indentLevel + 1);
 }
 private void BuildAndScan(IPageStore pageStore, string pageStoreName, PersistenceType persistenceType, int keyCount)
 {
     var config = new BPlusTreeConfiguration(8, 64, pageStore.PageSize);
     var builder = new BPlusTreeBuilder(pageStore, config);
     var treeRoot = builder.Build(1, _testOrderedValues.Take(keyCount));
     var treeBeforeSave = new BPlusTree(pageStore, treeRoot);
     treeBeforeSave.Save(1, null);
     //ValidateScan(treeBeforeSave.Scan(null), keyCount, pageStoreName + " before save");
     pageStore.Commit(1, null);
     pageStore.Close();
     
    
     using(var ps = TestUtils.OpenPageStore(pageStoreName, true, persistenceType, 1))
     {
         var tree = new BPlusTree(ps, treeRoot);
         tree.DumpStructure();
         ValidateScan(tree.Scan(null), keyCount, pageStoreName + " after save");
         ValidateSearch(tree, keyCount, pageStoreName + "after save");
     }
 }
Exemplo n.º 7
0
        public void DumpStructure(BPlusTree tree, int indentLevel)
        {
            var   keyPrefix     = new string(' ', indentLevel * 4);
            var   pointerPrefix = keyPrefix + "  ";
            INode childNode;

            for (int i = 0; i < _keyCount; i++)
            {
                var childPointer = GetPointer(i);
                Console.WriteLine("{0}PTR[{1}]: {2}", pointerPrefix, i, childPointer);
                childNode = tree.GetNode(childPointer, null);
                childNode.DumpStructure(tree, indentLevel + 1);
                Console.WriteLine("{0}KEY[{1}]: {2}", keyPrefix, i, GetKey(i).Dump());
            }
            var lastPointer = GetPointer(KeyCount);

            Console.WriteLine("{0}PTR[{1}]: {2}", pointerPrefix, _keyCount, lastPointer);
            childNode = tree.GetNode(lastPointer, null);
            childNode.DumpStructure(tree, indentLevel + 1);
        }
Exemplo n.º 8
0
        public void TestInsertSingleRootSplit()
        {
            ulong rootId;
            using (var pageStore = TestUtils.CreateEmptyPageStore("TestInsertSingleRootSplit.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));
                }

                tree.Insert(txnId, (ulong) config.LeafLoadFactor, BitConverter.GetBytes((ulong) config.LeafLoadFactor));
                Assert.IsTrue(tree.Search(14, buff, null));

                // Check we can find all the values inserted so far
                for (int i = 0; i <= config.LeafLoadFactor; i++)
                {
                    Assert.IsTrue(tree.Search((ulong) i, buff, null));
                }
                tree.Save(txnId, null);
                pageStore.Commit(txnId, null);
                rootId = tree.RootId;
            }

            using (var pageStore = TestUtils.OpenPageStore("TestInsertSingleRootSplit.data", true))
            {
                var tree = new BPlusTree(pageStore, rootId);
                var config = tree.Configuration;
                var buff = new byte[config.ValueSize];
                for (int i = 0; i <= config.LeafLoadFactor; i++)
                {
                    Assert.IsTrue(tree.Search((ulong) i, buff, null), "Could not find entry for key {0}", i);
                    var value = BitConverter.ToUInt64(buff, 0);
                    Assert.AreEqual((ulong) i, value);
                }
            }
        }
Exemplo n.º 9
0
        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(0, 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);
                Assert.IsTrue(tree.Search(3457ul, value, null), "Could not find entry 3457 before deletes");
                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);
                    Assert.IsTrue(tree.Search(3457ul, value, null), "Could not find entry 3457 after delete of {0}",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");
            }
        }
Exemplo n.º 10
0
 public void TestBatchedInserts()
 {
     var rng = new Random();
     var keyBuff = new byte[8];
     var value = new byte[64];
     ulong key = 0;
     var txnId = 0ul;
     var inserted = new HashSet<ulong>();
     inserted.Add(0); // Not using enumerable initializer because its not supported in the mobile build
     using (var pageStore = TestUtils.CreateEmptyPageStore("TestBatchedInserts.data"))
     {
         var tree = new BPlusTree(txnId, pageStore);
         for (int i = 1; i <= 10000; i++)
         {
             while (inserted.Contains(key))
             {
                 rng.NextBytes(keyBuff);
                 key = BitConverter.ToUInt64(keyBuff, 0);
             }
             inserted.Add(key);
             tree.Insert(txnId, key, value);
             if (i%250 == 0)
             {
                 tree.Save((ulong)i / 250, null);
                 pageStore.Commit((ulong)i / 250, null);
                 //Console.WriteLine("Dump tree @ commit after {0}", i);
                 //tree.DumpStructure();
                 Assert.AreEqual(i, tree.Scan(0, ulong.MaxValue, null).Count());
             }
         }
     }
 }
Exemplo n.º 11
0
        public void TestValuelessBTree()
        {
            var insertedValues = new List<Guid>();
            ulong treeRoot;
            var txnId = 0ul;
            using (var pageStore = TestUtils.CreateEmptyPageStore("TestValuelessBTree.data"))
            {
                var tree = new BPlusTree(0, pageStore, 16, 0);
                for(int i = 0; i < 1000; i++)
                {
                    var g = Guid.NewGuid();
                    tree.Insert(txnId, g.ToByteArray(), null);
                    insertedValues.Add(g);
                }
                tree.Save(0, null);
                treeRoot = tree.RootId;
                pageStore.Commit(0ul, null);
                //tree.DumpStructure();
            }

            using (var pageStore = TestUtils.OpenPageStore("TestValuelessBTree.data", false))
            {
                var tree = new BPlusTree(pageStore, treeRoot, 16, 0);
                tree.DumpStructure();
                var buff = new byte[0];
                foreach(var g in insertedValues)
                {
                    Assert.IsTrue(tree.Search(g.ToByteArray(), buff, null));
                }
            }
        }
Exemplo n.º 12
0
        public void TestMergeRight()
        {
            using (var pageStore = TestUtils.CreateEmptyPageStore("TestMergeRight.data"))
            {
                var txnId = 0ul;
                var tree = new BPlusTree(txnId, pageStore);
                var testBytes = new byte[] {1, 2, 3, 4};
                var config = tree.Configuration;
                var buff = new byte[config.ValueSize];
                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 IInternalNode).GetChildNodeId(rootNode.RightmostKey);
                var child = tree.GetNode(childId, null) as IInternalNode;
                var childLeftmostKey = BitConverter.ToUInt64(child.LeftmostKey, 0);
                var grandchild =
                    tree.GetNode(child.GetChildNodeId(BitConverter.GetBytes(childLeftmostKey - 1)), null) as ILeafNode;
                var deleteFrom = BitConverter.ToUInt64(grandchild.LeftmostKey, 0);

                var findChildId = (rootNode as IInternalNode).GetChildNodeId(BitConverter.GetBytes(deleteFrom));
                Assert.AreEqual(child.PageId, findChildId, "Incorrect node id returned for key {0}", deleteFrom);

                tree.DumpStructure();

                for (ulong i = 0; i < 4; i++)
                {
                    var deleteKey = deleteFrom + i;
                    tree.Delete(txnId, deleteKey, null); // Should be enough to force a right merge
                    //Console.WriteLine("\n\nDeleted {0}\n", deleteKey);
                    //tree.DumpStructure();
                    Assert.IsTrue(tree.Search(10395ul, buff, null));
                }

                for (ulong i = 0; i < (ulong) (config.LeafLoadFactor*config.InternalBranchFactor); i++)
                {
                    try
                    {
                        Assert.IsTrue(tree.Search(i, buff, null) ^ (i - deleteFrom >= 0 && i - deleteFrom < 4),
                                      "Could not find key {0}. deleteFrom={1}", i, deleteFrom);
                    }
                    catch (AssertionException)
                    {
                        Console.WriteLine("\nFailed tree structure:\n");
                        tree.DumpStructure();
                        throw;
                    }
                }

                deleteFrom = (ulong) (config.LeafLoadFactor*config.InternalBranchFactor) - 5;
                for (ulong i = 0; i < 4; i++)
                {
                    var deleteKey = deleteFrom + i;
                    tree.Delete(txnId, deleteKey, null);
                }
            }
        }
Exemplo n.º 13
0
        public void TestSplitRootNode()
        {
            ulong treeRootId;
            using (var pageStore = TestUtils.CreateEmptyPageStore("TestSplitRootNode.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.InternalBranchFactor; i++)
                {
                    for (int j = 0; j < config.LeafLoadFactor; j++)
                    {
                        var nodeKey = (ulong) ((i*config.LeafLoadFactor) + j);
                        tree.Insert(txnId, nodeKey, BitConverter.GetBytes(nodeKey));
                    }
                }
                treeRootId = tree.Save(0ul, null);
                Assert.IsTrue(tree.Search(14ul, buff, null));
                pageStore.Commit(0ul, null);
                pageStore.Close();
            }
            using (var pageStore = TestUtils.OpenPageStore("TestSplitRootNode.data",true))
            {
                var tree = new BPlusTree(pageStore, treeRootId); 
                var config = tree.Configuration;
                var buff = new byte[config.ValueSize];

                for (int i = 0; i < config.InternalBranchFactor; i++)
                {
                    for (int j = 0; j < config.LeafLoadFactor; j++)
                    {
                        var nodeKey = (ulong) ((i*config.LeafLoadFactor) + j);
                        Assert.IsTrue(tree.Search(nodeKey, buff, null), "Could not find entry for key {0}", nodeKey);
                        var value = BitConverter.ToUInt64(buff, 0);
                        Assert.AreEqual(nodeKey, value);
                    }
                }
            }

        }
Exemplo n.º 14
0
 public void DumpStructure(BPlusTree tree, int indentLevel)
 {
     if (KeyCount == 0)
     {
         Console.WriteLine("{0}EMPTY LEAF NODE",
             new string(' ', indentLevel));
         return;
     }
     Console.WriteLine("{0}LEAF@{1}[{2} keys: {3} - {4}]",
         new string(' ', indentLevel*4), PageId, KeyCount, LeftmostKey.Dump(), RightmostKey.Dump());
 }
Exemplo n.º 15
0
 /// <summary>
 /// Dump a trace of the structure of this node to the console
 /// </summary>
 /// <param name="tree">The tree that contains this node</param>
 /// <param name="indentLevel">The indent level to use when writing the structure</param>
 public void DumpStructure(BPlusTree tree, int indentLevel)
 {
     if (_keyCount == 0)
     {
         Console.WriteLine("EMPTY LEAF NODE");
         return;
     }
     Console.WriteLine("{0}LEAF@{1}[{2} keys: {3} - {4}]", new string(' ', indentLevel*4), PageId, _keyCount, _keys[0].Dump(), _keys[_keyCount - 1].Dump());
 }
Exemplo n.º 16
0
 public void TestInsertInRandomOrder()
 {
     ulong treeRootId;
     using (var pageStore = TestUtils.CreateEmptyPageStore("TestInsertInRandomOrder.data"))
     {
         var txnId = 0ul;
         var tree = new BPlusTree(txnId, pageStore);
         foreach (var insertValue in TestUtils.MakeRandomInsertList(100000))
         {
             tree.Insert(txnId, (ulong) insertValue, BitConverter.GetBytes(insertValue));
         }
         treeRootId = tree.Save(txnId, null);
         pageStore.Commit(txnId, null);
     }
     using (var pageStore = TestUtils.OpenPageStore("TestInsertInRandomOrder.data", true))
     {
         var tree = new BPlusTree(pageStore, treeRootId);
         var config = tree.Configuration;
         var buff = new byte[config.ValueSize];
         for (int i = 0; i < 100000; i++)
         {
             Assert.IsTrue(tree.Search((ulong) i, buff, null), "Could not find key {0} in tree", i);
             TestUtils.AssertBuffersEqual(BitConverter.GetBytes(i), buff);
         }
     }
 }
Exemplo n.º 17
0
        public void TestDeleteFromLeafRoot()
        {
            using (var pageStore = TestUtils.CreateEmptyPageStore("TestDeleteFromLeafRoot.data"))
            {
                var txnId = 0ul;
                var tree = new BPlusTree(txnId, pageStore);
                var config = tree.Configuration;
                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));
            }
        }
Exemplo n.º 18
0
        public void TestInsertInReverseOrder()
        {
            using (var pageStore = TestUtils.CreateEmptyPageStore("TestInsertInReverseOrder.data"))
            {
                var txnId = 0ul;
                var tree = new BPlusTree(txnId, pageStore);
                var config = tree.Configuration;

                for (int i = 100000; i > 0; i--)
                {
                    tree.Insert(txnId, (ulong) i, BitConverter.GetBytes(i));
                }
                Console.WriteLine("Tree after 100,000 inserts:");
                tree.DumpStructure();

                var buff = new byte[config.ValueSize];
                for (int i = 100000; i > 0; i--)
                {
                    Assert.IsTrue(tree.Search((ulong) i, buff, null), "Cannot find entry for key {0}", i);
                    TestUtils.AssertBuffersEqual(BitConverter.GetBytes(i), buff);
                }
            }
        }
Exemplo n.º 19
0
 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));
         }
     }
 }
Exemplo n.º 20
0
        public void TestInsertInReverseOrder()
        {
            using (var pageStore = TestUtils.CreateEmptyPageStore("TestInsertInReverseOrder.data"))
            {
                var tree = new BPlusTree(pageStore);
                var txnId = 0ul;
                for (int i = 100000; i > 0; i--)
                {
                    tree.Insert(txnId, (ulong) i, BitConverter.GetBytes(i));
                }

                var buff = new byte[_config.ValueSize];
                for (int i = 100000; i > 0; i--)
                {
                    Assert.IsTrue(tree.Search((ulong) i, buff, null));
                    TestUtils.AssertBuffersEqual(BitConverter.GetBytes(i), buff);
                }
            }
        }
Exemplo n.º 21
0
        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(0, 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--)
                {
                    try
                    {
                        tree.Delete(1, (ulong) i, null);
                    }
                    catch (Exception)
                    {
                        Console.WriteLine("Delete threw exception on key {0}", i);
                        throw;
                    }
                }
                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");
            }
        }
Exemplo n.º 22
0
 public void DumpStructure(BPlusTree tree, int indentLevel)
 {
     var keyPrefix = new string(' ', indentLevel * 4);
     var pointerPrefix = keyPrefix + "  ";
     INode childNode;
     for (int i = 0; i < _keyCount; i++)
     {
         var childPointer = GetPointer(i);
         Console.WriteLine("{0}PTR[{1}]: {2}", pointerPrefix, i, childPointer);
         childNode = tree.GetNode(childPointer, null);
         childNode.DumpStructure(tree, indentLevel + 1);
         Console.WriteLine("{0}KEY[{1}]: {2}", keyPrefix, i, GetKey(i).Dump());
     }
     var lastPointer = GetPointer(KeyCount);
     Console.WriteLine("{0}PTR[{1}]: {2}", pointerPrefix, _keyCount, lastPointer);
     childNode = tree.GetNode(lastPointer, null);
     childNode.DumpStructure(tree, indentLevel + 1);
 }
Exemplo n.º 23
0
        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(0, 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");
            }
        }
Exemplo n.º 24
0
        public void TestMergeLeft()
        {
            using (var pageStore = TestUtils.CreateEmptyPageStore("TestMergeLeft.data"))
            {
                var txnId = 0ul;
                var tree = new BPlusTree(txnId, pageStore);
                var testBytes = new byte[] {1, 2, 3, 4};
                var config = tree.Configuration;
                var buff = new byte[config.ValueSize];
                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);
                }
            }
        }
Exemplo n.º 25
0
 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);
         }
     }
 }
Exemplo n.º 26
0
        public void TestCoalesceLeafLoadPlusOne()
        {
            const string storeName = "Coalesce.LeafLoadPlusOne.data";
            ulong srcRootId, targetRootId;
            var config = new BPlusTreeConfiguration(8, 64, 4096);
            var txnId = 0ul;
            using (var store = TestUtils.CreateEmptyPageStore(storeName))
            {
                var sourceTree = new BPlusTree(store);
                for (int i = 0; i < config.LeafLoadFactor + 1; i++)
                {
                    sourceTree.Insert(txnId, (ulong)i, BitConverter.GetBytes((ulong)i));
                }
                sourceTree.DumpStructure();
                srcRootId = sourceTree.Save(txnId, null);
                store.Commit(txnId, null);
            }

            txnId = 1;
            using (var store = TestUtils.OpenPageStore(storeName, false))
            {
                var sourceTree = new BPlusTree(store, srcRootId);
                var builder = new BPlusTreeBuilder(store, config);
                targetRootId = builder.Build(1, sourceTree.Scan(null));
                var targetTree = new BPlusTree(store, targetRootId);
                targetTree.DumpStructure();
                byte[] valueBuff = new byte[64];
                for (int i = 0; i < config.LeafLoadFactor + 1; i++)
                {
                    Assert.IsTrue(targetTree.Search((ulong)i, valueBuff, null));
                    Assert.AreEqual((ulong)i, BitConverter.ToUInt64(valueBuff, 0));
                }
                store.Commit(1, null);
            }

            using (var store = TestUtils.OpenPageStore(storeName, true))
            {
                var targetTree = new BPlusTree(store, targetRootId);
                targetTree.DumpStructure();
                byte[] valueBuff = new byte[64];
                for (int i = 0; i < config.LeafLoadFactor + 1; i++)
                {
                    Assert.IsTrue(targetTree.Search((ulong)i, valueBuff, null));
                    Assert.AreEqual((ulong)i, BitConverter.ToUInt64(valueBuff, 0));
                }

                var root = targetTree.GetNode(targetTree.RootId, null) as InternalNode;
                Assert.IsNotNull(root);
                Assert.AreEqual(1, root.KeyCount);
                var leftChild = targetTree.GetNode(root.ChildPointers[0], null) as LeafNode;
                var rightChild = targetTree.GetNode(root.ChildPointers[1], null) as LeafNode;
                Assert.IsNotNull(leftChild);
                Assert.IsNotNull(rightChild);

                Assert.AreEqual(config.LeafLoadFactor+1, leftChild.KeyCount + rightChild.KeyCount);
                // Key count in each node should be >= split index
                Assert.IsTrue(leftChild.KeyCount > config.LeafSplitIndex, "Left child has too few keys");
                Assert.IsTrue(rightChild.KeyCount > config.LeafSplitIndex, "Right child has too few keys");
                // And neither
            }
            
        }
Exemplo n.º 27
0
 private static void ValidateSearch(BPlusTree tree, int keyCount, string pageStoreName)
 {
     var value = new byte[64];
     for (int key = 0; key < keyCount; key++)
     {
         Assert.IsTrue(tree.Search((ulong) key, value, null), "Could not find entry for key {0} in store {1}", key, pageStoreName);
         Assert.AreEqual(key, BitConverter.ToInt32(value, 0), "Incorrect value found for key {0} in store {1}", key, pageStoreName);
     }
 }
Exemplo n.º 28
0
        public void TestBorrowLeft()
        {
            using (var pageStore = TestUtils.CreateEmptyPageStore("TestBorrowLeft.data"))
            {
                var txnId = 0ul;
                var tree = new BPlusTree(txnId, pageStore);
                var config = tree.Configuration;
                var buff = new byte[config.ValueSize];
                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);
                }
            }
        }