diff options
Diffstat (limited to 'Source/JavaScriptCore/wtf/RedBlackTree.h')
-rw-r--r-- | Source/JavaScriptCore/wtf/RedBlackTree.h | 574 |
1 files changed, 0 insertions, 574 deletions
diff --git a/Source/JavaScriptCore/wtf/RedBlackTree.h b/Source/JavaScriptCore/wtf/RedBlackTree.h deleted file mode 100644 index 19460c141..000000000 --- a/Source/JavaScriptCore/wtf/RedBlackTree.h +++ /dev/null @@ -1,574 +0,0 @@ -/* - * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef RedBlackTree_h -#define RedBlackTree_h - -#include <wtf/Assertions.h> -#include <wtf/Noncopyable.h> - -namespace WTF { - -// This implements a red-black tree with the following properties: -// - The allocation of nodes in the tree is entirely up to the user. -// - If you are in possession of a pointer to a node, you can delete -// it from the tree. The tree will subsequently no longer have a -// reference to this node. -// - The key type must implement operator< and ==. - -template<class NodeType, typename KeyType> -class RedBlackTree { - WTF_MAKE_NONCOPYABLE(RedBlackTree); -private: - enum Color { - Red = 1, - Black - }; - -public: - class Node { - friend class RedBlackTree; - - public: - const NodeType* successor() const - { - const Node* x = this; - if (x->right()) - return treeMinimum(x->right()); - const NodeType* y = x->parent(); - while (y && x == y->right()) { - x = y; - y = y->parent(); - } - return y; - } - - const NodeType* predecessor() const - { - const Node* x = this; - if (x->left()) - return treeMaximum(x->left()); - const NodeType* y = x->parent(); - while (y && x == y->left()) { - x = y; - y = y->parent(); - } - return y; - } - - NodeType* successor() - { - return const_cast<NodeType*>(const_cast<const Node*>(this)->successor()); - } - - NodeType* predecessor() - { - return const_cast<NodeType*>(const_cast<const Node*>(this)->predecessor()); - } - - private: - void reset() - { - m_left = 0; - m_right = 0; - m_parentAndRed = 1; // initialize to red - } - - // NOTE: these methods should pack the parent and red into a single - // word. But doing so appears to reveal a bug in the compiler. - NodeType* parent() const - { - return reinterpret_cast<NodeType*>(m_parentAndRed & ~static_cast<uintptr_t>(1)); - } - - void setParent(NodeType* newParent) - { - m_parentAndRed = reinterpret_cast<uintptr_t>(newParent) | (m_parentAndRed & 1); - } - - NodeType* left() const - { - return m_left; - } - - void setLeft(NodeType* node) - { - m_left = node; - } - - NodeType* right() const - { - return m_right; - } - - void setRight(NodeType* node) - { - m_right = node; - } - - Color color() const - { - if (m_parentAndRed & 1) - return Red; - return Black; - } - - void setColor(Color value) - { - if (value == Red) - m_parentAndRed |= 1; - else - m_parentAndRed &= ~static_cast<uintptr_t>(1); - } - - NodeType* m_left; - NodeType* m_right; - uintptr_t m_parentAndRed; - }; - - RedBlackTree() - : m_root(0) - { - } - - void insert(NodeType* x) - { - x->reset(); - treeInsert(x); - x->setColor(Red); - - while (x != m_root && x->parent()->color() == Red) { - if (x->parent() == x->parent()->parent()->left()) { - NodeType* y = x->parent()->parent()->right(); - if (y && y->color() == Red) { - // Case 1 - x->parent()->setColor(Black); - y->setColor(Black); - x->parent()->parent()->setColor(Red); - x = x->parent()->parent(); - } else { - if (x == x->parent()->right()) { - // Case 2 - x = x->parent(); - leftRotate(x); - } - // Case 3 - x->parent()->setColor(Black); - x->parent()->parent()->setColor(Red); - rightRotate(x->parent()->parent()); - } - } else { - // Same as "then" clause with "right" and "left" exchanged. - NodeType* y = x->parent()->parent()->left(); - if (y && y->color() == Red) { - // Case 1 - x->parent()->setColor(Black); - y->setColor(Black); - x->parent()->parent()->setColor(Red); - x = x->parent()->parent(); - } else { - if (x == x->parent()->left()) { - // Case 2 - x = x->parent(); - rightRotate(x); - } - // Case 3 - x->parent()->setColor(Black); - x->parent()->parent()->setColor(Red); - leftRotate(x->parent()->parent()); - } - } - } - - m_root->setColor(Black); - } - - NodeType* remove(NodeType* z) - { - ASSERT(z); - ASSERT(z->parent() || z == m_root); - - // Y is the node to be unlinked from the tree. - NodeType* y; - if (!z->left() || !z->right()) - y = z; - else - y = z->successor(); - - // Y is guaranteed to be non-null at this point. - NodeType* x; - if (y->left()) - x = y->left(); - else - x = y->right(); - - // X is the child of y which might potentially replace y in - // the tree. X might be null at this point. - NodeType* xParent; - if (x) { - x->setParent(y->parent()); - xParent = x->parent(); - } else - xParent = y->parent(); - if (!y->parent()) - m_root = x; - else { - if (y == y->parent()->left()) - y->parent()->setLeft(x); - else - y->parent()->setRight(x); - } - - if (y != z) { - if (y->color() == Black) - removeFixup(x, xParent); - - y->setParent(z->parent()); - y->setColor(z->color()); - y->setLeft(z->left()); - y->setRight(z->right()); - - if (z->left()) - z->left()->setParent(y); - if (z->right()) - z->right()->setParent(y); - if (z->parent()) { - if (z->parent()->left() == z) - z->parent()->setLeft(y); - else - z->parent()->setRight(y); - } else { - ASSERT(m_root == z); - m_root = y; - } - } else if (y->color() == Black) - removeFixup(x, xParent); - - return z; - } - - NodeType* remove(const KeyType& key) - { - NodeType* result = findExact(key); - if (!result) - return 0; - return remove(result); - } - - NodeType* findExact(const KeyType& key) const - { - for (NodeType* current = m_root; current;) { - if (current->key() == key) - return current; - if (key < current->key()) - current = current->left(); - else - current = current->right(); - } - return 0; - } - - NodeType* findLeastGreaterThanOrEqual(const KeyType& key) const - { - NodeType* best = 0; - for (NodeType* current = m_root; current;) { - if (current->key() == key) - return current; - if (current->key() < key) - current = current->right(); - else { - best = current; - current = current->left(); - } - } - return best; - } - - NodeType* findGreatestLessThanOrEqual(const KeyType& key) const - { - NodeType* best = 0; - for (NodeType* current = m_root; current;) { - if (current->key() == key) - return current; - if (current->key() > key) - current = current->left(); - else { - best = current; - current = current->right(); - } - } - return best; - } - - NodeType* first() const - { - if (!m_root) - return 0; - return treeMinimum(m_root); - } - - NodeType* last() const - { - if (!m_root) - return 0; - return treeMaximum(m_root); - } - - // This is an O(n) operation. - size_t size() - { - size_t result = 0; - for (NodeType* current = first(); current; current = current->successor()) - result++; - return result; - } - - // This is an O(1) operation. - bool isEmpty() - { - return !m_root; - } - -private: - // Finds the minimum element in the sub-tree rooted at the given - // node. - static NodeType* treeMinimum(NodeType* x) - { - while (x->left()) - x = x->left(); - return x; - } - - static NodeType* treeMaximum(NodeType* x) - { - while (x->right()) - x = x->right(); - return x; - } - - static const NodeType* treeMinimum(const NodeType* x) - { - while (x->left()) - x = x->left(); - return x; - } - - static const NodeType* treeMaximum(const NodeType* x) - { - while (x->right()) - x = x->right(); - return x; - } - - void treeInsert(NodeType* z) - { - ASSERT(!z->left()); - ASSERT(!z->right()); - ASSERT(!z->parent()); - ASSERT(z->color() == Red); - - NodeType* y = 0; - NodeType* x = m_root; - while (x) { - y = x; - if (z->key() < x->key()) - x = x->left(); - else - x = x->right(); - } - z->setParent(y); - if (!y) - m_root = z; - else { - if (z->key() < y->key()) - y->setLeft(z); - else - y->setRight(z); - } - } - - //---------------------------------------------------------------------- - // Red-Black tree operations - // - - // Left-rotates the subtree rooted at x. - // Returns the new root of the subtree (x's right child). - NodeType* leftRotate(NodeType* x) - { - // Set y. - NodeType* y = x->right(); - - // Turn y's left subtree into x's right subtree. - x->setRight(y->left()); - if (y->left()) - y->left()->setParent(x); - - // Link x's parent to y. - y->setParent(x->parent()); - if (!x->parent()) - m_root = y; - else { - if (x == x->parent()->left()) - x->parent()->setLeft(y); - else - x->parent()->setRight(y); - } - - // Put x on y's left. - y->setLeft(x); - x->setParent(y); - - return y; - } - - // Right-rotates the subtree rooted at y. - // Returns the new root of the subtree (y's left child). - NodeType* rightRotate(NodeType* y) - { - // Set x. - NodeType* x = y->left(); - - // Turn x's right subtree into y's left subtree. - y->setLeft(x->right()); - if (x->right()) - x->right()->setParent(y); - - // Link y's parent to x. - x->setParent(y->parent()); - if (!y->parent()) - m_root = x; - else { - if (y == y->parent()->left()) - y->parent()->setLeft(x); - else - y->parent()->setRight(x); - } - - // Put y on x's right. - x->setRight(y); - y->setParent(x); - - return x; - } - - // Restores the red-black property to the tree after splicing out - // a node. Note that x may be null, which is why xParent must be - // supplied. - void removeFixup(NodeType* x, NodeType* xParent) - { - while (x != m_root && (!x || x->color() == Black)) { - if (x == xParent->left()) { - // Note: the text points out that w can not be null. - // The reason is not obvious from simply looking at - // the code; it comes about from the properties of the - // red-black tree. - NodeType* w = xParent->right(); - ASSERT(w); // x's sibling should not be null. - if (w->color() == Red) { - // Case 1 - w->setColor(Black); - xParent->setColor(Red); - leftRotate(xParent); - w = xParent->right(); - } - if ((!w->left() || w->left()->color() == Black) - && (!w->right() || w->right()->color() == Black)) { - // Case 2 - w->setColor(Red); - x = xParent; - xParent = x->parent(); - } else { - if (!w->right() || w->right()->color() == Black) { - // Case 3 - w->left()->setColor(Black); - w->setColor(Red); - rightRotate(w); - w = xParent->right(); - } - // Case 4 - w->setColor(xParent->color()); - xParent->setColor(Black); - if (w->right()) - w->right()->setColor(Black); - leftRotate(xParent); - x = m_root; - xParent = x->parent(); - } - } else { - // Same as "then" clause with "right" and "left" - // exchanged. - - // Note: the text points out that w can not be null. - // The reason is not obvious from simply looking at - // the code; it comes about from the properties of the - // red-black tree. - NodeType* w = xParent->left(); - ASSERT(w); // x's sibling should not be null. - if (w->color() == Red) { - // Case 1 - w->setColor(Black); - xParent->setColor(Red); - rightRotate(xParent); - w = xParent->left(); - } - if ((!w->right() || w->right()->color() == Black) - && (!w->left() || w->left()->color() == Black)) { - // Case 2 - w->setColor(Red); - x = xParent; - xParent = x->parent(); - } else { - if (!w->left() || w->left()->color() == Black) { - // Case 3 - w->right()->setColor(Black); - w->setColor(Red); - leftRotate(w); - w = xParent->left(); - } - // Case 4 - w->setColor(xParent->color()); - xParent->setColor(Black); - if (w->left()) - w->left()->setColor(Black); - rightRotate(xParent); - x = m_root; - xParent = x->parent(); - } - } - } - if (x) - x->setColor(Black); - } - - NodeType* m_root; -}; - -} - -#endif - |