BTreeBranch(long transactionId, byte[][] newKeys, IBTreeNode[] newChildren, long[] newPairCounts) { TransactionId = transactionId; _keys = newKeys; _children = newChildren; _pairCounts = newPairCounts; }
public void CreateOrUpdate(CreateOrUpdateCtx ctx) { ctx.TransactionId = _transactionId; if (ctx.Stack == null) ctx.Stack = new List<NodeIdxPair>(); else ctx.Stack.Clear(); if (_rootNode == null) { _rootNode = ctx.WholeKeyLen > BTreeLeafComp.MaxTotalLen ? BTreeLeaf.CreateFirst(ctx) : BTreeLeafComp.CreateFirst(ctx); _keyValueCount = 1; ctx.Stack.Add(new NodeIdxPair { Node = _rootNode, Idx = 0 }); ctx.KeyIndex = 0; ctx.Created = true; return; } ctx.Depth = 0; _rootNode.CreateOrUpdate(ctx); if (ctx.Split) { _rootNode = new BTreeBranch(ctx.TransactionId, ctx.Node1, ctx.Node2); ctx.Stack.Insert(0, new NodeIdxPair { Node = _rootNode, Idx = ctx.SplitInRight ? 1 : 0 }); } else if (ctx.Update) { _rootNode = ctx.Node1; } if (ctx.Created) { _keyValueCount++; } }
public override IBTreeNode GetParent() { if (_parent != null) return _parent; _parent = Btree.GetPersister().LoadNodeById(_parentOid); return _parent; }
public override void SetChildAt(IBTreeNode child, int index) { _children[index] = child; if (child != null) { child.SetParent(this); } }
internal BTreeBranch(long transactionId, IBTreeNode node1, IBTreeNode node2) { TransactionId = transactionId; _children = new[] { node1, node2 }; _keys = new[] { node2.GetLeftMostKey() }; var leftCount = node1.CalcKeyCount(); var rightCount = node2.CalcKeyCount(); _pairCounts = new[] { leftCount, leftCount + rightCount }; }
public void BuildTree(long keyCount, Func<BTreeLeafMember> memberGenerator) { _keyValueCount = keyCount; if (keyCount == 0) { _rootNode = null; return; } _rootNode = BuildTreeNode(keyCount, memberGenerator); }
public override void SetChildAt(IBTreeNode node, int childIndex, int index, bool throwExceptionIfDoesNotExist) { var childTreeNode = node.GetChildAt(childIndex, throwExceptionIfDoesNotExist); _children[index] = childTreeNode; if (childTreeNode != null) childTreeNode.SetParent(this); }
public static void ValidateNode(IBTreeNode node) { if (!OdbConfiguration.IsBTreeValidationEnabled()) return; var nbKeys = node.GetNbKeys(); if (node.HasParent() && nbKeys < node.GetDegree() - 1) { var degree = (node.GetDegree() - 1).ToString(); throw new BTreeNodeValidationException("Node with less than " + degree + " keys"); } var maxNbKeys = node.GetDegree() * 2 - 1; var nbChildren = node.GetNbChildren(); var maxNbChildren = node.GetDegree() * 2; if (nbChildren != 0 && nbKeys == 0) throw new BTreeNodeValidationException("Node with no key but with children : " + node); for (var i = 0; i < nbKeys; i++) { if (node.GetKeyAndValueAt(i) == null) { var keyIndex = i.ToString(); throw new BTreeNodeValidationException("Null key at " + keyIndex + " on node " + node); } CheckValuesOfChild(node.GetKeyAndValueAt(i), node.GetChildAt(i, false)); } for (var i = nbKeys; i < maxNbKeys; i++) { if (node.GetKeyAndValueAt(i) != null) throw new BTreeNodeValidationException(string.Concat("Not Null key at ", i.ToString(), " on node " + node)); } IBTreeNode previousNode = null; for (var i = 0; i < nbChildren; i++) { if (node.GetChildAt(i, false) == null) throw new BTreeNodeValidationException(string.Concat("Null child at index ", i.ToString(), " on node " + node)); if (previousNode != null && previousNode == node.GetChildAt(i, false)) throw new BTreeNodeValidationException(string.Concat("Two equals children at index ", i.ToString(), " : " + previousNode)); previousNode = node.GetChildAt(i, false); } for (var i = nbChildren; i < maxNbChildren; i++) { if (node.GetChildAt(i, false) != null) throw new BTreeNodeValidationException(string.Concat("Not Null child at ", i.ToString(), " on node " + node)); } }
public StringBuilder Build(IBTreeNode node, int height, bool withIds) { _lines = new StringBuilder[height]; for (var i = 0; i < height; i++) _lines[i] = new StringBuilder(); BuildDisplay(node, 0, "0", withIds); BuildRepresentation(); return _result; }
public static void ValidateNode(IBTreeNode node, bool isRoot) { if (!OdbConfiguration.IsBTreeValidationEnabled()) return; ValidateNode(node); if (isRoot && node.HasParent()) throw new BTreeNodeValidationException("Root node with a parent: " + node); if (!isRoot && !node.HasParent()) throw new BTreeNodeValidationException("Internal node without parent: " + node); }
public override void SetChildAt(IBTreeNode child, int index) { if (child != null) { if (child.GetId() == null) Btree.GetPersister().SaveNode(child); _childrenOids[index] = (OID) child.GetId(); child.SetParent(this); } else { _childrenOids[index] = null; } }
public static void CheckDuplicateChildren(IBTreeNode node1, IBTreeNode node2) { if (!OdbConfiguration.IsBTreeValidationEnabled()) return; for (var i = 0; i < node1.GetNbChildren(); i++) { var child1 = node1.GetChildAt(i, true); for (var j = 0; j < node2.GetNbChildren(); j++) { if (child1 == node2.GetChildAt(j, true)) throw new BTreeNodeValidationException("Duplicated node : " + child1); } } }
public override void SetParent(IBTreeNode node) { _parent = node; if (_parent != null) { if (_parent.GetId() == null) Btree.GetPersister().SaveNode(_parent); _parentOid = (OID) _parent.GetId(); } else { _parentOid = null; } }
private static void CheckValuesOfChild(IKeyAndValue key, IBTreeNode node) { if (!OdbConfiguration.IsBTreeValidationEnabled()) { return; } if (node == null) { return; } for (int i = 0; i < node.GetNbKeys(); i++) { if (node.GetKeyAndValueAt(i).GetKey().CompareTo(key.GetKey()) >= 0) { throw new BTreeNodeValidationException("Left child with values bigger than pivot " + key + " : " + node); } } }
public void CreateOrUpdate(CreateOrUpdateCtx ctx) { ctx.TransactionId = _transactionId; if (ctx.Stack == null) { ctx.Stack = new List <NodeIdxPair>(); } else { ctx.Stack.Clear(); } if (_rootNode == null) { _rootNode = ctx.WholeKeyLen > BTreeLeafComp.MaxTotalLen ? BTreeLeaf.CreateFirst(ctx) : BTreeLeafComp.CreateFirst(ctx); _keyValueCount = 1; ctx.Stack.Add(new NodeIdxPair { Node = _rootNode, Idx = 0 }); ctx.KeyIndex = 0; ctx.Created = true; return; } ctx.Depth = 0; _rootNode.CreateOrUpdate(ctx); if (ctx.Split) { _rootNode = new BTreeBranch(ctx.TransactionId, ctx.Node1, ctx.Node2); ctx.Stack.Insert(0, new NodeIdxPair { Node = _rootNode, Idx = ctx.SplitInRight ? 1 : 0 }); } else if (ctx.Update) { _rootNode = ctx.Node1; } if (ctx.Created) { _keyValueCount++; } }
public IBTreeNode <char> Search(char c, IBTreeNode <char> node) { Stack <IBTreeNode <char> > stack = new Stack <IBTreeNode <char> >(); while (stack.Count > 0 || node != null) { if (node != null) { if (node.Val == c) { return(node); } stack.Push(node); node = node.Left; } else { node = stack.Pop().Right; } } return(node); }
/// <summary> /// saves the bree node Only puts the current node in an 'modified Node' map to be saved on commit /// </summary> public void SaveNode(IBTreeNode node) { OID oid; // Here we only save the node if it does not have id, // else we just save into the hashmap if (node.GetId() == StorageEngineConstant.NullObjectId) { try { // first get the oid. : -2:it could be any value oid = _engine.GetObjectWriter().GetIdManager().GetNextObjectId(-2); node.SetId(oid); oid = _engine.Store(oid, node); Log4NetHelper.Instance.LogDebugMessage(string.Format("LazyOdbBtreePersister: Saved node id {0}", oid)); // + " : " + // node.toString()); if (_tree != null && node.GetBTree() == null) { node.SetBTree(_tree); } _oids.Add(oid, node); return; } catch (Exception e) { throw new OdbRuntimeException(BTreeError.InternalError.AddParameter("While saving node"), e); } } oid = (OID)node.GetId(); _oids.Add(oid, node); AddModifiedOid(oid); }
protected override object GetValueAt(IBTreeNode node, int currentIndex) { if (_currentValue == null) { _currentValue = (IList)node.GetValueAsObjectAt(currentIndex); } var listSize = _currentValue.Count; if (listSize > _currenListIndex) { var value = _currentValue[_currenListIndex]; _currenListIndex++; return(value); } // We have reached the end of the list or the list is empty // We must continue iterate in the current node / btree _currenListIndex = 0; _currentValue = null; return(null); }
private void InsertNonFull(IBTreeNode node, IComparable key, object value) { if (node.IsLeaf()) { node.InsertKeyAndValue(key, value); _persister.SaveNode(node); return; } var position = node.GetPositionOfKey(key); // return an index starting // from 1 instead of 0 var realPosition = -position - 1; // If position is positive, the key must be inserted in this node if (position >= 0) { node.InsertKeyAndValue(key, value); _persister.SaveNode(node); return; } // descend var nodeToDescend = node.GetChildAt(realPosition, true); if (nodeToDescend.IsFull()) { Split(node, nodeToDescend, realPosition); if (node.GetKeyAt(realPosition).CompareTo(key) < 0) { nodeToDescend = node.GetChildAt(realPosition + 1, true); } } InsertNonFull(nodeToDescend, key, value); }
private void BuildDisplay(IBTreeNode node, int currentHeight, object parentId, bool withIds) { if (currentHeight > _lines.Length - 1) return; // get string buffer of this line var line = _lines[currentHeight]; if (withIds) line.Append(node.GetId()).Append(":["); else line.Append("["); for (var i = 0; i < node.GetNbKeys(); i++) { if (i > 0) line.Append(" , "); var keyAndValue = node.GetKeyAndValueAt(i); line.Append(keyAndValue.GetKey()); } if (withIds) line.Append("]:").Append(node.GetParentId()).Append("/").Append(parentId).Append(" "); else line.Append("] "); for (var i = 0; i < node.GetNbChildren(); i++) { var child = node.GetChildAt(i, false); if (child != null) BuildDisplay(child, currentHeight + 1, node.GetId(), withIds); else _lines[currentHeight + 1].Append(string.Concat("[Child {0} null!] ", (i + 1).ToString())); } }
/// <summary> /// 设置根节点 /// </summary> /// <param name="root"></param> public void SetRoot(IBTreeNode root) { mRoot = root; }
public void SaveNode(IBTreeNode node) { }
private void CheckIfCanMergeWith(IBTreeNode node) { if (NbKeys + node.GetNbKeys() > _maxNbKeys) { var errorMessage = string.Concat("Trying to merge two nodes with too many keys ", NbKeys.ToString(), " + ", node.GetNbKeys().ToString(), " > ", _maxNbKeys.ToString()); throw new BTreeException(errorMessage); } if (NbKeys > 0) { var greatestOfThis = Keys[NbKeys - 1]; var smallestOfOther = node.GetKeyAt(0); if (greatestOfThis.CompareTo(smallestOfOther) >= 0) { var errorMessage = string.Format("Trying to merge two nodes that have intersections : {0} / {1}", ToString(), node); throw new BTreeNodeValidationException(errorMessage); } } if (NbKeys < NbChildren) throw new BTreeNodeValidationException("Trying to merge two nodes where the first one has more children than keys"); }
public abstract void SetChildAt(IBTreeNode arg1, int arg2, int arg3, bool arg4);
public abstract override void SetChildAt(IBTreeNode arg1, int arg2);
public void CreateOrUpdate(CreateOrUpdateCtx ctx) { var index = Find(ctx.KeyPrefix, ctx.Key); ctx.Stack.Add(new NodeIdxPair { Node = this, Idx = index }); ctx.Depth++; _children[index].CreateOrUpdate(ctx); ctx.Depth--; var newBranch = this; if (ctx.Split) { ctx.Split = false; var newKeys = new byte[_children.Length][]; var newChildren = new IBTreeNode[_children.Length + 1]; var newPairCounts = new long[_children.Length + 1]; Array.Copy(_keys, 0, newKeys, 0, index); newKeys[index] = ctx.Node2.GetLeftMostKey(); Array.Copy(_keys, index, newKeys, index + 1, _keys.Length - index); Array.Copy(_children, 0, newChildren, 0, index); newChildren[index] = ctx.Node1; newChildren[index + 1] = ctx.Node2; Array.Copy(_children, index + 1, newChildren, index + 2, _children.Length - index - 1); Array.Copy(_pairCounts, newPairCounts, index); var previousPairCount = index > 0 ? newPairCounts[index - 1] : 0; for (var i = index; i < newPairCounts.Length; i++) { previousPairCount += newChildren[i].CalcKeyCount(); newPairCounts[i] = previousPairCount; } ctx.Node1 = null; ctx.Node2 = null; if (_children.Length < MaxChildren) { if (TransactionId != ctx.TransactionId) { newBranch = new BTreeBranch(ctx.TransactionId, newKeys, newChildren, newPairCounts); ctx.Node1 = newBranch; ctx.Update = true; } else { _keys = newKeys; _children = newChildren; _pairCounts = newPairCounts; } if (ctx.SplitInRight) { index++; } ctx.Stack[ctx.Depth] = new NodeIdxPair { Node = newBranch, Idx = index }; return; } if (ctx.SplitInRight) { index++; } ctx.Split = true; var keyCountLeft = (newChildren.Length + 1) / 2; var keyCountRight = newChildren.Length - keyCountLeft; var splitKeys = new byte[keyCountLeft - 1][]; var splitChildren = new IBTreeNode[keyCountLeft]; var splitPairCounts = new long[keyCountLeft]; Array.Copy(newKeys, splitKeys, splitKeys.Length); Array.Copy(newChildren, splitChildren, splitChildren.Length); Array.Copy(newPairCounts, splitPairCounts, splitPairCounts.Length); ctx.Node1 = new BTreeBranch(ctx.TransactionId, splitKeys, splitChildren, splitPairCounts); splitKeys = new byte[keyCountRight - 1][]; splitChildren = new IBTreeNode[keyCountRight]; splitPairCounts = new long[keyCountRight]; Array.Copy(newKeys, keyCountLeft, splitKeys, 0, splitKeys.Length); Array.Copy(newChildren, keyCountLeft, splitChildren, 0, splitChildren.Length); for (int i = 0; i < splitPairCounts.Length; i++) { splitPairCounts[i] = newPairCounts[keyCountLeft + i] - newPairCounts[keyCountLeft - 1]; } ctx.Node2 = new BTreeBranch(ctx.TransactionId, splitKeys, splitChildren, splitPairCounts); if (index < keyCountLeft) { ctx.Stack[ctx.Depth] = new NodeIdxPair { Node = ctx.Node1, Idx = index }; ctx.SplitInRight = false; } else { ctx.Stack[ctx.Depth] = new NodeIdxPair { Node = ctx.Node2, Idx = index - keyCountLeft }; ctx.SplitInRight = true; } return; } if (ctx.Update) { if (TransactionId != ctx.TransactionId) { var newKeys = new byte[_keys.Length][]; var newChildren = new IBTreeNode[_children.Length]; var newPairCounts = new long[_children.Length]; Array.Copy(_keys, newKeys, _keys.Length); Array.Copy(_children, newChildren, _children.Length); newChildren[index] = ctx.Node1; Array.Copy(_pairCounts, newPairCounts, _pairCounts.Length); newBranch = new BTreeBranch(ctx.TransactionId, newKeys, newChildren, newPairCounts); ctx.Node1 = newBranch; } else { _children[index] = ctx.Node1; ctx.Update = false; ctx.Node1 = null; } ctx.Stack[ctx.Depth] = new NodeIdxPair { Node = newBranch, Idx = index }; } Debug.Assert(newBranch.TransactionId == ctx.TransactionId); if (!ctx.Created) { return; } var pairCounts = newBranch._pairCounts; for (var i = index; i < pairCounts.Length; i++) { pairCounts[i]++; } }
private IBTreeNode PrepareForDelete(IBTreeNode parent, IBTreeNode child, int childIndex) { BTreeValidator.ValidateNode(parent); BTreeValidator.ValidateNode(child); // case 3a IBTreeNode leftSibling = null; IBTreeNode rightSibling = null; if (childIndex > 0 && parent.GetNbChildren() > 0) { leftSibling = parent.GetChildAt(childIndex - 1, false); } if (childIndex < parent.GetNbChildren() - 1) { rightSibling = parent.GetChildAt(childIndex + 1, false); } // case 3a left if (leftSibling != null && leftSibling.GetNbKeys() >= _degree) { var elementToMoveDown = parent.GetKeyAndValueAt(childIndex - 1); var elementToMoveUp = leftSibling.GetLastKeyAndValue(); parent.SetKeyAndValueAt(elementToMoveUp, childIndex - 1); child.InsertKeyAndValue(elementToMoveDown.GetKey(), elementToMoveDown.GetValue()); if (leftSibling.GetNbChildren() > leftSibling.GetNbKeys()) { // Take the last child of the left sibling and set it the // first child of the 'child' (incoming parameter) // child.setChildAt(leftSibling.getChildAt(leftSibling.getNbChildren() // - 1, true), 0); child.SetChildAt(leftSibling, leftSibling.GetNbChildren() - 1, 0, true); child.IncrementNbChildren(); } leftSibling.DeleteKeyAndValueAt(leftSibling.GetNbKeys() - 1, false); if (!leftSibling.IsLeaf()) { leftSibling.DeleteChildAt(leftSibling.GetNbChildren() - 1); } _persister.SaveNode(parent); _persister.SaveNode(child); _persister.SaveNode(leftSibling); if (OdbConfiguration.IsBTreeValidationEnabled()) { BTreeValidator.ValidateNode(parent, parent == _root); BTreeValidator.ValidateNode(child, false); BTreeValidator.ValidateNode(leftSibling, false); BTreeValidator.CheckDuplicateChildren(leftSibling, child); } return(parent); } // case 3a right if (rightSibling != null && rightSibling.GetNbKeys() >= _degree) { var elementToMoveDown = parent.GetKeyAndValueAt(childIndex); var elementToMoveUp = rightSibling.GetKeyAndValueAt(0); parent.SetKeyAndValueAt(elementToMoveUp, childIndex); child.InsertKeyAndValue(elementToMoveDown.GetKey(), elementToMoveDown.GetValue()); if (rightSibling.GetNbChildren() > 0) { // Take the first child of the right sibling and set it the // last child of the 'child' (incoming parameter) child.SetChildAt(rightSibling, 0, child.GetNbChildren(), true); child.IncrementNbChildren(); } rightSibling.DeleteKeyAndValueAt(0, true); _persister.SaveNode(parent); _persister.SaveNode(child); _persister.SaveNode(rightSibling); if (OdbConfiguration.IsBTreeValidationEnabled()) { BTreeValidator.ValidateNode(parent, parent == _root); BTreeValidator.ValidateNode(child, false); BTreeValidator.ValidateNode(rightSibling, false); BTreeValidator.CheckDuplicateChildren(rightSibling, child); } return(parent); } // case 3b var isCase3B = (leftSibling != null && leftSibling.GetNbKeys() == _degree - 1) || (rightSibling != null && rightSibling.GetNbKeys() >= _degree - 1); var parentWasSetToNull = false; if (isCase3B) { // choose left sibling to execute merge if (leftSibling != null) { var elementToMoveDown = parent.GetKeyAndValueAt(childIndex - 1); leftSibling.InsertKeyAndValue(elementToMoveDown.GetKey(), elementToMoveDown.GetValue()); leftSibling.MergeWith(child); parent.DeleteKeyAndValueAt(childIndex - 1, true); if (parent.GetNbKeys() == 0) { // this is the root if (!parent.HasParent()) { _root = leftSibling; _root.SetParent(null); _height--; parentWasSetToNull = true; } else { const string errorMessage = "Unexpected empty node that is node the root!"; throw new BTreeNodeValidationException(errorMessage); } } else { parent.SetChildAt(leftSibling, childIndex - 1); } if (parentWasSetToNull) { _persister.DeleteNode(parent); } else { _persister.SaveNode(parent); BTreeValidator.ValidateNode(parent, parent == _root); } // child was merged with another node it must be deleted _persister.DeleteNode(child); _persister.SaveNode(leftSibling); // Validator.validateNode(child, child == root); BTreeValidator.ValidateNode(leftSibling, leftSibling == _root); // Validator.checkDuplicateChildren(leftSibling, child); return(parentWasSetToNull ? _root : parent); } // choose right sibling to execute merge { var elementToMoveDown = parent.GetKeyAndValueAt(childIndex); child.InsertKeyAndValue(elementToMoveDown.GetKey(), elementToMoveDown.GetValue()); child.MergeWith(rightSibling); parent.DeleteKeyAndValueAt(childIndex, true); if (parent.GetNbKeys() == 0) { // this is the root if (!parent.HasParent()) { _root = child; _root.SetParent(null); _height--; parentWasSetToNull = true; } else { throw new BTreeNodeValidationException("Unexpected empty root node!"); } } else { parent.SetChildAt(child, childIndex); } if (parentWasSetToNull) { _persister.DeleteNode(parent); } else { _persister.SaveNode(parent); BTreeValidator.ValidateNode(parent, parent == _root); } _persister.DeleteNode(rightSibling); _persister.SaveNode(child); BTreeValidator.ValidateNode(child, child == _root); // Validator.validateNode(rightSibling, rightSibling == // root); // Validator.checkDuplicateChildren(rightSibling, child); return(parentWasSetToNull ? _root : parent); } } throw new BTreeNodeValidationException("Unexpected case in executing prepare for delete"); }
public void CreateOrUpdate(CreateOrUpdateCtx ctx) { var index = Find(ctx.KeyPrefix, ctx.Key); ctx.Stack.Add(new NodeIdxPair { Node = this, Idx = index }); ctx.Depth++; _children[index].CreateOrUpdate(ctx); ctx.Depth--; var newBranch = this; if (ctx.Split) { ctx.Split = false; var newKeys = new byte[_children.Length][]; var newChildren = new IBTreeNode[_children.Length + 1]; var newPairCounts = new long[_children.Length + 1]; Array.Copy(_keys, 0, newKeys, 0, index); newKeys[index] = ctx.Node2.GetLeftMostKey(); Array.Copy(_keys, index, newKeys, index + 1, _keys.Length - index); Array.Copy(_children, 0, newChildren, 0, index); newChildren[index] = ctx.Node1; newChildren[index + 1] = ctx.Node2; Array.Copy(_children, index + 1, newChildren, index + 2, _children.Length - index - 1); Array.Copy(_pairCounts, newPairCounts, index); var previousPairCount = index > 0 ? newPairCounts[index - 1] : 0; for (var i = index; i < newPairCounts.Length; i++) { previousPairCount += newChildren[i].CalcKeyCount(); newPairCounts[i] = previousPairCount; } ctx.Node1 = null; ctx.Node2 = null; if (_children.Length < MaxChildren) { if (TransactionId != ctx.TransactionId) { newBranch = new BTreeBranch(ctx.TransactionId, newKeys, newChildren, newPairCounts); ctx.Node1 = newBranch; ctx.Update = true; } else { _keys = newKeys; _children = newChildren; _pairCounts = newPairCounts; } if (ctx.SplitInRight) index++; ctx.Stack[ctx.Depth] = new NodeIdxPair { Node = newBranch, Idx = index }; return; } if (ctx.SplitInRight) index++; ctx.Split = true; var keyCountLeft = (newChildren.Length + 1) / 2; var keyCountRight = newChildren.Length - keyCountLeft; var splitKeys = new byte[keyCountLeft - 1][]; var splitChildren = new IBTreeNode[keyCountLeft]; var splitPairCounts = new long[keyCountLeft]; Array.Copy(newKeys, splitKeys, splitKeys.Length); Array.Copy(newChildren, splitChildren, splitChildren.Length); Array.Copy(newPairCounts, splitPairCounts, splitPairCounts.Length); ctx.Node1 = new BTreeBranch(ctx.TransactionId, splitKeys, splitChildren, splitPairCounts); splitKeys = new byte[keyCountRight - 1][]; splitChildren = new IBTreeNode[keyCountRight]; splitPairCounts = new long[keyCountRight]; Array.Copy(newKeys, keyCountLeft, splitKeys, 0, splitKeys.Length); Array.Copy(newChildren, keyCountLeft, splitChildren, 0, splitChildren.Length); for (int i = 0; i < splitPairCounts.Length; i++) { splitPairCounts[i] = newPairCounts[keyCountLeft + i] - newPairCounts[keyCountLeft - 1]; } ctx.Node2 = new BTreeBranch(ctx.TransactionId, splitKeys, splitChildren, splitPairCounts); if (index < keyCountLeft) { ctx.Stack[ctx.Depth] = new NodeIdxPair { Node = ctx.Node1, Idx = index }; ctx.SplitInRight = false; } else { ctx.Stack[ctx.Depth] = new NodeIdxPair { Node = ctx.Node2, Idx = index - keyCountLeft }; ctx.SplitInRight = true; } return; } if (ctx.Update) { if (TransactionId != ctx.TransactionId) { var newKeys = new byte[_keys.Length][]; var newChildren = new IBTreeNode[_children.Length]; var newPairCounts = new long[_children.Length]; Array.Copy(_keys, newKeys, _keys.Length); Array.Copy(_children, newChildren, _children.Length); newChildren[index] = ctx.Node1; Array.Copy(_pairCounts, newPairCounts, _pairCounts.Length); newBranch = new BTreeBranch(ctx.TransactionId, newKeys, newChildren, newPairCounts); ctx.Node1 = newBranch; } else { _children[index] = ctx.Node1; ctx.Update = false; ctx.Node1 = null; } ctx.Stack[ctx.Depth] = new NodeIdxPair { Node = newBranch, Idx = index }; } Debug.Assert(newBranch.TransactionId == ctx.TransactionId); if (!ctx.Created) return; var pairCounts = newBranch._pairCounts; for (var i = index; i < pairCounts.Length; i++) { pairCounts[i]++; } }
public IBTreeNode EraseRange(long transactionId, long firstKeyIndex, long lastKeyIndex) { int firstRemoved = -1; int lastRemoved = -1; IBTreeNode firstPartialNode = null; IBTreeNode lastPartialNode = null; for (int i = 0; i < _pairCounts.Length; i++) { var prevPairCount = i > 0 ? _pairCounts[i - 1] : 0; if (lastKeyIndex < prevPairCount) break; var nextPairCount = _pairCounts[i]; if (nextPairCount <= firstKeyIndex) continue; if (firstKeyIndex <= prevPairCount && nextPairCount - 1 <= lastKeyIndex) { if (firstRemoved == -1) firstRemoved = i; lastRemoved = i; continue; } if (prevPairCount <= firstKeyIndex && lastKeyIndex < nextPairCount) { firstRemoved = i; lastRemoved = i; firstPartialNode = _children[i].EraseRange(transactionId, firstKeyIndex - prevPairCount, lastKeyIndex - prevPairCount); lastPartialNode = firstPartialNode; break; } if (firstRemoved == -1 && firstKeyIndex < nextPairCount) { if (prevPairCount > firstKeyIndex) throw new InvalidOperationException(); if (nextPairCount > lastKeyIndex) throw new InvalidOperationException(); firstRemoved = i; firstPartialNode = _children[i].EraseRange(transactionId, firstKeyIndex - prevPairCount, nextPairCount - 1 - prevPairCount); continue; } if (lastKeyIndex >= nextPairCount - 1) throw new InvalidOperationException(); lastRemoved = i; lastPartialNode = _children[i].EraseRange(transactionId, 0, lastKeyIndex - prevPairCount); break; } var finalChildrenCount = firstRemoved - (firstPartialNode == null ? 1 : 0) + _children.Length + 1 - lastRemoved - (lastPartialNode == null ? 1 : 0) - (firstPartialNode == lastPartialNode && firstPartialNode != null ? 1 : 0); var newKeys = new byte[finalChildrenCount - 1][]; var newChildren = new IBTreeNode[finalChildrenCount]; var newPairCounts = new long[finalChildrenCount]; Array.Copy(_children, 0, newChildren, 0, firstRemoved); var idx = firstRemoved; if (firstPartialNode != null && firstPartialNode != lastPartialNode) { newChildren[idx] = firstPartialNode; idx++; } if (lastPartialNode != null) { newChildren[idx] = lastPartialNode; idx++; } Array.Copy(_children, lastRemoved + 1, newChildren, idx, finalChildrenCount - idx); var previousPairCount = 0L; for (var i = 0; i < finalChildrenCount; i++) { previousPairCount += newChildren[i].CalcKeyCount(); newPairCounts[i] = previousPairCount; } for (var i = 0; i < finalChildrenCount - 1; i++) { newKeys[i] = newChildren[i + 1].GetLeftMostKey(); } if (transactionId == TransactionId) { _keys = newKeys; _children = newChildren; _pairCounts = newPairCounts; return this; } return new BTreeBranch(transactionId, newKeys, newChildren, newPairCounts); }
public override void SetParent(IBTreeNode node) { _parent = node; }
public abstract void SetParent(IBTreeNode node);
private void DrawNode <TKey, TValue>(int arity, int depth, int maxDepth, int parent_pos, PointF parent, IBTreeNode <TKey, TValue> node) { // if (depth == 0) // arity = 2; var a = arity; // depth == 0 ? 2 : var pa = node.Owner?.ArityIndex ?? 0; var child = 0; var pos = 0; float DecideX() { pos = DecidePosition(parent_pos, child, a, depth); var x = pos * nodeSegmentWidth; // if (depth == 0) return(x); // return x - (parent_pos * nodeSegmentWidth / 2); // (maxDepth - depth) * (a + 1); } var point = new PointF(DecideX(), depth * layerHeight); DrawLine(parent, point); foreach (var value in node.Values) { var rect = new RectangleF(DecideX(), point.Y, nodeSegmentWidth, nodeHeight); if (value.IsAvailable) { var txt = $"{value.Key}: {value.Value}"; DrawCell(rect, txt); } var p = new PointF(rect.Left, rect.Bottom); // var off = (xOff - a / 2); if (value.LesserNode != null) { DrawNode(arity, depth + 1, maxDepth, pos, p, value.LesserNode); } child++; } }
public Input(string s, char n, char n1) { tree = Helfer.AssembleBTreeCharPreOrder(s); this.n = Search(n, tree.GetRoot()); this.n1 = Search(n1, tree.GetRoot()); }
protected override void Init() { _childrenOids = new OID[MaxNbChildren]; _parentOid = null; _parent = null; }
public static void ValidateNode(IBTreeNode node) { if (!OdbConfiguration.IsBTreeValidationEnabled()) { return; } int nbKeys = node.GetNbKeys(); if (node.HasParent() && nbKeys < node.GetDegree() - 1) { string degree = (node.GetDegree() - 1).ToString(); throw new BTreeNodeValidationException("Node with less than " + degree + " keys"); } int maxNbKeys = node.GetDegree() * 2 - 1; int nbChildren = node.GetNbChildren(); int maxNbChildren = node.GetDegree() * 2; if (nbChildren != 0 && nbKeys == 0) { throw new BTreeNodeValidationException("Node with no key but with children : " + node); } for (int i = 0; i < nbKeys; i++) { if (node.GetKeyAndValueAt(i) == null) { string keyIndex = i.ToString(); throw new BTreeNodeValidationException("Null key at " + keyIndex + " on node " + node); } CheckValuesOfChild(node.GetKeyAndValueAt(i), node.GetChildAt(i, false)); } for (int i = nbKeys; i < maxNbKeys; i++) { if (node.GetKeyAndValueAt(i) != null) { throw new BTreeNodeValidationException(string.Concat("Not Null key at ", i.ToString(), " on node " + node)); } } IBTreeNode previousNode = null; for (int i = 0; i < nbChildren; i++) { if (node.GetChildAt(i, false) == null) { throw new BTreeNodeValidationException(string.Concat("Null child at index ", i.ToString(), " on node " + node)); } if (previousNode != null && previousNode == node.GetChildAt(i, false)) { throw new BTreeNodeValidationException(string.Concat("Two equals children at index ", i.ToString(), " : " + previousNode)); } previousNode = node.GetChildAt(i, false); } for (int i = nbChildren; i < maxNbChildren; i++) { if (node.GetChildAt(i, false) != null) { throw new BTreeNodeValidationException(string.Concat("Not Null child at ", i.ToString(), " on node " + node)); } } }
public void DeleteNode(IBTreeNode parent) { }
private static void CheckValuesOfChild(IKeyAndValue key, IBTreeNode node) { if (!OdbConfiguration.IsBTreeValidationEnabled()) return; if (node == null) return; for (var i = 0; i < node.GetNbKeys(); i++) { if (node.GetKeyAndValueAt(i).GetKey().CompareTo(key.GetKey()) >= 0) throw new BTreeNodeValidationException("Left child with values bigger than pivot " + key + " : " + node); } }
IKeyAndValue IBTree.GetSmallest(IBTreeNode node, bool delete) { throw new NotImplementedException(); }
public abstract override void SetChildAt(IBTreeNode arg1, int arg2, int arg3, bool arg4);
protected abstract object GetValueAt(IBTreeNode node, int currentIndex);
/// <summary> /// Can only merge node without intersection => the greater key of this must be smaller than the smallest key of the node /// </summary> public virtual void MergeWith(IBTreeNode node) { BTreeValidator.ValidateNode(this); BTreeValidator.ValidateNode(node); CheckIfCanMergeWith(node); var j = NbKeys; for (var i = 0; i < node.GetNbKeys(); i++) { SetKeyAndValueAt(node.GetKeyAt(i), node.GetValueAsObjectAt(i), j, false, false); SetChildAt(node, i, j, false); j++; } // in this, we have to take the last child if (node.GetNbChildren() > node.GetNbKeys()) SetChildAt(node, node.GetNbChildren() - 1, j, true); NbKeys += node.GetNbKeys(); NbChildren += node.GetNbChildren(); BTreeValidator.ValidateNode(this); }
public override void Clear() { base.Clear(); _parent = null; _parentOid = null; _childrenOids = null; _oid = null; }
public abstract void SetChildAt(IBTreeNode arg1, int arg2);
public override void SetChildAt(IBTreeNode node, int childIndex, int indexDestination, bool throwExceptionIfDoesNotExist) { var childOid = (OID) node.GetChildIdAt(childIndex, throwExceptionIfDoesNotExist); _childrenOids[indexDestination] = childOid; if (childOid != null) { // The parent of the child has changed var child = Btree.GetPersister().LoadNodeById(childOid); child.SetParent(this); Btree.GetPersister().SaveNode(child); } }
public Input(string tree, int node) { this.tree = Helfer.AssembleBTreePreOrder(tree); this.node = this.tree.GetNodeByValue(node); }
/// <summary> /// 删除子节点 /// </summary> /// <param name="node"></param> public virtual void DelChild(IBTreeNode node) { mChildren.Remove(node); }
/// <summary> /// 设置结点 /// </summary> /// <param name="node"></param> public virtual void SetNode(IBTreeNode node) { mNode = node; }
/// <summary> /// 添加子节点 /// </summary> /// <param name="node"></param> public virtual void AddChild(IBTreeNode node) { mChildren.Add(node); }
/// <summary> /// Returns the value of the deleted key /// </summary> /// <param name="node"> </param> /// <param name="keyAndValue"> </param> /// <returns> </returns> /// <exception cref="System.Exception">System.Exception</exception> private object InternalDelete(IBTreeNode node, IKeyAndValue keyAndValue) { var positionOfKey = node.GetPositionOfKey(keyAndValue.GetKey()); var keyIsHere = positionOfKey > 0; if (node.IsLeaf()) { if (keyIsHere) { var deletedValue = node.DeleteKeyForLeafNode(keyAndValue); GetPersister().SaveNode(node); return(deletedValue); } // key does not exist return(null); } int realPosition; if (!keyIsHere) { // descend realPosition = -positionOfKey - 1; var childTreeNode = node.GetChildAt(realPosition, true); if (childTreeNode.GetNbKeys() == _degree - 1) { node = PrepareForDelete(node, childTreeNode, realPosition); return(InternalDelete(node, keyAndValue)); } return(InternalDelete(childTreeNode, keyAndValue)); } // Here,the node is not a leaf and contains the key realPosition = positionOfKey - 1; var currentKey = node.GetKeyAt(realPosition); var currentValue = node.GetValueAsObjectAt(realPosition); // case 2a var leftNode = node.GetChildAt(realPosition, true); if (leftNode.GetNbKeys() >= _degree) { var prevKeyAndValue = GetBiggest(leftNode, true); node.SetKeyAndValueAt(prevKeyAndValue, realPosition); BTreeValidator.ValidateNode(node, node == _root); GetPersister().SaveNode(node); return(currentValue); } // case 2b var rightNode = node.GetChildAt(realPosition + 1, true); if (rightNode.GetNbKeys() >= _degree) { var nextKeyAndValue = GetSmallest(rightNode, true); node.SetKeyAndValueAt(nextKeyAndValue, realPosition); BTreeValidator.ValidateNode(node, node == _root); GetPersister().SaveNode(node); return(currentValue); } // case 2c // Here, both left and right part have degree-1 keys // remove the element to be deleted from node (shifting left all // right // elements, link to right link does not exist anymore) // insert the key to be deleted in left child and merge the 2 nodes. // rightNode should be deleted // if node is root, then leftNode becomes the new root and node // should be deleted // node.DeleteKeyAndValueAt(realPosition, true); leftNode.InsertKeyAndValue(currentKey, currentValue); leftNode.MergeWith(rightNode); // If node is the root and is empty if (!node.HasParent() && node.GetNbKeys() == 0) { _persister.DeleteNode(node); _root = leftNode; leftNode.SetParent(null); // The height has been decreased. No need to save btree here. // The calling delete method will save it. _height--; } else { node.SetChildAt(leftNode, realPosition); // Node must only be validated if it is not the root BTreeValidator.ValidateNode(node, node == _root); } _persister.DeleteNode(rightNode); BTreeValidator.ValidateNode(leftNode, leftNode == _root); GetPersister().SaveNode(node); GetPersister().SaveNode(leftNode); return(InternalDelete(leftNode, keyAndValue)); }
public IBTreeNode EraseRange(long transactionId, long firstKeyIndex, long lastKeyIndex) { int firstRemoved = -1; int lastRemoved = -1; IBTreeNode firstPartialNode = null; IBTreeNode lastPartialNode = null; for (int i = 0; i < _pairCounts.Length; i++) { var prevPairCount = i > 0 ? _pairCounts[i - 1] : 0; if (lastKeyIndex < prevPairCount) { break; } var nextPairCount = _pairCounts[i]; if (nextPairCount <= firstKeyIndex) { continue; } if (firstKeyIndex <= prevPairCount && nextPairCount - 1 <= lastKeyIndex) { if (firstRemoved == -1) { firstRemoved = i; } lastRemoved = i; continue; } if (prevPairCount <= firstKeyIndex && lastKeyIndex < nextPairCount) { firstRemoved = i; lastRemoved = i; firstPartialNode = _children[i].EraseRange(transactionId, firstKeyIndex - prevPairCount, lastKeyIndex - prevPairCount); lastPartialNode = firstPartialNode; break; } if (firstRemoved == -1 && firstKeyIndex < nextPairCount) { if (prevPairCount > firstKeyIndex) { throw new InvalidOperationException(); } if (nextPairCount > lastKeyIndex) { throw new InvalidOperationException(); } firstRemoved = i; firstPartialNode = _children[i].EraseRange(transactionId, firstKeyIndex - prevPairCount, nextPairCount - 1 - prevPairCount); continue; } if (lastKeyIndex >= nextPairCount - 1) { throw new InvalidOperationException(); } lastRemoved = i; lastPartialNode = _children[i].EraseRange(transactionId, 0, lastKeyIndex - prevPairCount); break; } var finalChildrenCount = firstRemoved - (firstPartialNode == null ? 1 : 0) + _children.Length + 1 - lastRemoved - (lastPartialNode == null ? 1 : 0) - (firstPartialNode == lastPartialNode && firstPartialNode != null ? 1 : 0); var newKeys = new byte[finalChildrenCount - 1][]; var newChildren = new IBTreeNode[finalChildrenCount]; var newPairCounts = new long[finalChildrenCount]; Array.Copy(_children, 0, newChildren, 0, firstRemoved); var idx = firstRemoved; if (firstPartialNode != null && firstPartialNode != lastPartialNode) { newChildren[idx] = firstPartialNode; idx++; } if (lastPartialNode != null) { newChildren[idx] = lastPartialNode; idx++; } Array.Copy(_children, lastRemoved + 1, newChildren, idx, finalChildrenCount - idx); var previousPairCount = 0L; for (var i = 0; i < finalChildrenCount; i++) { previousPairCount += newChildren[i].CalcKeyCount(); newPairCounts[i] = previousPairCount; } for (var i = 0; i < finalChildrenCount - 1; i++) { newKeys[i] = newChildren[i + 1].GetLeftMostKey(); } if (transactionId == TransactionId) { _keys = newKeys; _children = newChildren; _pairCounts = newPairCounts; return(this); } return(new BTreeBranch(transactionId, newKeys, newChildren, newPairCounts)); }
public void EraseRange(long firstKeyIndex, long lastKeyIndex) { Debug.Assert(firstKeyIndex >= 0); Debug.Assert(lastKeyIndex < _keyValueCount); if (firstKeyIndex == 0 && lastKeyIndex == _keyValueCount - 1) { _rootNode = null; _keyValueCount = 0; return; } _keyValueCount -= lastKeyIndex - firstKeyIndex + 1; _rootNode = _rootNode.EraseRange(TransactionId, firstKeyIndex, lastKeyIndex); }
protected override object GetValueAt(IBTreeNode node, int currentIndex) { var n = (IBTreeNodeOneValuePerKey)node; return(n.GetValueAt(currentIndex)); }
public void RemappingIterate(BTreeRemappingIterateAction action) { if (_rootNode == null) return; _rootNode = _rootNode.RemappingIterate(TransactionId, action); }
void IBTree.Split(IBTreeNode parent, IBTreeNode node2Split, int childIndex) { throw new NotImplementedException(); }