예제 #1
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);
        }
예제 #2
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);
        }
예제 #3
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);
                }
            }
        }
예제 #4
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
            }
            
        }
예제 #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);
 }
예제 #6
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);
 }