Example #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());                
            }
        }
Example #2
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));
                }
            }
        }
 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");
     }
 }
Example #4
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");
            }
        }
Example #5
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");
            }
        }
Example #6
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");
            }
        }
Example #7
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());
             }
         }
     }
 }
Example #8
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
            }
            
        }