// Delete element already found at path. private void _Delete(TreePath path) { ++VersionDirect; int leafIndex = path.TopNodeIndex; LeafNode leaf = (LeafNode)path.TopNode; leaf.Remove(leafIndex); --CountDirect; if (leafIndex == 0) { if (leaf.KeyCount != 0) { path.SetPivot(path.TopNode.GetKey(0)); } else { Debug.Assert(leaf.RightLeaf == null, "only the rightmost leaf should ever be emptied"); // Leaf is empty. Prune it unless it is the only leaf in the tree. LeafNode leftLeaf = (LeafNode)path.GetLeftNode(); if (leftLeaf != null) { leftLeaf.RightLeaf = leaf.RightLeaf; _Demote(path); } return; } } // Leaf underflow? if (leaf.KeyCount < leaf.KeyCapacity / 2) { LeafNode rightLeaf = leaf.RightLeaf; if (rightLeaf != null) { if (leaf.KeyCount + rightLeaf.KeyCount > leaf.KeyCapacity) { // Balance leaves by shifting pairs from right leaf. int shifts = leaf.KeyCapacity - (leaf.KeyCount + rightLeaf.KeyCount - 1) / 2; leaf.Add(rightLeaf, 0, shifts); rightLeaf.Remove(0, shifts); path.TraverseRight(); path.SetPivot(path.TopNode.GetKey(0)); } else { // Coalesce right leaf to current leaf and prune right leaf. leaf.Add(rightLeaf, 0, rightLeaf.KeyCount); leaf.RightLeaf = rightLeaf.RightLeaf; path.TraverseRight(); _Demote(path); } } } }
public void BuildFromFile() { string refsText = Path.GetFullPath(Path.Combine(DataPath, "refs.txt")); string rawLine = "::from ./bsinstalldir.txt"; CommandNode root = new CommandNode(rawLine); LeafNode childToAdd = new LeafNode(@"""Beat Saber_Data/"); root.Add(childToAdd); childToAdd = new LeafNode(@"""""Managed/"); root.Add(childToAdd); childToAdd.Add(new FileNode(@"""""""Unity.TextMeshPro.dll?virt?alias=UnityAlias.TextMeshPro.dll")); childToAdd.Add(new FileNode(@"""""""UnityEngine.dll")); PrintChildren(root); }
/// <summary> /// Splits this node into subnodes by creating a new "right" node /// and adds the (key,value) to the appropriate subnode. /// </summary> private Node SplitAndInsert(TKey key, TValue value, BTreeDictionary <TKey, TValue> tree) { var iSplit = (count + 1) / 2; var right = new LeafNode(tree.LeafNodeChildren); right.count = count - iSplit; this.count = iSplit; right.totalCount = right.count; this.totalCount = this.count; Array.Copy(this.keys, iSplit, right.keys, 0, right.count); Array.Clear(this.keys, iSplit, right.count); Array.Copy(this.values, iSplit, right.values, 0, right.count); Array.Clear(this.values, iSplit, right.count); right.nextLeaf = this.nextLeaf; this.nextLeaf = right; if (tree.cmp.Compare(right.keys[0], key) < 0) { right.Add(key, value, tree); } else { this.Add(key, value, tree); } return(right); }
// Insert element at preseeked path. private void Insert(TreePath path, TKey key, TValue value) { ++VersionDirect; LeafNode leaf = (LeafNode)path.TopNode; int leafIndex = path.TopNodeIndex; if (leaf.NotFull) { leaf.Insert(leafIndex, key, value); ++CountDirect; return; } // Leaf overflow. Right split a new leaf. LeafNode newLeaf = new LeafNode(leaf); if (newLeaf.RightLeaf == null && leafIndex == leaf.KeyCount) { // Densify sequential loads. newLeaf.Add(key, value); } else { int halfway = leaf.KeyCount / 2 + 1; if (leafIndex < halfway) { // Left-side insert: Copy right side to the split leaf. newLeaf.Add(leaf, halfway - 1, leaf.KeyCount); leaf.Truncate(halfway - 1); leaf.Insert(leafIndex, key, value); } else { // Right-side insert: Copy split leaf parts and new key. newLeaf.Add(leaf, halfway, leafIndex); newLeaf.Add(key, value); newLeaf.Add(leaf, leafIndex, leaf.KeyCount); leaf.Truncate(halfway); } } // Promote anchor of split leaf. ++CountDirect; Promote(path, newLeaf.GetKey(0), newLeaf); }
public void AddOnLeafShouldCreateAnotherLeafIfKeysAreEqual () { var leaf = new LeafNode<string> (1, "hello"); var result = (LeafNode<string>) leaf.Add (1, "there"); Assert.That (result.Key, Is.EqualTo (1)); Assert.That (result.Value, Is.EqualTo ("there")); Assert.That (result.Count, Is.EqualTo (1)); }
public void AddOnLeafShouldCreateAnotherLeafIfKeysAreEqual() { var leaf = new LeafNode <string> (1, "hello"); var result = (LeafNode <string>)leaf.Add(1, "there"); Assert.That(result.Key, Is.EqualTo(1)); Assert.That(result.Value, Is.EqualTo("there")); Assert.That(result.Count, Is.EqualTo(1)); }
public void AddOnLeafShouldCreateBranchIfKeysAreDifferent () { var leaf = new LeafNode<string> (5, "hello"); //101 var branch = (BranchNode<string>) leaf.Add (7, "there"); //111 Assert.That (branch.Prefix, Is.EqualTo (1)); //x*1 Assert.That (branch.BranchingBit, Is.EqualTo (2)); // Assert.That (branch.Left, Is.SameAs (leaf)); var right = (branch.Right as LeafNode<string>); Assert.That (right, Is.Not.Null); Assert.That (right.Key, Is.EqualTo (7)); Assert.That (right.Value, Is.EqualTo ("there")); }
public void AddOnLeafShouldCreateBranchIfKeysAreDifferent() { var leaf = new LeafNode <string> (5, "hello"); //101 var branch = (BranchNode <string>)leaf.Add(7, "there"); //111 Assert.That(branch.Prefix, Is.EqualTo(1)); //x*1 Assert.That(branch.BranchingBit, Is.EqualTo(2)); // Assert.That(branch.Left, Is.SameAs(leaf)); var right = (branch.Right as LeafNode <string>); Assert.That(right, Is.Not.Null); Assert.That(right.Key, Is.EqualTo(7)); Assert.That(right.Value, Is.EqualTo("there")); }
public void Test_Tree_Delete() { var root = new InnerNode<int, int>(3); root.Keys.Add(15); var level1Child1 = new InnerNode<int, int>(3); level1Child1.Keys.Add(9); level1Child1.Keys.Add(12); var level2Child1 = new LeafNode<int, int>(3); level2Child1.Add(1, 1); level2Child1.Add(4, 4); level1Child1.Children.Add(level2Child1); var level2Child2 = new LeafNode<int, int>(3); level2Child2.Add(9, 9); level2Child2.Add(10, 10); level1Child1.Children.Add(level2Child2); var level2Child3 = new LeafNode<int, int>(3); level2Child3.Add(12, 12); level2Child3.Add(13, 13); level1Child1.Children.Add(level2Child3); root.Children.Add(level1Child1); var level1Child2 = new InnerNode<int, int>(3); level1Child2.Keys.Add(20); var level2Child4 = new LeafNode<int, int>(3); level2Child4.Add(15, 15); level2Child4.Add(16, 16); level1Child2.Children.Add(level2Child4); var level2Child5 = new LeafNode<int, int>(3); level2Child5.Add(20,20); level2Child5.Add(25,25); level1Child2.Children.Add(level2Child5); root.Children.Add(level1Child2); var tree = new Tree<int, int>(root); tree.Delete(13); Assert.AreEqual(1, root.Keys.Count); Assert.AreEqual(15, root.Keys[0]); var delete13Parent = (root.Children[0] as InnerNode<int, int>); Assert.AreEqual(2, delete13Parent.Keys.Count); Assert.AreEqual(09, delete13Parent.Keys[0]); Assert.AreEqual(12, delete13Parent.Keys[1]); Assert.AreEqual(3, delete13Parent.Children.Count); var delete13Child3 = delete13Parent.Children[2]; Assert.AreEqual(1, delete13Child3.Keys.Count); Assert.AreEqual(12, delete13Child3.Keys[0]); tree.Delete(15); var delete15Parent = (root.Children[1] as InnerNode<int, int>); Assert.AreEqual(1, delete15Parent.Keys.Count); Assert.AreEqual(20, delete15Parent.Keys[0]); Assert.AreEqual(2, delete15Parent.Children.Count); var delete15Child1 = delete15Parent.Children[0]; Assert.AreEqual(1, delete15Child1.Keys.Count); Assert.AreEqual(16, delete15Child1.Keys[0]); tree.Delete(12); var delete12Parent = (root.Children[0] as InnerNode<int, int>); Assert.AreEqual(2, delete12Parent.Keys.Count); Assert.AreEqual(9, delete12Parent.Keys[0]); Assert.AreEqual(10, delete12Parent.Keys[1]); Assert.AreEqual(3, delete12Parent.Children.Count); var delete12Child2 = delete12Parent.Children[1]; Assert.AreEqual(1, delete12Child2.Keys.Count); Assert.AreEqual(9, delete12Child2.Keys[0]); var delete12Child3 = delete12Parent.Children[2]; Assert.AreEqual(1, delete12Child3.Keys.Count); Assert.AreEqual(10, delete12Child3.Keys[0]); tree.Delete(16); var delete16Parent = (root.Children[1] as InnerNode<int, int>); Assert.AreEqual(2, delete16Parent.Children.Count); Assert.AreEqual(1, delete16Parent.Keys.Count); Assert.AreEqual(25, delete16Parent.Keys[0]); var delete16Child1 = delete16Parent.Children[0]; Assert.AreEqual(1, delete16Child1.Keys.Count); Assert.AreEqual(20, delete16Child1.Keys[0]); var delete16Child2 = delete16Parent.Children[1]; Assert.AreEqual(1, delete16Child2.Keys.Count); Assert.AreEqual(25, delete16Child2.Keys[0]); tree.Delete(25); tree.Delete(10); }