home *** CD-ROM | disk | FTP | other *** search
Java Source | 1997-03-14 | 17.9 KB | 834 lines |
- // Copyright(c) 1996,1997 ObjectSpace, Inc.
- // Portions Copyright(c) 1995, 1996 Hewlett-Packard Company.
-
- package COM.objectspace.jgl;
-
- /**
- * Tree is a red-black tree structure used as the underlying data structure by all
- * all associative containers.
- * <p>
- * @version 2.0.2
- * @author ObjectSpace, Inc.
- */
-
- final class Tree
- {
- public static final int RED = 1;
- public static final int BLACK = 2;
- TreeNode NIL = new TreeNode();
- int size;
- boolean myInsertAlways;
- boolean myIsMap;
- BinaryPredicate myComparator;
- Container myContainer;
- TreeNode myHeader = new TreeNode(); // Note: myHeader == end, myHeader.left == begin
-
- Tree( boolean isMap, boolean always, Container container )
- {
- this( isMap, always, new HashComparator(), container );
- }
-
- Tree( boolean isMap, boolean always, BinaryPredicate comparator, Container container )
- {
- myContainer = container;
- myIsMap = isMap;
- myInsertAlways = always;
- myComparator = comparator;
- myHeader.color = RED;
- clear();
- }
-
- Tree( Tree tree )
- {
- myContainer = tree.myContainer;
- myIsMap = tree.myIsMap;
- myInsertAlways = tree.myInsertAlways;
- myComparator = tree.myComparator;
- myHeader.color = RED;
- copyTree( tree );
- }
-
- boolean compare( Object first, Object second )
- {
- return myComparator.execute( first, second );
- }
-
- Object key( Object object )
- {
- return myIsMap ? ((Pair) object).first : object;
- }
-
- Object value( Object object )
- {
- if ( myIsMap )
- {
- if ( object == null )
- return null;
-
- return ((Pair) object).second;
- }
- else
- {
- return object;
- }
- }
-
- void copy( Tree tree )
- {
- if ( this != tree )
- {
- clear();
- copyTree( tree );
- }
- }
-
- OrderedSetIterator beginSet()
- {
- return new OrderedSetIterator( this, myHeader.left, (OrderedSet)myContainer );
- }
-
- OrderedSetIterator endSet()
- {
- return new OrderedSetIterator( this, myHeader, (OrderedSet)myContainer );
- }
-
- OrderedMapIterator beginMap( int mode )
- {
- return new OrderedMapIterator( this, myHeader.left, (OrderedMap)myContainer, mode );
- }
-
- OrderedMapIterator endMap( int mode )
- {
- return new OrderedMapIterator( this, myHeader, (OrderedMap)myContainer, mode );
- }
-
- int maxSize()
- {
- return Allocator.maxSize();
- }
-
- TreeNode insert( TreeNode pos, Object value )
- {
- if ( pos == myHeader.left )
- {
- if ( size > 0 && compare( key( value ), key( pos.object ) ) )
- return insert( pos, pos, value );
- else
- return insert( value ).node;
- }
- else if ( pos == myHeader )
- {
- if ( compare( key( myHeader.right.object ), key( value ) ) )
- return insert( NIL, myHeader.right, value );
- else
- return insert( value ).node;
- }
- else
- {
- TreeNode before = decrement( pos, NIL );
-
- if ( compare( key( before.object ), key( value ) ) && compare( key( value ), key( pos.object ) ) )
- if ( before.right == NIL )
- return insert( NIL, before, value );
- else
- return insert( pos, pos, value );
- else
- return insert( value ).node;
- }
- }
-
- void clear()
- {
- myHeader.parent = NIL;
- myHeader.right = myHeader;
- myHeader.left = myHeader;
- size = 0;
- }
-
- Pair remove( Object key )
- {
- Pair range = equalRange( key );
- return remove( (TreeNode)range.first, (TreeNode)range.second, size );
- }
-
- Pair remove( Object key, int maximum )
- {
- Pair range = equalRange( key );
- return remove( (TreeNode)range.first, (TreeNode)range.second, maximum );
- }
-
- Pair remove( TreeNode first, TreeNode last )
- {
- return remove( first, last, size );
- }
-
- Pair remove( TreeNode first, TreeNode last, int maximum )
- {
- if ( maximum <= 0 )
- return new Pair( null, new Integer( 0 ) );
-
- int count = 0;
- Object rvalue = null;
- if ( first == myHeader.left && last == myHeader && size <= maximum )
- {
- count = size;
- rvalue = value( first.object );
- clear();
- }
- else
- {
- TreeNode next;
- while ( maximum > 0 && first != last )
- {
- if ( count == 0 )
- rvalue = value( first.object );
- --maximum;
- ++count;
- next = increment( first, NIL );
- remove( first );
- first = next;
- }
- }
-
- return new Pair( rvalue, new Integer( count ) );
- }
-
- TreeNode find( Object key )
- {
- TreeNode j = lowerBound( key );
- return ( j == myHeader || compare( key, key( j.object ) ) ) ? myHeader : j;
- }
-
- int count( Object key )
- {
- Pair range = equalRange( key );
- return distance( (TreeNode)range.first, (TreeNode)range.second, NIL );
- }
-
- TreeNode lowerBound( Object key )
- {
- return (TreeNode)equalRange( key ).first;
- }
-
- TreeNode upperBound( Object key )
- {
- return (TreeNode)equalRange( key ).second;
- }
-
- Pair equalRange( Object key )
- {
- TreeNode lower = lowerBoundAux( key );
- TreeNode upper = upperBoundAux( key );
-
- // upper == end()
- if ( upper == myHeader )
- return new Pair( lower, upper );
-
- // lower == end()
- if ( lower == myHeader )
- return new Pair( upper, lower );
-
- // advance each node until one reaches either the end of the
- // tree or the other node
- TreeNode b = lower;
- TreeNode e = upper;
- while ( true )
- {
- b = increment( b, NIL );
- e = increment( e, NIL );
- if ( e == myHeader || b == upper )
- return new Pair( lower, upper );
- if ( b == myHeader || lower == e )
- return new Pair( upper, lower );
- }
- }
-
- TreeNode lowerBoundAux( Object key )
- {
- TreeNode y = myHeader;
- TreeNode x = myHeader.parent;
- boolean comp = false;
-
- while ( x != NIL )
- {
- y = x;
- comp = compare( key( x.object ), key );
- x = comp ? x.right : x.left;
- }
-
- return comp ? increment( y, NIL ) : y;
- }
-
- TreeNode upperBoundAux( Object key )
- {
- TreeNode y = myHeader;
- TreeNode x = myHeader.parent;
- boolean comp = true;
-
- while ( x != NIL )
- {
- y = x;
- comp = compare( key, key( x.object ) );
- x = comp ? x.left : x.right;
- }
-
- return comp ? y : increment( y, NIL );
- }
-
- void insert( InputIterator first, InputIterator last )
- {
- InputIterator firstx = (InputIterator) first.clone();
-
- while ( !firstx.equals( last ) )
- insert( firstx.nextElement() );
- }
-
- Tree.InsertResult insertAux( Object value, boolean shortCircut )
- {
- TreeNode y = myHeader;
- TreeNode x = myHeader.parent;
- boolean comp = true;
-
- while ( x != NIL )
- {
- y = x;
- comp = compare( key( value ), key( x.object ) );
- x = comp ? x.left : x.right;
- }
-
- if ( myInsertAlways && shortCircut )
- return new Tree.InsertResult( insert( x, y, value ), true );
-
- TreeNode j = y;
-
- if ( comp )
- if ( j == myHeader.left )
- return new Tree.InsertResult( insert( x, y, value ), true );
- else
- j = decrement( j, NIL );
-
- if ( compare( key( j.object ), key( value ) ) )
- return new Tree.InsertResult( insert( x, y, value ), true );
- else
- return new Tree.InsertResult( j, false );
- }
-
- Tree.InsertResult insert( Object value )
- {
- return insertAux( value, true );
- }
-
- Tree.InsertResult put( Object value )
- {
- return insertAux( value, false );
- }
-
- Object get( Object key )
- {
- TreeNode y = myHeader;
- TreeNode x = myHeader.parent;
- boolean comp = true;
-
- while ( x != NIL )
- {
- y = x;
- comp = compare( key, key( x.object ) );
- x = comp ? x.left : x.right;
- }
-
- TreeNode j = y;
-
- if ( comp )
- if ( j == myHeader.left )
- return null;
- else
- j = decrement( j, NIL );
-
- if ( compare( key( j.object ), key ) )
- return null;
- else
- return ((Pair) j.object).second;
- }
-
- TreeNode insert( TreeNode x, TreeNode y, Object value )
- {
- ++size;
- TreeNode z = new TreeNode( value );
- boolean insertToLeft = ( y == myHeader || x != NIL || compare( key( value ), key( y.object ) ) );
- insert( insertToLeft, x, y, z );
- return z;
- }
-
- static int distance( TreeNode first, TreeNode last, TreeNode NIL )
- {
- int n = 0;
-
- while ( first != last )
- {
- first = increment( first, NIL );
- ++n;
- }
-
- return n;
- }
-
- TreeNode copyTree( TreeNode oldNode, TreeNode parent, TreeNode otherNIL )
- {
- if ( oldNode == otherNIL )
- return NIL;
-
- TreeNode newNode = new TreeNode( oldNode.object );
- newNode.color = oldNode.color;
- newNode.left = copyTree( oldNode.left, newNode, otherNIL );
- newNode.right = copyTree( oldNode.right, newNode, otherNIL );
- newNode.parent = parent;
- return newNode;
- }
-
- void copyTree( Tree tree )
- {
- myHeader.parent = copyTree( tree.myHeader.parent, myHeader, tree.NIL );
- myHeader.left = minimum( myHeader.parent );
- myHeader.right = maximum( myHeader.parent );
- size = tree.size;
- }
-
- Array keys()
- {
- Array array = new Array();
- int i = 0;
- TreeNode node = myHeader.left;
-
- while ( node != myHeader )
- {
- array.add( ((Pair) node.object).first );
- node = increment( node, NIL );
- }
-
- return array;
- }
-
- Array keys( Object value )
- {
- Array array = new Array();
- int i = 0;
- TreeNode node = myHeader.left;
-
- while ( node != myHeader )
- {
- if ( ((Pair) node.object).second.equals( value ) )
- array.add( ((Pair) node.object).first );
-
- node = increment( node, NIL );
- }
-
- return array;
- }
-
-
- Array values( Object key )
- {
- Array array = new Array();
- int i = 0;
- TreeNode node = myHeader.left;
-
- while ( node != myHeader )
- {
- if ( (((Pair) node.object).first).equals( key ) )
- array.add( ((Pair) node.object).second );
-
- node = increment( node, NIL );
- }
-
- return array;
- }
-
- static TreeNode increment( TreeNode node, TreeNode NIL )
- {
- if ( node.right != NIL )
- {
- node = node.right;
-
- while ( node.left != NIL )
- node = node.left;
-
- return node;
- }
- else
- {
- while ( node == node.parent.right )
- node = node.parent;
-
- return node.right == node.parent ? node : node.parent;
- }
- }
-
- static TreeNode decrement( TreeNode node, TreeNode NIL )
- {
- if ( node.color == RED && node.parent.parent == node )
- {
- return node.right;
- }
- else if ( node.left != NIL )
- {
- node = node.left;
-
- while ( node.right != NIL )
- node = node.right;
-
- return node;
- }
- else
- {
- while ( node == node.parent.left )
- node = node.parent;
-
- return node.parent;
- }
- }
-
- TreeNode minimum( TreeNode node )
- {
- if ( node == NIL )
- {
- return myHeader;
- }
- else
- {
- while ( node.left != NIL )
- node = node.left;
-
- return node;
- }
- }
-
- TreeNode maximum( TreeNode node )
- {
- if ( node == NIL )
- {
- return myHeader;
- }
- else
- {
- while ( node.right != NIL )
- node = node.right;
-
- return node;
- }
- }
-
- void rotateLeft( TreeNode x )
- {
- TreeNode y = x.right;
- x.right = y.left;
-
- if ( y.left != NIL )
- y.left.parent = x;
-
- y.parent = x.parent;
-
- if ( x == myHeader.parent )
- myHeader.parent = y;
- else if ( x == x.parent.left )
- x.parent.left = y;
- else
- x.parent.right = y;
-
- y.left = x;
- x.parent = y;
- }
-
- void rotateRight( TreeNode x )
- {
- TreeNode y = x.left;
- x.left = y.right;
-
- if ( y.right != NIL )
- y.right.parent = x;
-
- y.parent = x.parent;
-
- if ( x == myHeader.parent )
- myHeader.parent = y;
- else if ( x == x.parent.right )
- x.parent.right = y;
- else
- x.parent.left = y;
-
- y.right = x;
- x.parent = y;
- }
-
- void insert( boolean insertToLeft, TreeNode x, TreeNode y, TreeNode z )
- {
- if ( insertToLeft )
- {
- y.left = z;
-
- if ( y == myHeader )
- {
- myHeader.parent = z;
- myHeader.right = z;
- }
- else if ( y == myHeader.left )
- {
- myHeader.left = z;
- }
- }
- else
- {
- y.right = z;
-
- if ( y == myHeader.right )
- myHeader.right = z;
- }
-
- z.parent = y;
- z.left = NIL;
- z.right = NIL;
- x = z;
- x.color = RED;
-
- while ( x != myHeader.parent && x.parent.color == RED )
- if ( x.parent == x.parent.parent.left )
- {
- y = x.parent.parent.right;
-
- if ( y.color == RED )
- {
- x.parent.color = BLACK;
- y.color = BLACK;
- x.parent.parent.color = RED;
- x = x.parent.parent;
- }
- else
- {
- if ( x == x.parent.right )
- {
- x = x.parent;
- rotateLeft( x );
- }
-
- x.parent.color = BLACK;
- x.parent.parent.color = RED;
- rotateRight( x.parent.parent );
- }
- }
- else
- {
- y = x.parent.parent.left;
-
- if ( y.color == RED )
- {
- x.parent.color = BLACK;
- y.color = BLACK;
- x.parent.parent.color = RED;
- x = x.parent.parent;
- }
- else
- {
- if ( x == x.parent.left )
- {
- x = x.parent;
- rotateRight( x );
- }
-
- x.parent.color = BLACK;
- x.parent.parent.color = RED;
- rotateLeft( x.parent.parent );
- }
- }
-
- myHeader.parent.color = BLACK;
- }
-
- TreeNode remove( TreeNode z )
- {
- TreeNode y = z;
- TreeNode x;
-
- if ( y.left == NIL )
- {
- x = y.right;
- }
- else if ( y.right == NIL )
- {
- x = y.left;
- }
- else
- {
- y = y.right;
-
- while ( y.left != NIL )
- y = y.left;
-
- x = y.right;
- }
-
- if ( y != z )
- {
- z.left.parent = y;
- y.left = z.left;
-
- if ( y != z.right )
- {
- x.parent = y.parent;
- y.parent.left = x;
- y.right = z.right;
- z.right.parent = y;
- }
- else
- {
- x.parent = y;
- }
-
- if ( myHeader.parent == z )
- myHeader.parent = y;
- else if ( z.parent.left == z )
- z.parent.left = y;
- else
- z.parent.right = y;
-
- y.parent = z.parent;
-
- // Swap color of y and z.
- int tmp = y.color;
- y.color = z.color;
- z.color = tmp;
-
- y = z;
- }
- else
- {
- x.parent = y.parent;
-
- if ( myHeader.parent == z )
- myHeader.parent = x;
- else if ( z.parent.left == z )
- z.parent.left = x;
- else
- z.parent.right = x;
-
- if ( myHeader.left == z )
- if ( z.right == NIL )
- myHeader.left = z.parent;
- else
- myHeader.left = minimum( x );
-
- if ( myHeader.right == z )
- if ( z.left == NIL )
- myHeader.right = z.parent;
- else
- myHeader.right = maximum( x );
- }
-
- if ( y.color != RED )
- {
- while ( x != myHeader.parent && x.color == BLACK )
- if ( x == x.parent.left )
- {
- TreeNode w = x.parent.right;
-
- if ( w.color == RED )
- {
- w.color = BLACK;
- x.parent.color = RED;
- rotateLeft( x.parent );
- w = x.parent.right;
- }
-
- if ( w.left.color == BLACK && w.right.color == BLACK )
- {
- w.color = RED;
- x = x.parent;
- }
- else
- {
- if ( w.right.color == BLACK )
- {
- w.left.color = BLACK;
- w.color = RED;
- rotateRight( w );
- w = x.parent.right;
- }
-
- w.color = x.parent.color;
- x.parent.color = BLACK;
- w.right.color = BLACK;
- rotateLeft( x.parent );
- break;
- }
- }
- else
- {
- TreeNode w = x.parent.left;
-
- if ( w.color == RED )
- {
- w.color = BLACK;
- x.parent.color = RED;
- rotateRight( x.parent );
- w = x.parent.left;
- }
-
- if ( w.right.color == BLACK && w.left.color == BLACK )
- {
- w.color = RED;
- x = x.parent;
- }
- else
- {
- if ( w.left.color == BLACK )
- {
- w.right.color = BLACK;
- w.color = RED;
- rotateLeft( w );
- w = x.parent.left;
- }
-
- w.color = x.parent.color;
- x.parent.color = BLACK;
- w.left.color = BLACK;
- rotateRight( x.parent );
- break;
- }
- }
-
- x.color = BLACK;
- }
-
- --size;
- return y;
- }
-
- final class TreeNode
- {
- public int color = Tree.BLACK;
- public TreeNode parent;
- public TreeNode left;
- public TreeNode right;
- public Object object;
-
- public TreeNode()
- {
- }
-
- public TreeNode( Object value )
- {
- object = value;
- }
- }
-
- final class InsertResult
- {
- public boolean ok;
- public Tree.TreeNode node;
-
- public InsertResult( Tree.TreeNode n, boolean b )
- {
- ok = b;
- node = n;
- }
- }
- }
-