/* * JVSTM: a Java library for Software Transactional Memory * Copyright (C) 2005 INESC-ID Software Engineering Group * http://www.esw.inesc-id.pt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Author's contact: * INESC-ID Software Engineering Group * Rua Alves Redol 9 * 1000 - 029 Lisboa * Portugal */ package jvstm.util; import java.util.Iterator; import java.util.NoSuchElementException; public class RedBlackTree<E extends Comparable<? super E>> implements Iterable<E> { private static final boolean RED = true; private static final boolean BLACK = false; public static final RedBlackTree EMPTY = new RedBlackTree(BLACK, null, null, null); private boolean color; private E elem; private RedBlackTree<E> left; private RedBlackTree<E> right; private RedBlackTree(boolean color, E elem, RedBlackTree<E> left, RedBlackTree<E> right) { this.color = color; this.elem = elem; this.left = left; this.right = right; } public int size() { if (this == EMPTY) { return 0; } else { return left.size() + right.size() + 1; } } public RedBlackTree<E> put(E elem) { RedBlackTree<E> result = buildTree(elem); result.color = BLACK; return result; } private RedBlackTree<E> buildTree(E elem) { if (this == EMPTY) { return new RedBlackTree<E>(RED, elem, EMPTY, EMPTY); } else { int cmp = elem.compareTo(this.elem); if (cmp < 0) { return lbalance(this.color, this.elem, this.left.buildTree(elem), this.right); } else if (cmp > 0) { return rbalance(this.color, this.elem, this.left, this.right.buildTree(elem)); } else { return new RedBlackTree<E>(this.color, elem, this.left, this.right); } } } private RedBlackTree<E> lbalance(boolean color, E elem, RedBlackTree<E> left, RedBlackTree<E> right) { if (color == BLACK) { if ((left != EMPTY) && (left.color == RED)) { if (left.left.color == RED) { return new RedBlackTree<E>(RED, left.elem, new RedBlackTree<E>(BLACK, left.left.elem, left.left.left, left.left.right), new RedBlackTree<E>(BLACK, elem, left.right, right)); } if (left.right.color == RED) { return new RedBlackTree<E>(RED, left.right.elem, new RedBlackTree<E>(BLACK, left.elem, left.left, left.right.left), new RedBlackTree<E>(BLACK, elem, left.right.right, right)); } } } return new RedBlackTree<E>(color, elem, left, right); } private RedBlackTree<E> rbalance(boolean color, E elem, RedBlackTree<E> left, RedBlackTree<E> right) { if (color == BLACK) { if ((right != EMPTY) && (right.color == RED)) { if (right.left.color == RED) { return new RedBlackTree<E>(RED, right.left.elem, new RedBlackTree<E>(BLACK, elem, left, right.left.left), new RedBlackTree<E>(BLACK, right.elem, right.left.right, right.right)); } if (right.right.color == RED) { return new RedBlackTree<E>(RED, right.elem, new RedBlackTree<E>(BLACK, elem, left, right.left), new RedBlackTree<E>(BLACK, right.right.elem, right.right.left, right.right.right)); } } } return new RedBlackTree<E>(color, elem, left, right); } public boolean contains(E elem) { return getNode(elem) != null; } public E get(E elem) { RedBlackTree<E> node = getNode(elem); return (node == null) ? null : node.elem; } protected RedBlackTree<E> getNode(E elem) { RedBlackTree<E> iter = this; while (iter != EMPTY) { int cmp = elem.compareTo(iter.elem); if (cmp < 0) { iter = iter.left; } else if (cmp > 0) { iter = iter.right; } else { return iter; } } return null; } protected RedBlackTree<E> getNodeLowerBound(E elem) { RedBlackTree<E> iter = this; RedBlackTree<E> candidate = null; while (iter != EMPTY) { int cmp = elem.compareTo(iter.elem); if (cmp == 0) { return iter; } else if (cmp < 0) { candidate = iter; iter = iter.left; } else { iter = iter.right; } } return candidate; } protected RedBlackTree<E> getNodeUpperBound(E elem) { RedBlackTree<E> iter = this; RedBlackTree<E> candidate = null; while (iter != EMPTY) { int cmp = elem.compareTo(iter.elem); if (cmp == 0) { return iter; } else if (cmp < 0) { iter = iter.left; } else { candidate = iter; iter = iter.right; } } return candidate; } public Iterator<E> iterator() { return new RBTIterator<E>(this); } private static final Iterator EMPTY_ITERATOR = new Iterator() { public boolean hasNext() { return false; } public Object next() { throw new NoSuchElementException(); } public void remove() { throw new UnsupportedOperationException(); } }; public Iterator<E> iterator(E from, E to) { RedBlackTree<E> lower = getNodeLowerBound(from); RedBlackTree<E> upper = getNodeUpperBound(to); if ((lower == upper) || (lower == null) || (upper == null) || (lower.elem.compareTo(upper.elem) > 0)) { return EMPTY_ITERATOR; } return new BoundedRBTIterator<E>(this, lower, upper); } static class RBTIterator<T extends Comparable<? super T>> implements Iterator<T> { protected Cons<RedBlackTree<T>> path; protected RedBlackTree<T> next; RBTIterator() { this.path = Cons.empty(); } RBTIterator(RedBlackTree<T> root) { this(); if (root != EMPTY) { findLeftmost(root); } } private void findLeftmost(RedBlackTree<T> node) { while (node.left != EMPTY) { path = path.cons(node); node = node.left; } this.next = node; } public boolean hasNext() { return next != null; } public T next() { if (next == null) { throw new NoSuchElementException(); } else { T result = next.elem; if (next.right != EMPTY) { findLeftmost(next.right); } else { // no elements to the right, so climb up the tree if (path == Cons.EMPTY) { next = null; } else { next = path.first; path = path.rest; } } return result; } } public void remove() { throw new UnsupportedOperationException(); } } static class BoundedRBTIterator<T extends Comparable<? super T>> extends RBTIterator<T> { private RedBlackTree<T> last; BoundedRBTIterator(RedBlackTree<T> root, RedBlackTree<T> from, RedBlackTree<T> to) { super(); this.last = to; findStart(root, from); } private void findStart(RedBlackTree<T> node, RedBlackTree<T> target) { while (node != target) { path = path.cons(node); int cmp = target.elem.compareTo(node.elem); if (cmp < 0) { node = node.left; } else { node = node.right; } } this.next = node; } public T next() { T result = super.next(); if (next == last || next.elem.compareTo(last.elem) == 0) { next = null; } return result; } } }