///<summary> /// Remove /// removes the key and data object (delete) ///<summary> public bool Remove(object cacheKey, object node) { bool isNodeRemoved = false; RedBlackNodeReference <T> keyNodeReference = (RedBlackNodeReference <T>)node; RedBlackNode <T> keyNode = keyNodeReference.RBReference; try { //_nTrace.error("RedBlack.Remove() node-count : ", node.Data.Count.ToString()); if (cacheKey != null && keyNode.Data.Count > 1) { if (keyNode.Data.Contains(cacheKey)) { long initialSize = keyNode.IndexInMemorySize; keyNode.Data.Remove(cacheKey); //_nTrace.error(cacheKey + " removed from the tree"); isNodeRemoved = false; _rbNodeDataSize += keyNode.IndexInMemorySize - initialSize; } } else { //node.Data.Clear(); if (_typeSize != AttributeTypeSize.Variable) { _rbNodeKeySize -= MemoryUtil.GetTypeSize(_typeSize); } else { _rbNodeKeySize -= MemoryUtil.GetStringSize(keyNode.Key); } _rbNodeDataSize -= keyNode.IndexInMemorySize; Delete(keyNode); //_nTrace.error("key is " + cacheKey + " and node is deleted"); isNodeRemoved = true; } } catch (Exception) { //Trace.error("RedBlack.Remove()", e.ToString()); throw; } if (isNodeRemoved) { intCount = intCount - 1; } return(isNodeRemoved); }
///<summary> /// Add /// args: ByVal key As T, ByVal data As Object /// key is object that implements IComparable interface /// performance tip: change to use use int type (such as the hashcode) ///</summary> public object Add(T key, object data) { bool collision = false; RedBlackNodeReference <T> keyNodeRfrnce = null; try { if (key == null || data == null) { throw (new RedBlackException("RedBlackNode key and data must not be null")); } // traverse tree - find where node belongs int result = 0; // create new node RedBlackNode <T> node = new RedBlackNode <T>(); RedBlackNode <T> temp = rbTree; // grab the rbTree node of the tree while (temp != _sentinelNode) { // find Parent node.Parent = temp; if (key is string) { result = key.ToString().ToLower().CompareTo(temp.Key.ToString().ToLower()); } else { result = key.CompareTo(temp.Key); } if (result == 0) { collision = true; //data with the same key. break; } //throw(new RedBlackException("A Node with the same key already exists")); if (result > 0) { temp = temp.Right; collision = false; } else { temp = temp.Left; collision = false; } } if (collision) { //temp.Data.Add(data, null); long prevSize = temp.IndexInMemorySize; temp.Insert(data, null);//.Data[data] = null; keyNodeRfrnce = temp.RBNodeReference; _rbNodeDataSize += temp.IndexInMemorySize - prevSize; } else { // setup node //node = new RedBlackNode(); node.Key = key; node.Insert(data, null);//.Data.Add(data, null); node.Left = _sentinelNode; node.Right = _sentinelNode; if (_typeSize != AttributeTypeSize.Variable) { _rbNodeKeySize += MemoryUtil.GetTypeSize(_typeSize); } else { _rbNodeKeySize += MemoryUtil.GetStringSize(key); } _rbNodeDataSize += node.IndexInMemorySize; // insert node into tree starting at parent's location if (node.Parent != null) { if (key is string) { result = node.Key.ToString().ToLower().CompareTo(node.Parent.Key.ToString().ToLower()); } else { result = node.Key.CompareTo(node.Parent.Key); } if (result > 0) { node.Parent.Right = node; } else { node.Parent.Left = node; } } else { rbTree = node; // first node added } RestoreAfterInsert(node); // restore red-black properities lastNodeFound = node; intCount = intCount + 1; keyNodeRfrnce = node.RBNodeReference; } } catch (Exception ex) { //_nTrace.error("RedBlack.Add()->", "index-key : " + key + " cache-key : " + data); //throw new Exception(ex.ToString() + "index-key : " + key + " cache-key : " + data); } return(keyNodeRfrnce); }
/// <summary> /// Default constructor. /// </summary> public RedBlackNode() { Color = RED; Data = new HashVector(); _rbReference = new RedBlackNodeReference <T>(this); }