Exemple #1
0
        ///<summary>
        /// GetTagData
        /// Gets the data associated with the specified tag
        ///<summary>
        public void GetTagData(T tag, Hashtable finalResult)
        {
            int result;

            RedBlackNode <T>      treeNode = rbTree; // begin at root
            IDictionaryEnumerator en       = this.GetEnumerator();
            bool isStringValue             = false;

            if (tag is string)
            {
                isStringValue = true;
            }

            while (treeNode != _sentinelNode)
            {
                if (isStringValue && treeNode.Key is string)
                {
                    //result = string.Compare(treeNode.Key , key , true);
                    result = treeNode.Key.ToString().ToLower().CompareTo(tag.ToString().ToLower());
                }
                else
                {
                    result = treeNode.Key.CompareTo(tag);
                }
                if (result == 0)
                {
                    lastNodeFound = treeNode;
                    foreach (object key in treeNode.Data.Keys)
                    {
                        finalResult[key] = null;
                    }

                    return;
                }
                if (result > 0) //treenode is Greater then the one we are looking. Move to Left branch
                {
                    treeNode = treeNode.Left;
                }
                else
                {
                    treeNode = treeNode.Right; //treenode is Less then the one we are looking. Move to Right branch.
                }
            }
        }
Exemple #2
0
        ///<summary>
        /// RotateRight
        /// Rebalance the tree by rotating the nodes to the right
        ///</summary>
        public void RotateRight(RedBlackNode <T> x)
        {
            // pushing node x down and to the Right to balance the tree. x's Left child (y)
            // replaces x (since x < y), and y's Right child becomes x's Left child
            // (since it's < x but > y).

            RedBlackNode <T> y = x.Left;                 // get x's Left node, this becomes y

            // set x's Right link
            x.Left = y.Right;                                   // y's Right child becomes x's Left child

            // modify parents
            if (y.Right != _sentinelNode)
            {
                y.Right.Parent = x;                             // sets y's Right Parent to x
            }
            if (y != _sentinelNode)
            {
                y.Parent = x.Parent; // set y's Parent to x's Parent
            }
            if (x.Parent != null)    // null=rbTree, could also have used rbTree
            {                        // determine which side of it's Parent x was on
                if (x == x.Parent.Right)
                {
                    x.Parent.Right = y;                 // set Right Parent to y
                }
                else
                {
                    x.Parent.Left = y;                  // set Left Parent to y
                }
            }
            else
            {
                rbTree = y;                                             // at rbTree, set it to y
            }
            // link x and y
            y.Right = x;                                        // put x on y's Right
            if (x != _sentinelNode)                             // set y as x's Parent
            {
                x.Parent = y;
            }
        }
Exemple #3
0
        ///<summary>
        /// GetData
        /// Gets the data object associated with the specified key
        ///<summary>
        public object GetData(T key, COMPARE compareType)
        {
            int                   result;
            ArrayList             keyList  = new ArrayList();
            RedBlackNode <T>      treeNode = rbTree; // begin at root
            IDictionaryEnumerator en       = this.GetEnumerator();
            string                pattern;
            WildcardEnabledRegex  regex;
            HashVector            finalTable    = null;
            HashVector            skippedKeys   = null;
            bool                  isStringValue = false;

            if (key is string)
            {
                isStringValue = true;
            }

            switch (compareType)
            {
            case COMPARE.EQ:
                // traverse tree until node is found
                while (treeNode != _sentinelNode)
                {
                    if (isStringValue && treeNode.Key is string)
                    {
                        //result = string.Compare(treeNode.Key , key , true);
                        result = treeNode.Key.ToString().ToLower().CompareTo(key.ToString().ToLower());
                    }
                    else
                    {
                        result = treeNode.Key.CompareTo(key);
                    }
                    if (result == 0)
                    {
                        lastNodeFound = treeNode;
                        keyList.AddRange(treeNode.Data.Keys);
                        //return treeNode.Data;
                        return(keyList);
                    }
                    if (result > 0)     //treenode is Greater then the one we are looking. Move to Left branch
                    {
                        treeNode = treeNode.Left;
                    }
                    else
                    {
                        treeNode = treeNode.Right;     //treenode is Less then the one we are looking. Move to Right branch.
                    }
                }
                break;

            case COMPARE.NE:
                // traverse tree until node is found
                finalTable = new HashVector();

                while (en.MoveNext())
                {
                    if (isStringValue && en.Key is string)
                    {
                        //result = string.Compare(((IComparable)en.Key) , key , true);
                        result = en.Key.ToString().ToLower().CompareTo(key.ToString().ToLower());
                    }
                    else
                    {
                        result = ((IComparable)en.Key).CompareTo(key);
                    }

                    if (result != 0)
                    {
                        HashVector            tmp = en.Value as HashVector;
                        IDictionaryEnumerator ide = tmp.GetEnumerator();

                        while (ide.MoveNext())
                        {
                            finalTable[ide.Key] = ide.Value;
                        }
                        //keyList.AddRange(((Hashtable)en.Value).Keys);
                    }
                }

                return(new ArrayList(finalTable.Keys));   //keyList;

                break;

            case COMPARE.GT:
                finalTable = new HashVector();
                while (en.MoveNext())
                {
                    if (isStringValue && en.Key is string)
                    {
                        //result = string.Compare(((IComparable)en.Key) , key , true);
                        result = en.Key.ToString().ToLower().CompareTo(key.ToString().ToLower());
                    }
                    else
                    {
                        result = ((IComparable)en.Key).CompareTo(key);
                    }

                    if (result > 0)
                    {
                        HashVector            tmp = en.Value as HashVector;
                        IDictionaryEnumerator ide = tmp.GetEnumerator();

                        while (ide.MoveNext())
                        {
                            finalTable[ide.Key] = ide.Value;
                        }

                        //keyList.AddRange(((Hashtable)en.Value).Keys);
                    }
                }

                return(new ArrayList(finalTable.Keys));   //keyList;

                break;

            case COMPARE.LT:
                finalTable = new HashVector();
                while (en.MoveNext())
                {
                    if (isStringValue && en.Key is string)
                    {
                        //result = string.Compare(((IComparable)en.Key) , key , true);
                        result = en.Key.ToString().ToLower().CompareTo(key.ToString().ToLower());
                    }
                    else
                    {
                        result = ((IComparable)en.Key).CompareTo(key);
                    }

                    if (result < 0)
                    {
                        HashVector            tmp = en.Value as HashVector;
                        IDictionaryEnumerator ide = tmp.GetEnumerator();
                        while (ide.MoveNext())
                        {
                            finalTable[ide.Key] = ide.Value;
                        }

                        //keyList.AddRange(((Hashtable)en.Value).Keys);
                    }
                    //else break;
                }

                return(new ArrayList(finalTable.Keys));   //keyList;

                break;

            case COMPARE.GTEQ:
                finalTable = new HashVector();

                while (en.MoveNext())
                {
                    if (isStringValue && en.Key is string)
                    {
                        //result = string.Compare(((IComparable)en.Key) , key , true);
                        result = en.Key.ToString().ToLower().CompareTo(key.ToString().ToLower());
                    }
                    else
                    {
                        result = ((IComparable)en.Key).CompareTo(key);
                    }

                    if (result >= 0)
                    {
                        HashVector            tmp = en.Value as HashVector;
                        IDictionaryEnumerator ide = tmp.GetEnumerator();
                        while (ide.MoveNext())
                        {
                            finalTable[ide.Key] = ide.Value;
                        }

                        //keyList.AddRange(((Hashtable)en.Value).Keys);
                    }
                }

                return(new ArrayList(finalTable.Keys));   //keyList;

                break;

            case COMPARE.LTEQ:
                finalTable = new HashVector();
                while (en.MoveNext())
                {
                    if (isStringValue && en.Key is string)
                    {
                        //result = string.Compare(((IComparable)en.Key) , key , true);
                        result = en.Key.ToString().ToLower().CompareTo(key.ToString().ToLower());
                    }
                    else
                    {
                        result = ((IComparable)en.Key).CompareTo(key);
                    }

                    if (result <= 0)
                    {
                        HashVector            tmp = en.Value as HashVector;
                        IDictionaryEnumerator ide = tmp.GetEnumerator();
                        while (ide.MoveNext())
                        {
                            finalTable[ide.Key] = ide.Value;
                        }

                        //keyList.AddRange(((Hashtable)en.Value).Keys);
                    }
                    else
                    {
                        break;
                    }
                }

                return(new ArrayList(finalTable.Keys));   //keyList;

                break;

            case COMPARE.REGEX:
                finalTable = new HashVector();
                pattern    = key as string;
                regex      = new WildcardEnabledRegex(pattern);
                while (en.MoveNext())
                {
                    if (en.Key is string)
                    {
                        if (regex.IsMatch((string)en.Key.ToString().ToLower()))
                        {
                            HashVector            tmp = en.Value as HashVector;
                            IDictionaryEnumerator ide = tmp.GetEnumerator();

                            while (ide.MoveNext())
                            {
                                finalTable[ide.Key] = ide.Value;
                            }
                        }
                        //keyList.AddRange(((Hashtable)en.Value).Keys);
                    }
                }

                return(new ArrayList(finalTable.Keys));   //keyList;

                break;

            case COMPARE.IREGEX:
                finalTable  = new HashVector();
                pattern     = key as string;
                regex       = new WildcardEnabledRegex(pattern);
                skippedKeys = new HashVector();
                while (en.MoveNext())
                {
                    if (en.Key is string)
                    {
                        if (regex.IsMatch((string)en.Key.ToString().ToLower()))
                        {
                            HashVector            tmp = en.Value as HashVector;
                            IDictionaryEnumerator ide = tmp.GetEnumerator();
                            while (ide.MoveNext())
                            {
                                skippedKeys[ide.Key] = ide.Value;
                            }
                        }
                        else
                        {
                            HashVector            tmp = en.Value as HashVector;
                            IDictionaryEnumerator ide = tmp.GetEnumerator();
                            while (ide.MoveNext())
                            {
                                finalTable[ide.Key] = ide.Value;
                            }
                        }
                    }
                }

                ArrayList list = new ArrayList(finalTable.Keys);    // keyList;

                for (int idx = list.Count - 1; idx >= 0; idx--)
                {
                    if (skippedKeys.ContainsKey(list[idx]))
                    {
                        list.RemoveAt(idx);
                    }
                }

                return(list);

                break;
            }

            return(keyList);
        }
Exemple #4
0
        ///<summary>
        /// RestoreAfterInsert
        /// Additions to red-black trees usually destroy the red-black
        /// properties. Examine the tree and restore. Rotations are normally
        /// required to restore it
        ///</summary>
        private void RestoreAfterInsert(RedBlackNode <T> x)
        {
            // x and y are used as variable names for brevity, in a more formal
            // implementation, you should probably change the names

            RedBlackNode <T> y;

            // maintain red-black tree properties after adding x
            while (x != rbTree && x.Parent.Color == RedBlackNode <T> .RED)
            {
                // Parent node is .Colored red;
                if (x.Parent == x.Parent.Parent.Left) // determine traversal path
                {                                     // is it on the Left or Right subtree?
                    y = x.Parent.Parent.Right;        // get uncle
                    if (y != null && y.Color == RedBlackNode <T> .RED)
                    {                                 // uncle is red; change x's Parent and uncle to black
                        x.Parent.Color = RedBlackNode <T> .BLACK;
                        y.Color        = RedBlackNode <T> .BLACK;
                        // grandparent must be red. Why? Every red node that is not
                        // a leaf has only black children
                        x.Parent.Parent.Color = RedBlackNode <T> .RED;
                        x = x.Parent.Parent;    // continue loop with grandparent
                    }
                    else
                    {
                        // uncle is black; determine if x is greater than Parent
                        if (x == x.Parent.Right)
                        {       // yes, x is greater than Parent; rotate Left
                            // make x a Left child
                            x = x.Parent;
                            RotateLeft(x);
                        }
                        // no, x is less than Parent
                        x.Parent.Color        = RedBlackNode <T> .BLACK; // make Parent black
                        x.Parent.Parent.Color = RedBlackNode <T> .RED;   // make grandparent black
                        RotateRight(x.Parent.Parent);                    // rotate right
                    }
                }
                else
                {       // x's Parent is on the Right subtree
                    // this code is the same as above with "Left" and "Right" swapped
                    y = x.Parent.Parent.Left;
                    if (y != null && y.Color == RedBlackNode <T> .RED)
                    {
                        x.Parent.Color        = RedBlackNode <T> .BLACK;
                        y.Color               = RedBlackNode <T> .BLACK;
                        x.Parent.Parent.Color = RedBlackNode <T> .RED;
                        x = x.Parent.Parent;
                    }
                    else
                    {
                        if (x == x.Parent.Left)
                        {
                            x = x.Parent;
                            RotateRight(x);
                        }
                        x.Parent.Color        = RedBlackNode <T> .BLACK;
                        x.Parent.Parent.Color = RedBlackNode <T> .RED;
                        RotateLeft(x.Parent.Parent);
                    }
                }
            }
            rbTree.Color = RedBlackNode <T> .BLACK;               // rbTree should always be black
        }
Exemple #5
0
        ///<summary>
        /// RestoreAfterDelete
        /// Deletions from red-black trees may destroy the red-black
        /// properties. Examine the tree and restore. Rotations are normally
        /// required to restore it
        ///</summary>
        private void RestoreAfterDelete(RedBlackNode <T> x)
        {
            // maintain Red-Black tree balance after deleting node

            RedBlackNode <T> y;

            while (x != rbTree && x.Color == RedBlackNode <T> .BLACK)
            {
                if (x == x.Parent.Left) // determine sub tree from parent
                {
                    y = x.Parent.Right; // y is x's sibling
                    if (y.Color == RedBlackNode <T> .RED)
                    {                   // x is black, y is red - make both black and rotate
                        y.Color        = RedBlackNode <T> .BLACK;
                        x.Parent.Color = RedBlackNode <T> .RED;
                        RotateLeft(x.Parent);
                        y = x.Parent.Right;
                    }
                    if (y.Left.Color == RedBlackNode <T> .BLACK &&
                        y.Right.Color == RedBlackNode <T> .BLACK)
                    {                                    // children are both black
                        y.Color = RedBlackNode <T> .RED; // change parent to red
                        x       = x.Parent;              // move up the tree
                    }
                    else
                    {
                        if (y.Right.Color == RedBlackNode <T> .BLACK)
                        {
                            y.Left.Color = RedBlackNode <T> .BLACK;
                            y.Color      = RedBlackNode <T> .RED;
                            RotateRight(y);
                            y = x.Parent.Right;
                        }
                        y.Color        = x.Parent.Color;
                        x.Parent.Color = RedBlackNode <T> .BLACK;
                        y.Right.Color  = RedBlackNode <T> .BLACK;
                        RotateLeft(x.Parent);
                        x = rbTree;
                    }
                }
                else
                {       // right subtree - same as code above with right and left swapped
                    y = x.Parent.Left;
                    if (y.Color == RedBlackNode <T> .RED)
                    {
                        y.Color        = RedBlackNode <T> .BLACK;
                        x.Parent.Color = RedBlackNode <T> .RED;
                        RotateRight(x.Parent);
                        y = x.Parent.Left;
                    }
                    if (y.Right.Color == RedBlackNode <T> .BLACK &&
                        y.Left.Color == RedBlackNode <T> .BLACK)
                    {
                        y.Color = RedBlackNode <T> .RED;
                        x       = x.Parent;
                    }
                    else
                    {
                        if (y.Left.Color == RedBlackNode <T> .BLACK)
                        {
                            y.Right.Color = RedBlackNode <T> .BLACK;
                            y.Color       = RedBlackNode <T> .RED;
                            RotateLeft(y);
                            y = x.Parent.Left;
                        }
                        y.Color        = x.Parent.Color;
                        x.Parent.Color = RedBlackNode <T> .BLACK;
                        y.Left.Color   = RedBlackNode <T> .BLACK;
                        RotateRight(x.Parent);
                        x = rbTree;
                    }
                }
            }
            x.Color = RedBlackNode <T> .BLACK;
        }
Exemple #6
0
        ///<summary>
        /// Delete
        /// Delete a node from the tree and restore red black properties
        ///<summary>
        private void Delete(RedBlackNode <T> z)
        {
            // A node to be deleted will be:
            //		1. a leaf with no children
            //		2. have one child
            //		3. have two children
            // If the deleted node is red, the red black properties still hold.
            // If the deleted node is black, the tree needs rebalancing

            RedBlackNode <T> x = new RedBlackNode <T>();  // work node to contain the replacement node
            RedBlackNode <T> y;                           // work node

            // find the replacement node (the successor to x) - the node one with
            // at *most* one child.
            if (z.Left == _sentinelNode || z.Right == _sentinelNode)
            {
                y = z;                                          // node has sentinel as a child
            }
            else
            {
                // z has two children, find replacement node which will
                // be the leftmost node greater than z
                y = z.Right;                            // traverse right subtree
                while (y.Left != _sentinelNode)         // to find next node in sequence
                {
                    y = y.Left;
                }
            }

            // at this point, y contains the replacement node. it's content will be copied
            // to the valules in the node to be deleted

            // x (y's only child) is the node that will be linked to y's old parent.
            if (y.Left != _sentinelNode)
            {
                x = y.Left;
            }
            else
            {
                x = y.Right;
            }

            // replace x's parent with y's parent and
            // link x to proper subtree in parent
            // this removes y from the chain
            x.Parent = y.Parent;
            if (y.Parent != null)
            {
                if (y == y.Parent.Left)
                {
                    y.Parent.Left = x;
                }
                else
                {
                    y.Parent.Right = x;
                }
            }
            else
            {
                rbTree = x;                     // make x the root node
            }
            // copy the values from y (the replacement node) to the node being deleted.
            // note: this effectively deletes the node.
            if (y != z)
            {
                z.Key                         = y.Key;
                z.Data                        = y.Data; //un-commented by [] 12 Jun,08
                z.RBNodeReference             = y.RBNodeReference;
                z.RBNodeReference.RBReference = z;
            }

            if (y.Color == RedBlackNode <T> .BLACK)
            {
                RestoreAfterDelete(x);
            }

            lastNodeFound = _sentinelNode;
        }
Exemple #7
0
        ///<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 RedBlackNodeReference(RedBlackNode <T> rbNode)
 {
     _rbNode = rbNode;
 }