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 bool MoveNext() { ///if in duplicate mode. if (inDuplicateMode) { Int64 nextdup = duplicatereader.ReadNext(); if (nextdup > 0) { this.currentValue = nextdup; return(true); } else { // end of duplicate. this.inDuplicateMode = false; this.duplicatereader = null; // cotinue with the getnextpointer; } } NodePointer pointer = getnextpointer(); if (pointer == null) { return(false); } /// else /// if (pointer.Indicator == EnumValues.TypeIndicator.block) { this.currentValue = pointer.PositionPointer; return(true); } else if (pointer.Indicator == EnumValues.TypeIndicator.duplicate) { duplicatereader = this.treefile.duplicate.getReader(pointer.PositionPointer); Int64 nextdup = duplicatereader.ReadNext(); if (nextdup > 0) { this.currentValue = nextdup; this.inDuplicateMode = true; return(true); } else { // there is no item in the duplicate, should not be possible, just to make sure. this.duplicatereader = null; this.inDuplicateMode = false; // go to the next record again. return(MoveNext()); } } else { /// should not be possible. return(false); } }
/// <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; }
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 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)); }
/// <summary> /// find the pointer to next node or leaf that should contains the key. /// </summary> /// <param name="key"></param> /// <returns></returns> public NodePointer FindPointer(byte[] key) { NodePointer nodepointer = new NodePointer(); byte[] currentkey = key; byte[] currentvalue = new byte[NodePointer.Length]; bool found = false; foreach (var item in KeyArray) { if (this.tree.comparer.Compare(key, item.Key) >= 0) { if (!found) { found = true; currentkey = item.Key; currentvalue = item.Value; } else { if (this.tree.comparer.Compare(item.Key, currentkey) > 0) { currentkey = item.Key; currentvalue = item.Value; } } } } if (found) { nodepointer.KeyToPosition = currentkey; nodepointer.PointerBytes = currentvalue; } else { nodepointer.PointerBytes = this.PreviousPointer; nodepointer.IsFirstPreviousPointer = true; } return(nodepointer); }
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)); } }
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); } } }
/// <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); } } }