2 * Copyright (C) 2010 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // A red-black tree, which is a form of a balanced binary tree. It
27 // supports efficient insertion, deletion and queries of comparable
28 // elements. The same element may be inserted multiple times. The
29 // algorithmic complexity of common operations is:
31 // Insertion: O(lg(n))
35 // The data type T that is stored in this red-black tree must be only
36 // Plain Old Data (POD), or bottom out into POD. It must _not_ rely on
37 // having its destructor called. This implementation internally
38 // allocates storage in large chunks and does not call the destructor
41 // Type T must supply a default constructor, a copy constructor, and
42 // the "<" and "==" operators.
44 // In debug mode, printing of the data contained in the tree is
45 // enabled. This requires the template specialization to be available:
47 // template<> struct ValueToString<T> {
48 // static String string(const T& t);
51 // Note that when complex types are stored in this red/black tree, it
52 // is possible that single invocations of the "<" and "==" operators
53 // will be insufficient to describe the ordering of elements in the
54 // tree during queries. As a concrete example, consider the case where
55 // intervals are stored in the tree sorted by low endpoint. The "<"
56 // operator on the Interval class only compares the low endpoint, but
57 // the "==" operator takes into account the high endpoint as well.
58 // This makes the necessary logic for querying and deletion somewhat
59 // more complex. In order to properly handle such situations, the
60 // property "needsFullOrderingComparisons" must be set to true on
63 // This red-black tree is designed to be _augmented_; subclasses can
64 // add additional and summary information to each node to efficiently
65 // store and index more complex data structures. A concrete example is
66 // the IntervalTree, which extends each node with a summary statistic
67 // to efficiently store one-dimensional intervals.
69 // The design of this red-black tree comes from Cormen, Leiserson,
70 // and Rivest, _Introduction to Algorithms_, MIT Press, 1990.
72 #ifndef PODRedBlackTree_h
73 #define PODRedBlackTree_h
75 #include "platform/PODFreeListArena.h"
76 #include "wtf/Assertions.h"
77 #include "wtf/Noncopyable.h"
78 #include "wtf/RefPtr.h"
80 #include "wtf/text/CString.h"
81 #include "wtf/text/StringBuilder.h"
82 #include "wtf/text/WTFString.h"
92 enum UninitializedTreeEnum
{
97 class PODRedBlackTree
{
101 // Visitor interface for walking all of the tree's elements.
104 virtual void visit(const T
& data
) = 0;
106 virtual ~Visitor() { }
109 // Constructs a new red-black tree without allocating an arena.
110 // isInitialized will return false in this case. initIfNeeded can be used
111 // to init the structure. This constructor is usefull for creating
112 // lazy initialized tree.
113 explicit PODRedBlackTree(UninitializedTreeEnum
)
115 , m_needsFullOrderingComparisons(false)
117 , m_verboseDebugging(false)
122 // Constructs a new red-black tree, allocating temporary objects
123 // from a newly constructed PODFreeListArena.
125 : m_arena(PODFreeListArena
<Node
>::create())
127 , m_needsFullOrderingComparisons(false)
129 , m_verboseDebugging(false)
134 // Constructs a new red-black tree, allocating temporary objects
135 // from the given PODArena.
136 explicit PODRedBlackTree(PassRefPtr
<PODFreeListArena
<Node
>> arena
)
139 , m_needsFullOrderingComparisons(false)
141 , m_verboseDebugging(false)
146 virtual ~PODRedBlackTree() { }
148 // Clearing will delete the contents of the tree. After this call
149 // isInitialized will return false.
157 bool isInitialized() const
165 m_arena
= PODFreeListArena
<Node
>::create();
168 void initIfNeeded(PODFreeListArena
<Node
>* arena
)
174 void add(const T
& data
)
176 ASSERT(isInitialized());
177 Node
* node
= m_arena
->template allocateObject
<T
>(data
);
181 // Returns true if the datum was found in the tree.
182 bool remove(const T
& data
)
184 ASSERT(isInitialized());
185 Node
* node
= treeSearch(data
);
193 bool contains(const T
& data
) const
195 ASSERT(isInitialized());
196 return treeSearch(data
);
199 void visitInorder(Visitor
* visitor
) const
201 ASSERT(isInitialized());
204 visitInorderImpl(m_root
, visitor
);
209 ASSERT(isInitialized());
211 visitInorder(&counter
);
212 return counter
.count();
215 // See the class documentation for an explanation of this property.
216 void setNeedsFullOrderingComparisons(bool needsFullOrderingComparisons
)
218 m_needsFullOrderingComparisons
= needsFullOrderingComparisons
;
221 virtual bool checkInvariants() const
223 ASSERT(isInitialized());
225 return checkInvariantsFromNode(m_root
, &blackCount
);
229 // Dumps the tree's contents to the logging info stream for
230 // debugging purposes.
234 dumpFromNode(m_root
, 0);
237 // Turns on or off verbose debugging of the tree, causing many
238 // messages to be logged during insertion and other operations in
240 void setVerboseDebugging(bool verboseDebugging
)
242 m_verboseDebugging
= verboseDebugging
;
251 // The base Node class which is stored in the tree. Nodes are only
252 // an internal concept; users of the tree deal only with the data
255 WTF_MAKE_NONCOPYABLE(Node
);
257 // Constructor. Newly-created nodes are colored red.
258 explicit Node(const T
& data
)
269 Color
color() const { return m_color
; }
270 void setColor(Color color
) { m_color
= color
; }
272 // Fetches the user data.
273 T
& data() { return m_data
; }
275 // Copies all user-level fields from the source node, but not
276 // internal fields. For example, the base implementation of this
277 // method copies the "m_data" field, but not the child or parent
278 // fields. Any augmentation information also does not need to be
279 // copied, as it will be recomputed. Subclasses must call the
280 // superclass implementation.
281 virtual void copyFrom(Node
* src
) { m_data
= src
->data(); }
283 Node
* left() const { return m_left
; }
284 void setLeft(Node
* node
) { m_left
= node
; }
286 Node
* right() const { return m_right
; }
287 void setRight(Node
* node
) { m_right
= node
; }
289 Node
* parent() const { return m_parent
; }
290 void setParent(Node
* node
) { m_parent
= node
; }
301 // Returns the root of the tree, which is needed by some subclasses.
302 Node
* root() const { return m_root
; }
305 // This virtual method is the hook that subclasses should use when
306 // augmenting the red-black tree with additional per-node summary
307 // information. For example, in the case of an interval tree, this
308 // is used to compute the maximum endpoint of the subtree below the
309 // given node based on the values in the left and right children. It
310 // is guaranteed that this will be called in the correct order to
311 // properly update such summary information based only on the values
312 // in the left and right children. This method should return true if
313 // the node's summary information changed.
314 virtual bool updateNode(Node
*) { return false; }
316 //----------------------------------------------------------------------
317 // Generic binary search tree operations
320 // Searches the tree for the given datum.
321 Node
* treeSearch(const T
& data
) const
323 if (m_needsFullOrderingComparisons
)
324 return treeSearchFullComparisons(m_root
, data
);
326 return treeSearchNormal(m_root
, data
);
329 // Searches the tree using the normal comparison operations,
330 // suitable for simple data types such as numbers.
331 Node
* treeSearchNormal(Node
* current
, const T
& data
) const
334 if (current
->data() == data
)
336 if (data
< current
->data())
337 current
= current
->left();
339 current
= current
->right();
344 // Searches the tree using multiple comparison operations, required
345 // for data types with more complex behavior such as intervals.
346 Node
* treeSearchFullComparisons(Node
* current
, const T
& data
) const
350 if (data
< current
->data())
351 return treeSearchFullComparisons(current
->left(), data
);
352 if (current
->data() < data
)
353 return treeSearchFullComparisons(current
->right(), data
);
354 if (data
== current
->data())
357 // We may need to traverse both the left and right subtrees.
358 Node
* result
= treeSearchFullComparisons(current
->left(), data
);
360 result
= treeSearchFullComparisons(current
->right(), data
);
364 void treeInsert(Node
* z
)
370 if (z
->data() < x
->data())
379 if (z
->data() < y
->data())
386 // Finds the node following the given one in sequential ordering of
387 // their data, or null if none exists.
388 Node
* treeSuccessor(Node
* x
)
391 return treeMinimum(x
->right());
392 Node
* y
= x
->parent();
393 while (y
&& x
== y
->right()) {
400 // Finds the minimum element in the sub-tree rooted at the given
402 Node
* treeMinimum(Node
* x
)
409 // Helper for maintaining the augmented red-black tree.
410 void propagateUpdates(Node
* start
)
412 bool shouldContinue
= true;
413 while (start
&& shouldContinue
) {
414 shouldContinue
= updateNode(start
);
415 start
= start
->parent();
419 //----------------------------------------------------------------------
420 // Red-Black tree operations
423 // Left-rotates the subtree rooted at x.
424 // Returns the new root of the subtree (x's right child).
425 Node
* leftRotate(Node
* x
)
428 Node
* y
= x
->right();
430 // Turn y's left subtree into x's right subtree.
431 x
->setRight(y
->left());
433 y
->left()->setParent(x
);
435 // Link x's parent to y.
436 y
->setParent(x
->parent());
440 if (x
== x
->parent()->left())
441 x
->parent()->setLeft(y
);
443 x
->parent()->setRight(y
);
446 // Put x on y's left.
450 // Update nodes lowest to highest.
456 // Right-rotates the subtree rooted at y.
457 // Returns the new root of the subtree (y's left child).
458 Node
* rightRotate(Node
* y
)
463 // Turn x's right subtree into y's left subtree.
464 y
->setLeft(x
->right());
466 x
->right()->setParent(y
);
468 // Link y's parent to x.
469 x
->setParent(y
->parent());
473 if (y
== y
->parent()->left())
474 y
->parent()->setLeft(x
);
476 y
->parent()->setRight(x
);
479 // Put y on x's right.
483 // Update nodes lowest to highest.
489 // Inserts the given node into the tree.
490 void insertNode(Node
* x
)
496 logIfVerbose(" PODRedBlackTree::InsertNode");
498 // The node from which to start propagating updates upwards.
499 Node
* updateStart
= x
->parent();
501 while (x
!= m_root
&& x
->parent()->color() == Red
) {
502 if (x
->parent() == x
->parent()->parent()->left()) {
503 Node
* y
= x
->parent()->parent()->right();
504 if (y
&& y
->color() == Red
) {
506 logIfVerbose(" Case 1/1");
507 x
->parent()->setColor(Black
);
509 x
->parent()->parent()->setColor(Red
);
510 updateNode(x
->parent());
511 x
= x
->parent()->parent();
513 updateStart
= x
->parent();
515 if (x
== x
->parent()->right()) {
516 logIfVerbose(" Case 1/2");
522 logIfVerbose(" Case 1/3");
523 x
->parent()->setColor(Black
);
524 x
->parent()->parent()->setColor(Red
);
525 Node
* newSubTreeRoot
= rightRotate(x
->parent()->parent());
526 updateStart
= newSubTreeRoot
->parent();
529 // Same as "then" clause with "right" and "left" exchanged.
530 Node
* y
= x
->parent()->parent()->left();
531 if (y
&& y
->color() == Red
) {
533 logIfVerbose(" Case 2/1");
534 x
->parent()->setColor(Black
);
536 x
->parent()->parent()->setColor(Red
);
537 updateNode(x
->parent());
538 x
= x
->parent()->parent();
540 updateStart
= x
->parent();
542 if (x
== x
->parent()->left()) {
544 logIfVerbose(" Case 2/2");
549 logIfVerbose(" Case 2/3");
550 x
->parent()->setColor(Black
);
551 x
->parent()->parent()->setColor(Red
);
552 Node
* newSubTreeRoot
= leftRotate(x
->parent()->parent());
553 updateStart
= newSubTreeRoot
->parent();
558 propagateUpdates(updateStart
);
560 m_root
->setColor(Black
);
563 // Restores the red-black property to the tree after splicing out
564 // a node. Note that x may be null, which is why xParent must be
566 void deleteFixup(Node
* x
, Node
* xParent
)
568 while (x
!= m_root
&& (!x
|| x
->color() == Black
)) {
569 if (x
== xParent
->left()) {
570 // Note: the text points out that w can not be null.
571 // The reason is not obvious from simply looking at
572 // the code; it comes about from the properties of the
574 Node
* w
= xParent
->right();
575 ASSERT(w
); // x's sibling should not be null.
576 if (w
->color() == Red
) {
579 xParent
->setColor(Red
);
581 w
= xParent
->right();
583 if ((!w
->left() || w
->left()->color() == Black
)
584 && (!w
->right() || w
->right()->color() == Black
)) {
588 xParent
= x
->parent();
590 if (!w
->right() || w
->right()->color() == Black
) {
592 w
->left()->setColor(Black
);
595 w
= xParent
->right();
598 w
->setColor(xParent
->color());
599 xParent
->setColor(Black
);
601 w
->right()->setColor(Black
);
604 xParent
= x
->parent();
607 // Same as "then" clause with "right" and "left"
610 // Note: the text points out that w can not be null.
611 // The reason is not obvious from simply looking at
612 // the code; it comes about from the properties of the
614 Node
* w
= xParent
->left();
615 ASSERT(w
); // x's sibling should not be null.
616 if (w
->color() == Red
) {
619 xParent
->setColor(Red
);
620 rightRotate(xParent
);
623 if ((!w
->right() || w
->right()->color() == Black
)
624 && (!w
->left() || w
->left()->color() == Black
)) {
628 xParent
= x
->parent();
630 if (!w
->left() || w
->left()->color() == Black
) {
632 w
->right()->setColor(Black
);
638 w
->setColor(xParent
->color());
639 xParent
->setColor(Black
);
641 w
->left()->setColor(Black
);
642 rightRotate(xParent
);
644 xParent
= x
->parent();
652 // Deletes the given node from the tree. Note that this
653 // particular node may not actually be removed from the tree;
654 // instead, another node might be removed and its contents
656 void deleteNode(Node
* z
)
658 // Y is the node to be unlinked from the tree.
660 if (!z
->left() || !z
->right())
663 y
= treeSuccessor(z
);
665 // Y is guaranteed to be non-null at this point.
672 // X is the child of y which might potentially replace y in
673 // the tree. X might be null at this point.
676 x
->setParent(y
->parent());
677 xParent
= x
->parent();
679 xParent
= y
->parent();
684 if (y
== y
->parent()->left())
685 y
->parent()->setLeft(x
);
687 y
->parent()->setRight(x
);
691 // This node has changed location in the tree and must be updated.
693 // The parent and its parents may now be out of date.
694 propagateUpdates(z
->parent());
697 // If we haven't already updated starting from xParent, do so now.
698 if (xParent
&& xParent
!= y
&& xParent
!= z
)
699 propagateUpdates(xParent
);
700 if (y
->color() == Black
)
701 deleteFixup(x
, xParent
);
703 m_arena
->freeObject(y
);
706 // Visits the subtree rooted at the given node in order.
707 void visitInorderImpl(Node
* node
, Visitor
* visitor
) const
710 visitInorderImpl(node
->left(), visitor
);
711 visitor
->visit(node
->data());
713 visitInorderImpl(node
->right(), visitor
);
716 void markFree(Node
*node
)
722 markFree(node
->left());
724 markFree(node
->right());
725 m_arena
->freeObject(node
);
728 //----------------------------------------------------------------------
729 // Helper class for size()
731 // A Visitor which simply counts the number of visited elements.
732 class Counter
: public Visitor
{
733 WTF_MAKE_NONCOPYABLE(Counter
);
738 virtual void visit(const T
&) { ++m_count
; }
739 int count() const { return m_count
; }
745 //----------------------------------------------------------------------
746 // Verification and debugging routines
749 // Returns in the "blackCount" parameter the number of black
750 // children along all paths to all leaves of the given node.
751 bool checkInvariantsFromNode(Node
* node
, int* blackCount
) const
753 // Base case is a leaf node.
759 // Each node is either red or black.
760 if (!(node
->color() == Red
|| node
->color() == Black
))
763 // Every leaf (or null) is black.
765 if (node
->color() == Red
) {
766 // Both of its children are black.
767 if (!((!node
->left() || node
->left()->color() == Black
)))
769 if (!((!node
->right() || node
->right()->color() == Black
)))
773 // Every simple path to a leaf node contains the same number of
775 int leftCount
= 0, rightCount
= 0;
776 bool leftValid
= checkInvariantsFromNode(node
->left(), &leftCount
);
777 bool rightValid
= checkInvariantsFromNode(node
->right(), &rightCount
);
778 if (!leftValid
|| !rightValid
)
780 *blackCount
= leftCount
+ (node
->color() == Black
? 1 : 0);
781 return leftCount
== rightCount
;
785 void logIfVerbose(const char*) const { }
787 void logIfVerbose(const char* output
) const
789 if (m_verboseDebugging
)
790 WTF_LOG_ERROR("%s", output
);
795 // Dumps the subtree rooted at the given node.
796 void dumpFromNode(Node
* node
, int indentation
) const
798 StringBuilder builder
;
799 for (int i
= 0; i
< indentation
; i
++)
804 builder
.append(ValueToString
<T
>::string(node
->data()));
805 builder
.append((node
->color() == Black
) ? " (black)" : " (red)");
807 WTF_LOG_ERROR("%s", builder
.toString().ascii().data());
809 dumpFromNode(node
->left(), indentation
+ 2);
810 dumpFromNode(node
->right(), indentation
+ 2);
815 //----------------------------------------------------------------------
818 RefPtr
<PODFreeListArena
<Node
>> m_arena
;
820 bool m_needsFullOrderingComparisons
;
822 bool m_verboseDebugging
;
828 #endif // PODRedBlackTree_h