コード例 #1
0
        public RedBlackSTM()
        {
            strIdentifier       = base.ToString() + rand.Next();
            intHashCode         = rand.Next();

            // set up the sentinel node. the sentinel node is the key to a successfull
            // implementation and for understanding the red-black tree properties.
            //sentinelNode        = new RedBlackSTMNode();

            /* Old code*/
            //sentinelNode.Left   = null;
            //sentinelNode.Right  = null;
            /* FIX */
            sentinelNode.Left = sentinelNode;
            sentinelNode.Right = sentinelNode;

            sentinelNode.Parent = null;
            sentinelNode.Color  = RedBlackSTMNode.BLACK;
            rbTree              = sentinelNode;
            lastNodeFound       = sentinelNode;
        }
コード例 #2
0
            ///<summary>
            /// Determine order, walk the tree and push the nodes onto the stack
            ///</summary>
            public RedBlackSTMEnumerator(RedBlackSTMNode tnode, bool keys, bool ascending)
            {
                stack = new Stack();
                this.keys = keys;
                this.ascending = ascending;

                // use depth-first traversal to push nodes into stack
                // the lowest node will be at the top of the stack
                if (ascending)
                {   // find the lowest node
                    while (tnode != RedBlackSTM.sentinelNode)
                    {
                        stack.Push(tnode);
                        tnode = tnode.Left;
                    }
                }
                else
                {
                    // the highest node will be at top of stack
                    while (tnode != RedBlackSTM.sentinelNode)
                    {
                        stack.Push(tnode);
                        tnode = tnode.Right;
                    }
                }
            }
コード例 #3
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(IComparable key, RedBlackSTMNode x)
        {
            // x and y are used as variable names for brevity, in a more formal
            // implementation, you should probably change the names

            RedBlackSTMNode y;

            // maintain red-black tree properties after adding x
            while(x != rbTree && x.Parent.Color == RedBlackSTMNode.RED)
            {
                DebugPrint(key, "RestoreAfterInsert while...", x.Parent);
                // 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 == RedBlackSTMNode.RED)
                    {	// uncle is red; change x's Parent and uncle to black
                        x.Parent.Color = RedBlackSTMNode.BLACK;
                        //Console.WriteLine("x.parent.Color OK, type of Y is: {0}", y.GetType());
                        y.Color = 1;
                        //Console.WriteLine("y.Color is: {0}, RedBlackSTMNode.BLACK is: {1}", y.Color, RedBlackSTMNode.BLACK);

                        y.Color = RedBlackSTMNode.BLACK;
                        //Console.WriteLine("y.Color OK");
                        // grandparent must be red. Why? Every red node that is not
                        // a leaf has only black children
                        x.Parent.Parent.Color	= RedBlackSTMNode.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			= RedBlackSTMNode.BLACK;	// make Parent black
                        x.Parent.Parent.Color	= RedBlackSTMNode.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;
                    //DebugPrint(key, "before if...", y);
                    if((int)key == 221)
                        Console.WriteLine("testing if part 1 {0}", x.Parent.Parent.Left.Left);
                    if (y != null && y.Color == RedBlackSTMNode.RED)
                    {
                        DebugPrint(key, "if...", y);
                        x.Parent.Color = RedBlackSTMNode.BLACK;
                        y.Color					= RedBlackSTMNode.BLACK;
                        x.Parent.Parent.Color	= RedBlackSTMNode.RED;
                        x						= x.Parent.Parent;
                    }
                    else
                    {
                        DebugPrint(key, "else do if...", x);
                        if (x == x.Parent.Left)
                        {
                            x = x.Parent;
                            RotateRight(x);
                        }
                        x.Parent.Color			= RedBlackSTMNode.BLACK;
                        x.Parent.Parent.Color = RedBlackSTMNode.RED;
                        RotateLeft(x.Parent.Parent);
                    }
                }
            }
            rbTree.Color = RedBlackSTMNode.BLACK;		// rbTree should always be black
        }
コード例 #4
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(RedBlackSTMNode x)
        {
            // maintain Red-Black tree balance after deleting node

            RedBlackSTMNode y;

            while(x != rbTree && x.Color == RedBlackSTMNode.BLACK)
            {

                if (x == x.Parent.Left)			// determine sub tree from parent
                {

                    y = x.Parent.Right;			// y is x's sibling
                    if(y.Color == RedBlackSTMNode.RED)
                    {	// x is black, y is red - make both black and rotate
                        y.Color			= RedBlackSTMNode.BLACK;
                        x.Parent.Color	= RedBlackSTMNode.RED;
                        RotateLeft(x.Parent);
                        y = x.Parent.Right;
                    }
                    if(y.Left.Color == RedBlackSTMNode.BLACK &&
                        y.Right.Color == RedBlackSTMNode.BLACK)
                    {	// children are both black
                        y.Color = RedBlackSTMNode.RED;		// change parent to red
                        x = x.Parent;					// move up the tree
                    }
                    else
                    {
                        if(y.Right.Color == RedBlackSTMNode.BLACK)
                        {
                            y.Left.Color	= RedBlackSTMNode.BLACK;
                            y.Color			= RedBlackSTMNode.RED;
                            RotateRight(y);
                            y				= x.Parent.Right;
                        }
                        y.Color			= x.Parent.Color;
                        x.Parent.Color	= RedBlackSTMNode.BLACK;
                        y.Right.Color	= RedBlackSTMNode.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 == RedBlackSTMNode.RED)
                    {
                        y.Color			= RedBlackSTMNode.BLACK;
                        x.Parent.Color	= RedBlackSTMNode.RED;
                        RotateRight (x.Parent);
                        y = x.Parent.Left;
                    }
                    if(y.Right.Color == RedBlackSTMNode.BLACK &&
                        y.Left.Color == RedBlackSTMNode.BLACK)
                    {
                        y.Color = RedBlackSTMNode.RED;
                        x		= x.Parent;
                    }
                    else
                    {
                        if(y.Left.Color == RedBlackSTMNode.BLACK)
                        {
                            y.Right.Color	= RedBlackSTMNode.BLACK;
                            y.Color			= RedBlackSTMNode.RED;
                            RotateLeft(y);
                            y				= x.Parent.Left;
                        }
                        y.Color			= x.Parent.Color;
                        x.Parent.Color	= RedBlackSTMNode.BLACK;
                        y.Left.Color	= RedBlackSTMNode.BLACK;
                        RotateRight(x.Parent);
                        x = rbTree;
                    }
                }
            }
            x.Color = RedBlackSTMNode.BLACK;
        }
コード例 #5
0
        long RedBlackSTMVerify2(RedBlackSTMNode root, long depth)
        {
            long height_left;
            long height_right;

            if (root == RedBlackSTM.sentinelNode)
            {
                return 1;
            }

            height_left = RedBlackSTMVerify2(root.Left, depth + 1);
            height_right = RedBlackSTMVerify2(root.Right, depth + 1);

            if (height_left == 0 || height_right == 0)
            {
                return 0;
            }

            if (height_left != height_right)
            {
                Console.WriteLine("WARNING: Imbalance @depth={0} : {1} {2}\n", depth, height_left, height_right);
            }

            if (root.Left != RedBlackSTM.sentinelNode && root.Left.Parent != root)
            {
                Console.WriteLine("lineage(?)\n");
            }
            if (root.Right != RedBlackSTM.sentinelNode && root.Right.Parent != root)
            {
                Console.WriteLine("lineage(?)\n");
            }

            // Red-Black alternation
            if (root.Color == RedBlackSTMNode.RED)
            {
                if (root.Left != RedBlackSTM.sentinelNode && root.Left.Color != RedBlackSTMNode.BLACK)
                {
                    Console.WriteLine("verify1(?)\n");
                    return 0;
                }
                if (root.Right != RedBlackSTM.sentinelNode && root.Right.Color != RedBlackSTMNode.BLACK)
                {
                    Console.WriteLine("verify2(?)\n");
                    return 0;
                }
                return height_left;
            }

            if (root.Color != RedBlackSTMNode.BLACK)
            {
                Console.WriteLine("verify3(?)\n");
                return 0;
            }

            return (height_left + 1);
        }
コード例 #6
0
 private void DebugPrint(IComparable key, String msg, RedBlackSTMNode node)
 {
     if ((int)key == 221)
     {
         Console.WriteLine(msg);
         //MonoEmbed.PrintVBoxes(node);
     }
 }
コード例 #7
0
        ///<summary>
        /// Delete
        /// Delete a node from the tree and restore red black properties
        ///<summary>
        private void Delete(RedBlackSTMNode 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

            RedBlackSTMNode x = new RedBlackSTMNode();	// work node to contain the replacement node
            RedBlackSTMNode 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;
            }

            if (y.Color == RedBlackSTMNode.BLACK)
            {
                RestoreAfterDelete(x);
            }

            lastNodeFound = sentinelNode;
        }
コード例 #8
0
 private static RedBlackSTMNode NodeSuccessor(RedBlackSTMNode node)
 {
     if (node == RedBlackSTM.sentinelNode)
         return RedBlackSTM.sentinelNode;
     else if (node.Right != RedBlackSTM.sentinelNode)
     {
         RedBlackSTMNode p = node.Right;
         while (p.Left != RedBlackSTM.sentinelNode)
         {
             p = p.Left;
         }
         return p;
     }
     else
     {
         RedBlackSTMNode p = node.Parent;
         RedBlackSTMNode ch = node;
         while (p != null && ch == p.Right)
         {
             ch = p;
             p = p.Parent;
         }
         return p;
     }
 }
コード例 #9
0
 static RedBlackSTM()
 {
     sentinelNode = new RedBlackSTMNode();
 }
コード例 #10
0
        ///<summary>
        /// RotateRight
        /// Rebalance the tree by rotating the nodes to the right
        ///</summary>
        public void RotateRight(RedBlackSTMNode 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).

            RedBlackSTMNode 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;
        }
コード例 #11
0
        ///<summary>
        /// GetMinKey
        /// Returns the minimum key value
        ///<summary>
        public IComparable GetMinKey()
        {
            RedBlackSTMNode treeNode = rbTree;

            if(treeNode == null || treeNode == sentinelNode)
                throw(new RedBlackSTMException("RedBlackSTM tree is empty"));

            // traverse to the extreme left to find the smallest key
            while(treeNode.Left != sentinelNode)
                treeNode = treeNode.Left;

            lastNodeFound = treeNode;

            return treeNode.Key;
        }
コード例 #12
0
        ///<summary>
        /// GetData
        /// Gets the data object associated with the specified key
        ///<summary>
        public object GetData(IComparable key)
        {
            int result;

            RedBlackSTMNode treeNode = rbTree;     // begin at root

            // traverse tree until node is found
            while(treeNode != sentinelNode)
            {
                result = key.CompareTo(treeNode.Key);
                if(result == 0)
                {
                    lastNodeFound = treeNode;
                    //MonoEmbed.PrintVBoxes(treeNode);
                    return treeNode.Data;
                }
                if(result < 0)
                    treeNode = treeNode.Left;
                else
                    treeNode = treeNode.Right;
            }
            return null;
            //throw(new RedBlackSTMException("RedBlackSTMNode key was not found"));
        }
コード例 #13
0
 ///<summary>
 /// Clear
 /// Empties or clears the tree
 ///<summary>
 public void Clear()
 {
     rbTree      = sentinelNode;
     intCount    = 0;
 }
コード例 #14
0
        ///<summary>
        /// Add
        /// args: ByVal key As IComparable, 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 bool Add(IComparable key, object data)
        {
            //if ((int)key == 219 || (int)key == 220)
            //    MonoEmbed.BreakpointTest();
            if (key == null || data == null)
                throw(new RedBlackSTMException("RedBlackSTMNode key and data must not be null"));

            // traverse tree - find where node belongs
            int result			=	0;
            // create new node
            RedBlackSTMNode node	=	new RedBlackSTMNode();
            RedBlackSTMNode temp	=	rbTree;				// grab the rbTree node of the tree

            while(temp != sentinelNode)
            {	// find Parent
                node.Parent	= temp;
                result		=  key.CompareTo(temp.Key);
                if (result == 0)
                    return false;
                    //throw(new RedBlackSTMException("A Node with the same key already exists"));
                if(result > 0)
                    temp = temp.Right;
                else
                    temp = temp.Left;
            }

            // setup node
            node.Key			=	key;
            node.Data			=	data;
            node.Left           =   sentinelNode;
            node.Right          =   sentinelNode;

            // insert node into tree starting at parent's location
            if(node.Parent != null)
            {
                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(key, node);           // restore red-black properities

            lastNodeFound = node;

            intCount = intCount + 1;

            return true;
        }