public override Node Remove(TKey key, ConcurrentBTreeDictionary <TKey, TValue> tree) { int idx = Array.BinarySearch(keys, 1, count - 1, key, tree.Comparer); Node removed; int iPos; if (idx >= 0) { iPos = idx; } else { iPos = (~idx) - 1; } removed = nodes[iPos].Remove(key, tree); if (removed != null) { var nKeys = new TKey[tree.InternalNodeChildren]; var nNodes = new Node[tree.InternalNodeChildren]; Array.Copy(this.keys, 0, nKeys, 0, this.count); Array.Copy(this.nodes, 0, nNodes, 0, this.count); nNodes[iPos] = removed; removed = new InternalNode(nKeys, nNodes, this.count, this.totalCount - 1); } return(removed); }
private (Node, Node) Insert(int idx, TKey key, Node leftNode, Node node, ConcurrentBTreeDictionary <TKey, TValue> tree) { if (count == keys.Length) { return(SplitAndInsert(key, idx, leftNode, node, tree)); } var nKeys = new TKey[tree.InternalNodeChildren]; var nNodes = new Node[tree.InternalNodeChildren]; Array.Copy(this.keys, 0, nKeys, 0, idx); Array.Copy(this.nodes, 0, nNodes, 0, idx); if (idx < count) { // Leave a 'hole' at position idx. Array.Copy(this.keys, idx, nKeys, idx + 1, count - idx); Array.Copy(this.nodes, idx, nNodes, idx + 1, count - idx); } nNodes[idx - 1] = leftNode; nKeys[idx] = key; nNodes[idx] = node; int nCount = this.count + 1; var newNode = new InternalNode(nKeys, nNodes, this.count + 1, SumNodeCounts(nNodes, nCount)); return(newNode, null); }
public ConcurrentBTreeDictionary(ConcurrentBTreeDictionary <TKey, TValue> that) { this.Comparer = that.Comparer; this.version = 0; this.InternalNodeChildren = that.InternalNodeChildren; this.LeafNodeChildren = that.LeafNodeChildren; this.keyCollection = new KeyCollection(this); this.valueCollection = new ValueCollection(this); this.root = that.root; // Snapshot the old tree. }
public override (TValue, bool) Get(TKey key, ConcurrentBTreeDictionary <TKey, TValue> tree) { int idx = Array.BinarySearch(keys, 0, count, key, tree.Comparer); if (idx < 0) { return(default(TValue), false); } return(values[idx], true); }
/// <summary> /// Splits this node into subnodes by creating a new "left" and /// a new "right" node and adds the (key,value) to the appropriate subnode. /// </summary> private (Node, Node) SplitAndInsert(TKey key, TValue value, ConcurrentBTreeDictionary <TKey, TValue> tree) { var iSplit = (this.count + 1) / 2; var leftCount = iSplit; var rightCount = this.count - iSplit; var lKeys = new TKey[tree.LeafNodeChildren]; var rKeys = new TKey[tree.LeafNodeChildren]; var lValues = new TValue[tree.LeafNodeChildren]; var rValues = new TValue[tree.LeafNodeChildren]; Array.Copy(this.keys, 0, lKeys, 0, leftCount); Array.Copy(this.keys, iSplit, rKeys, 0, rightCount); Array.Copy(this.values, 0, lValues, 0, leftCount); Array.Copy(this.values, iSplit, rValues, 0, rightCount); TKey[] nKeys; TValue[] nValues; int count; if (tree.Comparer.Compare(rKeys[0], key) < 0) { nKeys = rKeys; nValues = rValues; count = rightCount; ++rightCount; } else { nKeys = lKeys; nValues = lValues; count = leftCount; ++leftCount; } // Find the place where the item would be if it had been present. int idx = Array.BinarySearch(nKeys, 0, count, key, tree.Comparer); if (idx >= 0) { throw new ArgumentException("Duplicate key."); } idx = ~idx; if (idx < count) { // Make a 'hole' if the place is not at the end of the items. Array.Copy(nKeys, idx, nKeys, idx + 1, count - idx); Array.Copy(nValues, idx, nValues, idx + 1, count - idx); } nKeys[idx] = key; nValues[idx] = value; var left = new LeafNode(lKeys, lValues, leftCount, leftCount); var right = new LeafNode(rKeys, rValues, rightCount, rightCount); return(left, right); }
public override (TValue, bool) Get(TKey key, ConcurrentBTreeDictionary <TKey, TValue> tree) { int idx = Array.BinarySearch(keys, 1, count - 1, key, tree.Comparer); if (idx >= 0) { return(nodes[idx].Get(key, tree)); } else { var iPos = (~idx) - 1; return(nodes[iPos].Get(key, tree)); } }
public override Node Remove(TKey key, ConcurrentBTreeDictionary <TKey, TValue> tree) { int idx = Array.BinarySearch(keys, 0, count, key, tree.Comparer); if (idx >= 0) { var nKeys = new TKey[this.keys.Length]; var nValues = new TValue[this.values.Length]; var nCount = this.count - 1; if (idx > 0) { Array.Copy(keys, 0, nKeys, 0, idx); Array.Copy(values, 0, nValues, 0, idx); } Array.Copy(keys, idx + 1, nKeys, idx, nCount - idx); Array.Copy(values, idx + 1, nValues, idx, nCount - idx); var newNode = new LeafNode(nKeys, nValues, nCount, nCount); return(newNode); } return(null); }
private (Node, Node) Insert(int idx, TKey key, TValue value, ConcurrentBTreeDictionary <TKey, TValue> tree) { if (count == keys.Length) { return(SplitAndInsert(key, value, tree)); } var nKeys = new TKey[tree.LeafNodeChildren]; var nValues = new TValue[tree.LeafNodeChildren]; Array.Copy(keys, 0, nKeys, 0, idx); Array.Copy(values, 0, nValues, 0, idx); if (idx < count) { // Leave a hole at position idx. Array.Copy(keys, idx, nKeys, idx + 1, count - idx); Array.Copy(values, idx, nValues, idx + 1, count - idx); } nKeys[idx] = key; nValues[idx] = value; var newNode = new LeafNode(nKeys, nValues, this.count + 1, this.totalCount + 1); return(newNode, null); }
public override (Node, Node) Put(TKey key, TValue value, bool setting, ConcurrentBTreeDictionary <TKey, TValue> tree) { int idx = Array.BinarySearch(keys, 0, count, key, tree.Comparer); if (idx >= 0) { if (!setting) { throw new ArgumentException("Duplicate key."); } var nKeys = new TKey[tree.LeafNodeChildren]; var nValues = new TValue[tree.LeafNodeChildren]; Array.Copy(this.keys, 0, nKeys, 0, this.count); Array.Copy(this.values, 0, nValues, 0, this.count); nValues[idx] = value; var newNode = new LeafNode(nKeys, nValues, this.count, this.totalCount); return(newNode, null); } else { return(Insert(~idx, key, value, tree)); } }
public override (Node, Node) Put(TKey key, TValue value, bool setting, ConcurrentBTreeDictionary <TKey, TValue> tree) { int idx = Array.BinarySearch(keys, 1, count - 1, key, tree.Comparer); int iPos = (idx >= 0) ? idx : (~idx) - 1; var subnode = nodes[iPos]; var(leftNode, rightNode) = subnode.Put(key, value, setting, tree); if (rightNode == null) { var nKeys = new TKey[tree.InternalNodeChildren]; var nNodes = new Node[tree.InternalNodeChildren]; Array.Copy(this.keys, 0, nKeys, 0, this.count); Array.Copy(this.nodes, 0, nNodes, 0, this.count); nNodes[iPos] = leftNode; var newNode = new InternalNode(nKeys, nNodes, this.count, SumNodeCounts(nNodes, this.count)); return(newNode, null); } else { return(Insert(iPos + 1, rightNode.keys[0], leftNode, rightNode, tree)); } }
/// <summary> /// Make a pair of new nodes by partitioning the subnodes of the current node. /// </summary> private (Node, Node) SplitAndInsert(TKey key, int iLeft, Node leftNode, Node node, ConcurrentBTreeDictionary <TKey, TValue> tree) { var iSplit = (this.count + 1) / 2; var lKeys = new TKey[tree.InternalNodeChildren]; var rKeys = new TKey[tree.InternalNodeChildren]; var lNodes = new Node[tree.InternalNodeChildren]; var rNodes = new Node[tree.InternalNodeChildren]; var leftCount = iSplit; var rightCount = this.count - iSplit; Array.Copy(this.keys, 0, lKeys, 0, leftCount); Array.Copy(this.keys, iSplit, rKeys, 0, rightCount); Array.Copy(this.nodes, 0, lNodes, 0, leftCount); Array.Copy(this.nodes, iSplit, rNodes, 0, rightCount); if (iLeft - 1 < iSplit) { lNodes[iLeft - 1] = leftNode; } else { rNodes[iLeft - (iSplit + 1)] = leftNode; } TKey[] nKeys; Node[] nNodes; int count; if (tree.Comparer.Compare(rKeys[0], key) < 0) { nKeys = rKeys; nNodes = rNodes; count = rightCount; ++rightCount; } else { nKeys = lKeys; nNodes = lNodes; count = leftCount; ++leftCount; } int idx = Array.BinarySearch(nKeys, 1, count - 1, key, tree.Comparer); if (idx >= 0) { throw new ArgumentException("Duplicate key."); } idx = ~idx; if (idx < count) { // Leave a 'hole' at position idx. Array.Copy(nKeys, idx, nKeys, idx + 1, count - idx); Array.Copy(nNodes, idx, nNodes, idx + 1, count - idx); } nKeys[idx] = key; nNodes[idx] = node; var left = new InternalNode(lKeys, lNodes, leftCount, SumNodeCounts(lNodes, leftCount)); var right = new InternalNode(rKeys, rNodes, rightCount, SumNodeCounts(rNodes, rightCount)); return(left, right); }
/// <summary> /// Removes the key from the node. /// </summary> /// <param name="key">Key to remove</param> /// <param name="tree">The ConcurrentBTreeDictionary</param> /// <returns>A new node if <paramref name="key"/> was found and deleted, otherwise null.</returns> public abstract Node Remove(TKey key, ConcurrentBTreeDictionary <TKey, TValue> tree);
internal ValueCollection(ConcurrentBTreeDictionary <TKey, TValue> btree) : base(btree) { }
public abstract (TValue, bool) Get(TKey key, ConcurrentBTreeDictionary <TKey, TValue> tree);
protected Collection(ConcurrentBTreeDictionary <TKey, TValue> btree) { this.btree = btree; }
public abstract (Node, Node) Put(TKey key, TValue value, bool setting, ConcurrentBTreeDictionary <TKey, TValue> tree);