public static MemoryTreeNode FindLastLeaf(TreeFile TreeFile, MemoryTreeNode currentNode = null) { if (currentNode == null) { currentNode = TreeFile.RootCache; } NodePointer pointer = new NodePointer(); var key = KeyFinder.FindLastKey(currentNode.TreeNode.KeyArray, TreeFile.comparer); if (key == null) { pointer.PointerBytes = currentNode.TreeNode.PreviousPointer; } else { pointer = currentNode.TreeNode.FindPointer(key); } if (pointer.PositionPointer > 0 && pointer.Indicator != EnumValues.TypeIndicator.leaf) { MemoryTreeNode newcachenode = GetOrLoadNode(TreeFile, currentNode, pointer); return(FindLastLeaf(TreeFile, newcachenode)); } ///find the leaf that contains the key. if (pointer.PointerBytes != null && pointer.PositionPointer > 0 && pointer.Indicator == EnumValues.TypeIndicator.leaf) { MemoryTreeNode newcacheleaf = GetOrLoadNode(TreeFile, currentNode, pointer); return(newcacheleaf); } return(null); }
public static MemoryTreeNode FindNextLeaf(TreeFile TreeFile, MemoryTreeNode CurrentLeaf) { if (CurrentLeaf.TreeNode.TypeIndicator != EnumValues.TypeIndicator.leaf) { throw new Exception("this method only accept leaf"); } byte[] key = KeyFinder.FindSmallestBiggerKey(CurrentLeaf.ParentNodeKey, CurrentLeaf.Parent.TreeNode.KeyArray, TreeFile.comparer); while (key != null) { var pointer = CurrentLeaf.Parent.TreeNode.FindPointer(key); if (pointer != null && pointer.PositionPointer > 0) { var nextleaf = GetOrLoadNode(TreeFile, CurrentLeaf.Parent, pointer); if (nextleaf != null && nextleaf.TreeNode.TypeIndicator == EnumValues.TypeIndicator.leaf) { return(nextleaf); } } key = KeyFinder.FindSmallestBiggerKey(key, CurrentLeaf.Parent.TreeNode.KeyArray, TreeFile.comparer); } return(GetUpLinkFirstLeaf(TreeFile, CurrentLeaf.Parent)); }
private static MemoryTreeNode GetUpLinkFirstLeaf(TreeFile TreeFile, MemoryTreeNode ParentNode) { if (ParentNode.TreeNode.TypeIndicator == EnumValues.TypeIndicator.root) { return(null); } MemoryTreeNode siblingNode; byte[] siblingkey = KeyFinder.FindSmallestBiggerKey(ParentNode.ParentNodeKey, ParentNode.Parent.TreeNode.KeyArray, TreeFile.comparer); while (siblingkey != null) { var pointer = ParentNode.Parent.TreeNode.FindPointer(siblingkey); if (pointer != null && pointer.PositionPointer > 0) { siblingNode = GetOrLoadNode(TreeFile, ParentNode.Parent, pointer); var result = FindContainerFirstLeaf(TreeFile, siblingNode); if (result != null) { return(result); } } siblingkey = KeyFinder.FindSmallestBiggerKey(siblingkey, ParentNode.Parent.TreeNode.KeyArray, TreeFile.comparer); } return(GetUpLinkFirstLeaf(TreeFile, ParentNode.Parent)); }
public static void NodeChange(TreeFile tree, MemoryTreeNode node) { if (node == null) { return; } if (node.TreeNode.TypeIndicator == EnumValues.TypeIndicator.root) { var treenode = tree.ReadNode(node.TreeNode.DiskPosition); var newrootcache = new MemoryTreeNode(treenode); tree.RootCache = newrootcache; } else { var parent = node.Parent; if (parent != null) { if (node.IsParentPreviousPointer) { parent.PreviousPointer = null; } else { parent.Children.Remove(node.TreeNode.DiskPosition); } } } node = null; }
public void Dispose() { //release the reference. this.treefile = null; this.startnode = null; this.endnode = null; this.currentnode = null; }
/// <summary> /// load the record, this is in the DESC mode. /// </summary> /// <param name="currentnode"></param> private void loadNodeRecordDESC(MemoryTreeNode currentnode) { //recordIndex = -1; //recordlistcount = 0; //recordlist.Clear(); foreach (var item in currentnode.TreeNode.KeyArray.OrderByDescending(o => o.Key, this.comparer)) { if (isCurrentStartNode) { if (isCurrentEndNode) { //both start and end in the same leaf. if ((this.comparer.Compare(startKeyBytes, item.Key) < 0 || (this.comparer.Compare(startKeyBytes, item.Key) == 0 && !this.lowerOpen)) && (this.comparer.Compare(endKeyBytes, item.Key) > 0 || (this.comparer.Compare(endKeyBytes, item.Key) == 0 && !this.upperOpen))) { NodePointer pointer = new NodePointer(); pointer.PointerBytes = item.Value; recordlist.Add(pointer); } } else { // the start node. if (this.comparer.Compare(endKeyBytes, item.Key) > 0 || (this.comparer.Compare(endKeyBytes, item.Key) == 0 && !this.upperOpen)) { NodePointer pointer = new NodePointer(); pointer.PointerBytes = item.Value; recordlist.Add(pointer); } } } else { // the end node. if (isCurrentEndNode) { if (this.comparer.Compare(startKeyBytes, item.Key) < 0 || (this.comparer.Compare(startKeyBytes, item.Key) == 0 && !this.lowerOpen)) { NodePointer pointer = new NodePointer(); pointer.PointerBytes = item.Value; recordlist.Add(pointer); } } else { //not start, not end, the middle one, insert everything. NodePointer pointer = new NodePointer(); pointer.PointerBytes = item.Value; recordlist.Add(pointer); } } } recordlistcount = recordlist.Count; }
public static MemoryTreeNode GetOrLoadNode(TreeFile TreeFile, MemoryTreeNode ParentNode, NodePointer Pointer) { if (Pointer.IsFirstPreviousPointer) { if (ParentNode.PreviousPointer != null) { return(ParentNode.PreviousPointer); } else { TreeNode node = TreeFile.ReadNode(Pointer.PositionPointer); if (node == null) { return(null); } MemoryTreeNode newcachenode = new MemoryTreeNode(node); newcachenode.Parent = ParentNode; newcachenode.IsParentPreviousPointer = Pointer.IsFirstPreviousPointer; newcachenode.ParentNodeKey = Pointer.KeyToPosition; newcachenode.Level = ParentNode.Level + 1; if (newcachenode.Level < TreeFile.MaxCacheLevel) { ParentNode.PreviousPointer = newcachenode; } return(newcachenode); } } else { if (ParentNode.Children.ContainsKey(Pointer.PositionPointer)) { return(ParentNode.Children[Pointer.PositionPointer]); } else { TreeNode node = TreeFile.ReadNode(Pointer.PositionPointer); if (node == null) { return(null); } MemoryTreeNode newcachenode = new MemoryTreeNode(node); newcachenode.Parent = ParentNode; newcachenode.IsParentPreviousPointer = Pointer.IsFirstPreviousPointer; newcachenode.ParentNodeKey = Pointer.KeyToPosition; newcachenode.Level = ParentNode.Level + 1; if (newcachenode.Level < TreeFile.MaxCacheLevel) { ParentNode.Children[Pointer.PositionPointer] = newcachenode; } return(newcachenode); } } }
private static MemoryTreeNode FindContainerLastLeaf(TreeFile TreeFile, MemoryTreeNode ContainerNode) { if (ContainerNode == null) { return(null); } if (ContainerNode.TreeNode.TypeIndicator == EnumValues.TypeIndicator.leaf) { return(ContainerNode); } NodePointer pointer = new NodePointer(); pointer.PointerBytes = ContainerNode.TreeNode.PreviousPointer; if (pointer.PositionPointer > 0) { var subnode = GetOrLoadNode(TreeFile, ContainerNode, pointer); if (subnode != null) { var result = FindContainerFirstLeaf(TreeFile, subnode); if (result != null) { return(result); } } } // did not get return, try one key by one key. byte[] key = KeyFinder.FindSmallestBiggerKey(null, ContainerNode.TreeNode.KeyArray, TreeFile.comparer); while (key != null) { var nodepointer = ContainerNode.TreeNode.FindPointer(key); if (nodepointer != null && nodepointer.PositionPointer > 0) { var keynode = GetOrLoadNode(TreeFile, ContainerNode, nodepointer); if (keynode != null) { var result = FindContainerFirstLeaf(TreeFile, keynode); if (result != null) { return(result); } } } key = KeyFinder.FindSmallestBiggerKey(key, ContainerNode.TreeNode.KeyArray, TreeFile.comparer); } return(null); }
private void getnextnode() { recordIndex = -1; recordlistcount = 0; recordlist.Clear(); newRecordList.Clear(); if (this.currentnode.TreeNode.DiskPosition == this.endnode.TreeNode.DiskPosition) { return; } if (ascending) { this.currentnode = MemoryTreeNodeManager.FindNextLeaf(this.treefile, currentnode); } else { this.currentnode = MemoryTreeNodeManager.FindPreviousLeaf(this.treefile, currentnode); } if (this.currentnode == null) { return; } if (this.currentnode.TreeNode.DiskPosition == this.startnode.TreeNode.DiskPosition) { this.isCurrentStartNode = true; } else { this.isCurrentStartNode = false; } if (this.currentnode.TreeNode.DiskPosition == this.endnode.TreeNode.DiskPosition) { this.isCurrentEndNode = true; } else { this.isCurrentEndNode = false; } if (ascending) { loadNodeRecord(currentnode); } else { loadNodeRecordDESC(currentnode); } }
private static MemoryTreeNode GetUpLinkLastLeaf(TreeFile TreeFile, MemoryTreeNode ParentNode) { if (ParentNode.TreeNode.TypeIndicator == EnumValues.TypeIndicator.root) { return(null); } MemoryTreeNode siblingNode; byte[] siblingkey = KeyFinder.FindBiggestSmallerKey(ParentNode.ParentNodeKey, ParentNode.Parent.TreeNode.KeyArray, TreeFile.comparer); while (siblingkey != null) { var pointer = ParentNode.Parent.TreeNode.FindPointer(siblingkey); if (pointer != null && pointer.PositionPointer > 0) { siblingNode = GetOrLoadNode(TreeFile, ParentNode.Parent, pointer); var result = FindContainerLastLeaf(TreeFile, siblingNode); if (result != null) { return(result); } } siblingkey = KeyFinder.FindBiggestSmallerKey(siblingkey, ParentNode.Parent.TreeNode.KeyArray, TreeFile.comparer); } /// need to check the first previous pointer after process all key arrays. NodePointer previousPointer = new NodePointer(); previousPointer.PointerBytes = ParentNode.Parent.TreeNode.PreviousPointer; var PreviousPointerNode = GetOrLoadNode(TreeFile, ParentNode.Parent, previousPointer); //parentNode.Parent.PreviousPointerNode can't be the same with ParentNode,otherwise it will cause a dead cycle. if (PreviousPointerNode != null && ParentNode != PreviousPointerNode) { var result = FindContainerLastLeaf(TreeFile, PreviousPointerNode); if (result != null) { return(result); } } return(GetUpLinkLastLeaf(TreeFile, ParentNode.Parent)); }
public static MemoryTreeNode FindPreviousLeaf(TreeFile TreeFile, MemoryTreeNode CurrentLeaf) { if (CurrentLeaf.TreeNode.TypeIndicator != EnumValues.TypeIndicator.leaf) { throw new Exception("this method only accept leaf"); } if (CurrentLeaf.IsParentPreviousPointer && CurrentLeaf.ParentNodeKey == null) { return(GetUpLinkLastLeaf(TreeFile, CurrentLeaf.Parent)); } byte[] key = KeyFinder.FindBiggestSmallerKey(CurrentLeaf.ParentNodeKey, CurrentLeaf.Parent.TreeNode.KeyArray, TreeFile.comparer); while (key != null) { var pointer = CurrentLeaf.Parent.TreeNode.FindPointer(key); if (pointer != null && pointer.PositionPointer > 0) { var nextleaf = GetOrLoadNode(TreeFile, CurrentLeaf.Parent, pointer); if (nextleaf != null && nextleaf.TreeNode.TypeIndicator == EnumValues.TypeIndicator.leaf) { return(nextleaf); } } key = KeyFinder.FindBiggestSmallerKey(key, CurrentLeaf.Parent.TreeNode.KeyArray, TreeFile.comparer); } // check the previous pointer. NodePointer previousPointer = new NodePointer(); previousPointer.PointerBytes = CurrentLeaf.Parent.TreeNode.PreviousPointer; var PreviousPointerLeaf = GetOrLoadNode(TreeFile, CurrentLeaf.Parent, previousPointer); if (PreviousPointerLeaf != null && PreviousPointerLeaf.TreeNode.TypeIndicator == EnumValues.TypeIndicator.leaf) { return(PreviousPointerLeaf); } return(GetUpLinkLastLeaf(TreeFile, CurrentLeaf.Parent)); }
/// <summary> /// Find by key, return the lowerest node... /// </summary> /// <param name="currentNode"></param> /// <param name="Key"></param> /// <returns></returns> public static MemoryTreeNode FindLeafByKey(TreeFile Tree, MemoryTreeNode currentNode, byte[] Keybytes) { NodePointer pointer = currentNode.TreeNode.FindPointer(Keybytes); if (pointer.PositionPointer == 0) { Tree.CreateFirstLeaf(currentNode.TreeNode); NodeChange(Tree, currentNode); return(FindLeafByKey(Tree, Tree.RootCache, Keybytes)); } MemoryTreeNode foundnode = GetOrLoadNode(Tree, currentNode, pointer); if (foundnode.TreeNode.TypeIndicator == EnumValues.TypeIndicator.leaf) { return(foundnode); } else { return(FindLeafByKey(Tree, foundnode, Keybytes)); } }
private void init() { if (ascending) { this.startnode = MemoryTreeNodeManager.FindLeafByKey(this.treefile, this.treefile.RootCache, startKeyBytes); this.endnode = MemoryTreeNodeManager.FindLeafByKey(this.treefile, this.treefile.RootCache, endKeyBytes); } else { //load the last key as startnode, firstkey as endnode. this.endnode = MemoryTreeNodeManager.FindLeafByKey(this.treefile, this.treefile.RootCache, startKeyBytes); this.startnode = MemoryTreeNodeManager.FindLeafByKey(this.treefile, this.treefile.RootCache, endKeyBytes); } this.currentnode = startnode; if (currentnode == null) { return; } isCurrentStartNode = true; if (currentnode.TreeNode.DiskPosition == endnode.TreeNode.DiskPosition) { isCurrentEndNode = true; } recordIndex = -1; recordlistcount = 0; if (ascending) { loadNodeRecord(currentnode); } else { loadNodeRecordDESC(currentnode); } }
public static void NodeReload(TreeFile tree, MemoryTreeNode node) { var newnode = tree.ReadNode(node.TreeNode.DiskPosition); node.TreeNode = newnode; }
/// <summary> /// Get the count of records in the range. count distinct will have better performance. /// </summary> /// <param name="range"></param> /// <param name="distinct"></param> /// <returns></returns> public int Count(Range <T> range, bool distinct) { lock (_object) { byte[] startKeyBytes = this.Converter.ToByte(range.lower); byte[] endKeyBytes = this.Converter.ToByte(range.upper); startKeyBytes = this.appendToFixedLength(startKeyBytes); endKeyBytes = this.appendToFixedLength(endKeyBytes); MemoryTreeNode startnode = MemoryTreeNodeManager.FindLeafByKey(this.Tree, this.Tree.RootCache, startKeyBytes); MemoryTreeNode endnode = MemoryTreeNodeManager.FindLeafByKey(this.Tree, this.Tree.RootCache, endKeyBytes); if (startnode.TreeNode.DiskPosition == endnode.TreeNode.DiskPosition) { int count = 0; foreach (var item in startnode.TreeNode.KeyArray) { if ((this.Comparer.Compare(startKeyBytes, item.Key) < 0 || (this.Comparer.Compare(startKeyBytes, item.Key) == 0 && !range.lowerOpen)) && ((this.Comparer.Compare(endKeyBytes, item.Key) > 0 || (this.Comparer.Compare(endKeyBytes, item.Key) == 0 && !range.upperOpen)))) { if (!distinct) { NodePointer pointer = new NodePointer(); pointer.PointerBytes = item.Value; if (pointer.Indicator == EnumValues.TypeIndicator.duplicate) { count = count + this.Tree.duplicate.count(pointer.PositionPointer); } else { count += 1; } } else { count += 1; } } } return(count); } else { int firstnodecount = 0; int lastnodecount = 0; int middlecount = 0; foreach (var item in startnode.TreeNode.KeyArray) { if (this.Comparer.Compare(startKeyBytes, item.Key) < 0 || (this.Comparer.Compare(startKeyBytes, item.Key) == 0 && !range.lowerOpen)) { if (!distinct) { NodePointer pointer = new NodePointer(); pointer.PointerBytes = item.Value; if (pointer.Indicator == EnumValues.TypeIndicator.duplicate) { firstnodecount = firstnodecount + this.Tree.duplicate.count(pointer.PositionPointer); } else { firstnodecount += 1; } } else { firstnodecount += 1; } } } foreach (var item in endnode.TreeNode.KeyArray) { if (this.Comparer.Compare(endKeyBytes, item.Key) > 0 || (this.Comparer.Compare(endKeyBytes, item.Key) == 0 && !range.upperOpen)) { if (!distinct) { NodePointer pointer = new NodePointer(); pointer.PointerBytes = item.Value; if (pointer.Indicator == EnumValues.TypeIndicator.duplicate) { lastnodecount = lastnodecount + this.Tree.duplicate.count(pointer.PositionPointer); } else { lastnodecount += 1; } } else { lastnodecount += 1; } } } var middlenode = MemoryTreeNodeManager.FindNextLeaf(this.Tree, startnode); while (middlenode.TreeNode.DiskPosition != endnode.TreeNode.DiskPosition) { foreach (var item in middlenode.TreeNode.KeyArray) { if (!distinct) { NodePointer pointer = new NodePointer(); pointer.PointerBytes = item.Value; if (pointer.Indicator == EnumValues.TypeIndicator.duplicate) { middlecount = middlecount + this.Tree.duplicate.count(pointer.PositionPointer); } else { middlecount += 1; } } else { middlecount += 1; } } middlenode = MemoryTreeNodeManager.FindNextLeaf(this.Tree, middlenode); } return(firstnodecount + middlecount + lastnodecount); } } }
public void AddChild(MemoryTreeNode memorynode) { memorynode.Parent = this; memorynode.Level = this.Level + 1; this.Children.Add(memorynode.TreeNode.DiskPosition, memorynode); }