// insertNode adds the given key and value into the node private rbNode insertNode(rbNode node, RbKey key, object value) { if (node == null) { this.count++; return(newRbNode(key, value)); } var cmp = key.ComparedTo(node.key); switch (cmp) { case KeyComparison.KeyIsLess: node.left = this.insertNode(node.left, key, value); break; case KeyComparison.KeyIsGreater: node.right = this.insertNode(node.right, key, value); break; default: if (this.onInsert == null) { node.value = value; } else { node.value = this.onInsert(key, value); } break; } return(balance(node)); }
// ceilig returns the smallest key node in the subtree rooted at x greater than or equal to the given key private rbNode ceiling(rbNode node, RbKey key) { if (node == null) { return(null); } var cmp = key.ComparedTo(node.key); switch (cmp) { case KeyComparison.KeysAreEqual: return(node); case KeyComparison.KeyIsGreater: return(ceiling(node.right, key)); default: var cn = ceiling(node.left, key); if (cn != null) { return(cn); } return(node); } }
// floor returns the largest key node in the subtree rooted at x less than or equal to the given key private rbNode floor(rbNode node, RbKey key) { if (node == null) { return(null); } var cmp = key.ComparedTo(node.key); switch (cmp) { case KeyComparison.KeysAreEqual: return(node); case KeyComparison.KeyIsLess: return(floor(node.left, key)); default: var fn = floor(node.right, key); if (fn != null) { return(fn); } return(node); } }
public void LessOrEqual(RbKey key, out int count, out error err) { count = 0; err = null; if (key == null) { err = ErrorDef.ArgumentNilError("key"); return; } RbTree tree; this.checkStateAndGetTree(out tree, out err); if (err != null) { return; } try { this.walkLessOrEqual(tree.root, key); count = this.CurrentCount(); } finally { Interlocked.CompareExchange(ref this.state, (long)IterationState.iteratorReady, (long)IterationState.iteratorWalking); } }
public void walkGreaterThan(rbNode node, RbKey key) { if (node == null || !this.inWalk()) { return; } if (node.key.ComparedTo(key) == KeyComparison.KeyIsGreater) { if (node.left != null) { this.walkGreaterThan(node.left, key); if (!this.inWalk()) { return; } } this.incrementCount(); this.callback(this, node.key, node.value); if (!this.inWalk()) { return; } } if (node.right != null) { this.walkGreaterThan(node.right, key); } }
public void walkLessOrEqual(rbNode node, RbKey key) { if (node == null || !this.inWalk()) { return; } if (node.left != null) { this.walkLessOrEqual(node.left, key); if (!this.inWalk()) { return; } } var cmp = node.key.ComparedTo(key); if (cmp == KeyComparison.KeyIsLess || cmp == KeyComparison.KeysAreEqual) { this.incrementCount(); this.callback(this, node.key, node.value); if (!this.inWalk()) { return; } if (node.right != null) { this.walkLessOrEqual(node.right, key); } } }
// Insert inserts the given key and value into the tree public void Insert(RbKey key, object value) { if (key != null) { this.root = this.insertNode(this.root, key, value); this.root.color = black; } }
// Delete deletes the given key from the tree public void Delete(RbKey key) { this.root = this.deleteNode(this.root, key); if (this.root != null) { this.root.color = black; } }
// newRbNode creates a new rbNode and returns its address private rbNode newRbNode(RbKey key, object value) { var result = new rbNode { key = key, value = value, color = red, }; return(result); }
public void Between(RbKey loKey, RbKey hiKey, out int count, out error err) { count = 0; err = null; if (loKey == null) { err = ErrorDef.ArgumentNilError("loKey"); return; } if (hiKey == null) { err = ErrorDef.ArgumentNilError("hiKey"); return; } RbTree tree; this.checkStateAndGetTree(out tree, out err); if (err != null) { return; } try { var cmp = loKey.ComparedTo(hiKey); switch (cmp) { case KeyComparison.KeysAreEqual: var node = tree.find(loKey); if (node != null) { count = 1; this.callback(this, node.key, node.value); return; } return; case KeyComparison.KeyIsGreater: var tmp = loKey; loKey = hiKey; hiKey = tmp; break; } this.walkBetween(tree.root, loKey, hiKey); count = this.CurrentCount(); } finally { Interlocked.CompareExchange(ref this.state, (long)IterationState.iteratorReady, (long)IterationState.iteratorWalking); } }
// Max returns the largest key in the this. public void Max(out RbKey key, out object value) { key = null; value = null; if (this.root != null) { var result = max(this.root); key = result.key; value = result.value; } }
public KeyComparison ComparedTo(RbKey key) { var diff = this.value - ((IntKey)key).value; if (diff > 0) { return(KeyComparison.KeyIsGreater); } if (diff < 0) { return(KeyComparison.KeyIsLess); } return(KeyComparison.KeysAreEqual); }
// Ceiling returns the smallest key in the tree greater than or equal to key public void Ceiling(RbKey key, out RbKey outKey, out object value) { outKey = null; value = null; if (key != null && this.root != null) { var node = ceiling(this.root, key); if (node != null) { outKey = node.key; value = node.value; } } }
// Get returns the stored value if (key found and 'true', // otherwise returns 'false' with second return param if (key not found public void Get(RbKey key, out object value, out bool success) { value = null; success = false; if (key != null && this.root != null) { var node = this.find(key); if (node != null) { value = node.value; success = true; } } }
public void walkBetween(rbNode node, RbKey loKey, RbKey hiKey) { if (node == null || !this.inWalk()) { return; } var cmpLo = (int)loKey.ComparedTo(node.key); if (cmpLo < RbTree.zeroOrEqual) { if (node.left != null) { this.walkBetween(node.left, loKey, hiKey); if (!this.inWalk()) { return; } } } var cmpHi = (int)hiKey.ComparedTo(node.key); if (cmpLo <= RbTree.zeroOrEqual && cmpHi >= RbTree.zeroOrEqual) { this.incrementCount(); this.callback(this, node.key, node.value); if (!this.inWalk()) { return; } } if (cmpHi > RbTree.zeroOrEqual) { if (node.right != null) { this.walkBetween(node.right, loKey, hiKey); } } }
// find returns the node if (key found, otherwise returns null internal rbNode find(RbKey key) { for (var node = this.root; node != null;) { var cmp = key.ComparedTo(node.key); switch (cmp) { case KeyComparison.KeyIsLess: node = node.left; break; case KeyComparison.KeyIsGreater: node = node.right; break; default: return(node); } } return(null); }
public static void nilIterationCallback(RbIterator iterator, RbKey key, object value) { }
// deleteNode deletes the given key from the node private rbNode deleteNode(rbNode node, RbKey key) { if (node == null) { return(null); } var cmp = key.ComparedTo(node.key); if (cmp == KeyComparison.KeyIsLess) { if (isBlack(node.left) && !isRed(node.left.left)) { node = moveRedLeft(node); } node.left = this.deleteNode(node.left, key); } else { if (cmp == KeyComparison.KeysAreEqual && this.onDelete != null) { var value = this.onInsert(key, node.value); if (value != null) { node.value = value; return(node); } } if (isRed(node.left)) { node = rotateRight(node); } if (isBlack(node.right) && !isRed(node.right.left)) { node = moveRedRight(node); } if (key.ComparedTo(node.key) != KeyComparison.KeysAreEqual) { node.right = this.deleteNode(node.right, key); } else { if (node.right == null) { return(null); } var rm = min(node.right); node.key = rm.key; node.value = rm.value; node.right = deleteMin(node.right); rm.left = null; rm.right = null; this.count--; } } return(balance(node)); }