--- /dev/null
+/*
+ Copyright 2011 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#ifndef GrRedBlackTree_DEFINED
+#define GrRedBlackTree_DEFINED
+
+#include "GrNoncopyable.h"
+
+template <typename T>
+class GrLess {
+public:
+ bool operator()(const T& a, const T& b) const { return a < b; }
+};
+
+template <typename T>
+class GrLess<T*> {
+public:
+ bool operator()(const T* a, const T* b) const { return *a < *b; }
+};
+
+/**
+ * In debug build this will cause full traversals of the tree when the validate
+ * is called on insert and remove. Useful for debugging but very slow.
+ */
+#define DEEP_VALIDATE 0
+
+/**
+ * A sorted tree that uses the red-black tree algorithm. Allows duplicate
+ * entries. Data is of type T and is compared using functor C. A single C object
+ * will be created and used for all comparisons.
+ */
+template <typename T, typename C = GrLess<T> >
+class GrRedBlackTree : public GrNoncopyable {
+public:
+ /**
+ * Creates an empty tree.
+ */
+ GrRedBlackTree();
+ virtual ~GrRedBlackTree();
+
+ /**
+ * Class used to iterater through the tree. The valid range of the tree
+ * is given by [begin(), end()). It is legal to dereference begin() but not
+ * end(). The iterator has preincrement and predecrement operators, it is
+ * legal to decerement end() if the tree is not empty to get the last
+ * element. However, a last() helper is provided.
+ */
+ class Iter;
+
+ /**
+ * Add an element to the tree. Duplicates are allowed.
+ * @param t the item to add.
+ * @return an iterator to the item.
+ */
+ Iter insert(const T& t);
+
+ /**
+ * Removes all items in the tree.
+ */
+ void reset();
+
+ /**
+ * @return true if there are no items in the tree, false otherwise.
+ */
+ bool empty() const {return 0 == fCount;}
+
+ /**
+ * @return the number of items in the tree.
+ */
+ int count() const {return fCount;}
+
+ /**
+ * @return an iterator to the first item in sorted order, or end() if empty
+ */
+ Iter begin();
+ /**
+ * Gets the last valid iterator. This is always valid, even on an empty.
+ * However, it can never be dereferenced. Useful as a loop terminator.
+ * @return an iterator that is just beyond the last item in sorted order.
+ */
+ Iter end();
+ /**
+ * @return an iterator that to the last item in sorted order, or end() if
+ * empty.
+ */
+ Iter last();
+
+ /**
+ * Finds an occurrence of an item.
+ * @param t the item to find.
+ * @return an iterator to a tree element equal to t or end() if none exists.
+ */
+ Iter find(const T& t);
+ /**
+ * Finds the first of an item in iterator order.
+ * @param t the item to find.
+ * @return an iterator to the first element equal to t or end() if
+ * none exists.
+ */
+ Iter findFirst(const T& t);
+ /**
+ * Finds the last of an item in iterator order.
+ * @param t the item to find.
+ * @return an iterator to the last element equal to t or end() if
+ * none exists.
+ */
+ Iter findLast(const T& t);
+ /**
+ * Gets the number of items in the tree equal to t.
+ * @param t the item to count.
+ * @return number of items equal to t in the tree
+ */
+ int countOf(const T& t) const;
+
+ /**
+ * Removes the item indicated by an iterator. The iterator will not be valid
+ * afterwards.
+ *
+ * @param iter iterator of item to remove. Must be valid (not end()).
+ */
+ void remove(const Iter& iter) { deleteAtNode(iter.fN); }
+
+ static void UnitTest();
+
+private:
+ enum Color {
+ kRed_Color,
+ kBlack_Color
+ };
+
+ enum Child {
+ kLeft_Child = 0,
+ kRight_Child = 1
+ };
+
+ struct Node {
+ T fItem;
+ Color fColor;
+
+ Node* fParent;
+ Node* fChildren[2];
+ };
+
+ void rotateRight(Node* n);
+ void rotateLeft(Node* n);
+
+ static Node* SuccessorNode(Node* x);
+ static Node* PredecessorNode(Node* x);
+
+ void deleteAtNode(Node* x);
+ static void RecursiveDelete(Node* x);
+
+ int countOfHelper(const Node* n, const T& t) const;
+
+#if GR_DEBUG
+ void validate() const;
+ int checkNode(Node* n, int* blackHeight) const;
+ // checks relationship between a node and its children. allowRedRed means
+ // node may be in an intermediate state where a red parent has a red child.
+ bool validateChildRelations(const Node* n, bool allowRedRed) const;
+ // place to stick break point if validateChildRelations is failing.
+ bool validateChildRelationsFailed() const { return false; }
+#else
+ void validate() const {}
+#endif
+
+ int fCount;
+ Node* fRoot;
+ Node* fFirst;
+ Node* fLast;
+
+ const C fComp;
+};
+
+template <typename T, typename C>
+class GrRedBlackTree<T,C>::Iter {
+public:
+ Iter() {};
+ Iter(const Iter& i) {fN = i.fN; fTree = i.fTree;}
+ Iter& operator =(const Iter& i) {
+ fN = i.fN;
+ fTree = i.fTree;
+ return *this;
+ }
+ // altering the sort value of the item using this method will cause
+ // errors.
+ T& operator *() const { return fN->fItem; }
+ bool operator ==(const Iter& i) const {
+ return fN == i.fN && fTree == i.fTree;
+ }
+ bool operator !=(const Iter& i) const { return !(*this == i); }
+ Iter& operator ++() {
+ GrAssert(*this != fTree->end());
+ fN = SuccessorNode(fN);
+ return *this;
+ }
+ Iter& operator --() {
+ GrAssert(*this != fTree->begin());
+ if (NULL != fN) {
+ fN = PredecessorNode(fN);
+ } else {
+ *this = fTree->last();
+ }
+ return *this;
+ }
+
+private:
+ friend class GrRedBlackTree;
+ explicit Iter(Node* n, GrRedBlackTree* tree) {
+ fN = n;
+ fTree = tree;
+ }
+ Node* fN;
+ GrRedBlackTree* fTree;
+};
+
+template <typename T, typename C>
+GrRedBlackTree<T,C>::GrRedBlackTree() : fComp() {
+ fRoot = NULL;
+ fFirst = NULL;
+ fLast = NULL;
+ fCount = 0;
+ validate();
+}
+
+template <typename T, typename C>
+GrRedBlackTree<T,C>::~GrRedBlackTree() {
+ RecursiveDelete(fRoot);
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::begin() {
+ return Iter(fFirst, this);
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::end() {
+ return Iter(NULL, this);
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::last() {
+ return Iter(fLast, this);
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::find(const T& t) {
+ Node* n = fRoot;
+ while (NULL != n) {
+ if (fComp(t, n->fItem)) {
+ n = n->fChildren[kLeft_Child];
+ } else {
+ if (!fComp(n->fItem, t)) {
+ return Iter(n, this);
+ }
+ n = n->fChildren[kRight_Child];
+ }
+ }
+ return end();
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::findFirst(const T& t) {
+ Node* n = fRoot;
+ Node* leftMost = NULL;
+ while (NULL != n) {
+ if (fComp(t, n->fItem)) {
+ n = n->fChildren[kLeft_Child];
+ } else {
+ if (!fComp(n->fItem, t)) {
+ // found one. check if another in left subtree.
+ leftMost = n;
+ n = n->fChildren[kLeft_Child];
+ } else {
+ n = n->fChildren[kRight_Child];
+ }
+ }
+ }
+ return Iter(leftMost, this);
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::findLast(const T& t) {
+ Node* n = fRoot;
+ Node* rightMost = NULL;
+ while (NULL != n) {
+ if (fComp(t, n->fItem)) {
+ n = n->fChildren[kLeft_Child];
+ } else {
+ if (!fComp(n->fItem, t)) {
+ // found one. check if another in right subtree.
+ rightMost = n;
+ }
+ n = n->fChildren[kRight_Child];
+ }
+ }
+ return Iter(rightMost, this);
+}
+
+template <typename T, typename C>
+int GrRedBlackTree<T,C>::countOf(const T& t) const {
+ return countOfHelper(fRoot, t);
+}
+
+template <typename T, typename C>
+int GrRedBlackTree<T,C>::countOfHelper(const Node* n, const T& t) const {
+ // this is count*log(n) :(
+ while (NULL != n) {
+ if (fComp(t, n->fItem)) {
+ n = n->fChildren[kLeft_Child];
+ } else {
+ if (!fComp(n->fItem, t)) {
+ int count = 1;
+ count += countOfHelper(n->fChildren[kLeft_Child], t);
+ count += countOfHelper(n->fChildren[kRight_Child], t);
+ return count;
+ }
+ n = n->fChildren[kRight_Child];
+ }
+ }
+ return 0;
+
+}
+
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::reset() {
+ RecursiveDelete(fRoot);
+ fRoot = NULL;
+ fFirst = NULL;
+ fLast = NULL;
+ fCount = 0;
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Iter GrRedBlackTree<T,C>::insert(const T& t) {
+ validate();
+
+ ++fCount;
+
+ Node* x = new Node;
+ x->fChildren[kLeft_Child] = NULL;
+ x->fChildren[kRight_Child] = NULL;
+ x->fItem = t;
+
+ Node* gp = NULL;
+ Node* p = NULL;
+ Node* n = fRoot;
+ Child pc;
+ Child gpc;
+
+ bool first = true;
+ bool last = true;
+ while (NULL != n) {
+ gpc = pc;
+ pc = fComp(x->fItem, n->fItem) ? kLeft_Child : kRight_Child;
+ first = first && kLeft_Child == pc;
+ last = last && kRight_Child == pc;
+ gp = p;
+ p = n;
+ n = p->fChildren[pc];
+
+ }
+ if (last) {
+ fLast = x;
+ }
+ if (first) {
+ fFirst = x;
+ }
+
+ if (NULL == p) {
+ fRoot = x;
+ x->fColor = kBlack_Color;
+ x->fParent = NULL;
+ GrAssert(1 == fCount);
+ return Iter(x, this);
+ }
+ p->fChildren[pc] = x;
+ x->fColor = kRed_Color;
+ x->fParent = p;
+
+ do {
+ // assumptions at loop start.
+ GrAssert(NULL != x);
+ GrAssert(kRed_Color == x->fColor);
+ // can't have a grandparent but no parent.
+ GrAssert(!(NULL != gp && NULL == p));
+ // make sure pc and gpc are correct
+ GrAssert(NULL == p || p->fChildren[pc] == x);
+ GrAssert(NULL == gp || gp->fChildren[gpc] == p);
+
+ // if x's parent is black then we didn't violate any of the
+ // red/black properties when we added x as red.
+ if (kBlack_Color == p->fColor) {
+ return Iter(x, this);
+ }
+ // gp must be valid because if p was the root then it is black
+ GrAssert(NULL != gp);
+ // gp must be black since it's child, p, is red.
+ GrAssert(kBlack_Color == gp->fColor);
+
+
+ // x and its parent are red, violating red-black property.
+ Node* u = gp->fChildren[1-gpc];
+ // if x's uncle (p's sibling) is also red then we can flip
+ // p and u to black and make gp red. But then we have to recurse
+ // up to gp since it's parent may also be red.
+ if (NULL != u && kRed_Color == u->fColor) {
+ p->fColor = kBlack_Color;
+ u->fColor = kBlack_Color;
+ gp->fColor = kRed_Color;
+ x = gp;
+ p = x->fParent;
+ if (NULL == p) {
+ // x (prev gp) is the root, color it black and be done.
+ GrAssert(fRoot == x);
+ x->fColor = kBlack_Color;
+ validate();
+ return Iter(x, this);
+ }
+ gp = p->fParent;
+ pc = (p->fChildren[kLeft_Child] == x) ? kLeft_Child :
+ kRight_Child;
+ if (NULL != gp) {
+ gpc = (gp->fChildren[kLeft_Child] == p) ? kLeft_Child :
+ kRight_Child;
+ }
+ continue;
+ } break;
+ } while (true);
+ // Here p is red but u is black and we still have to resolve the fact
+ // that x and p are both red.
+ GrAssert(NULL == gp->fChildren[1-gpc] || kBlack_Color == gp->fChildren[1-gpc]->fColor);
+ GrAssert(kRed_Color == x->fColor);
+ GrAssert(kRed_Color == p->fColor);
+ GrAssert(kBlack_Color == gp->fColor);
+
+ // make x be on the same side of p as p is of gp. If it isn't already
+ // the case then rotate x up to p and swap their labels.
+ if (pc != gpc) {
+ if (kRight_Child == pc) {
+ rotateLeft(p);
+ Node* temp = p;
+ p = x;
+ x = temp;
+ pc = kLeft_Child;
+ } else {
+ rotateRight(p);
+ Node* temp = p;
+ p = x;
+ x = temp;
+ pc = kRight_Child;
+ }
+ }
+ // we now rotate gp down, pulling up p to be it's new parent.
+ // gp's child, u, that is not affected we know to be black. gp's new
+ // child is p's previous child (x's pre-rotation sibling) which must be
+ // black since p is red.
+ GrAssert(NULL == p->fChildren[1-pc] ||
+ kBlack_Color == p->fChildren[1-pc]->fColor);
+ // Since gp's two children are black it can become red if p is made
+ // black. This leaves the black-height of both of p's new subtrees
+ // preserved and removes the red/red parent child relationship.
+ p->fColor = kBlack_Color;
+ gp->fColor = kRed_Color;
+ if (kLeft_Child == pc) {
+ rotateRight(gp);
+ } else {
+ rotateLeft(gp);
+ }
+ validate();
+ return Iter(x, this);
+}
+
+
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::rotateRight(Node* n) {
+ /* d? d?
+ * / /
+ * n s
+ * / \ ---> / \
+ * s a? c? n
+ * / \ / \
+ * c? b? b? a?
+ */
+ Node* d = n->fParent;
+ Node* s = n->fChildren[kLeft_Child];
+ GrAssert(NULL != s);
+ Node* b = s->fChildren[kRight_Child];
+
+ if (NULL != d) {
+ Child c = d->fChildren[kLeft_Child] == n ? kLeft_Child :
+ kRight_Child;
+ d->fChildren[c] = s;
+ } else {
+ GrAssert(fRoot == n);
+ fRoot = s;
+ }
+ s->fParent = d;
+ s->fChildren[kRight_Child] = n;
+ n->fParent = s;
+ n->fChildren[kLeft_Child] = b;
+ if (NULL != b) {
+ b->fParent = n;
+ }
+
+ GR_DEBUGASSERT(validateChildRelations(d, true));
+ GR_DEBUGASSERT(validateChildRelations(s, true));
+ GR_DEBUGASSERT(validateChildRelations(n, false));
+ GR_DEBUGASSERT(validateChildRelations(n->fChildren[kRight_Child], true));
+ GR_DEBUGASSERT(validateChildRelations(b, true));
+ GR_DEBUGASSERT(validateChildRelations(s->fChildren[kLeft_Child], true));
+}
+
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::rotateLeft(Node* n) {
+
+ Node* d = n->fParent;
+ Node* s = n->fChildren[kRight_Child];
+ GrAssert(NULL != s);
+ Node* b = s->fChildren[kLeft_Child];
+
+ if (NULL != d) {
+ Child c = d->fChildren[kRight_Child] == n ? kRight_Child :
+ kLeft_Child;
+ d->fChildren[c] = s;
+ } else {
+ GrAssert(fRoot == n);
+ fRoot = s;
+ }
+ s->fParent = d;
+ s->fChildren[kLeft_Child] = n;
+ n->fParent = s;
+ n->fChildren[kRight_Child] = b;
+ if (NULL != b) {
+ b->fParent = n;
+ }
+
+ GR_DEBUGASSERT(validateChildRelations(d, true));
+ GR_DEBUGASSERT(validateChildRelations(s, true));
+ GR_DEBUGASSERT(validateChildRelations(n, true));
+ GR_DEBUGASSERT(validateChildRelations(n->fChildren[kLeft_Child], true));
+ GR_DEBUGASSERT(validateChildRelations(b, true));
+ GR_DEBUGASSERT(validateChildRelations(s->fChildren[kRight_Child], true));
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Node* GrRedBlackTree<T,C>::SuccessorNode(Node* x) {
+ GrAssert(NULL != x);
+ if (NULL != x->fChildren[kRight_Child]) {
+ x = x->fChildren[kRight_Child];
+ while (NULL != x->fChildren[kLeft_Child]) {
+ x = x->fChildren[kLeft_Child];
+ }
+ return x;
+ }
+ while (NULL != x->fParent && x == x->fParent->fChildren[kRight_Child]) {
+ x = x->fParent;
+ }
+ return x->fParent;
+}
+
+template <typename T, typename C>
+typename GrRedBlackTree<T,C>::Node* GrRedBlackTree<T,C>::PredecessorNode(Node* x) {
+ GrAssert(NULL != x);
+ if (NULL != x->fChildren[kLeft_Child]) {
+ x = x->fChildren[kLeft_Child];
+ while (NULL != x->fChildren[kRight_Child]) {
+ x = x->fChildren[kRight_Child];
+ }
+ return x;
+ }
+ while (NULL != x->fParent && x == x->fParent->fChildren[kLeft_Child]) {
+ x = x->fParent;
+ }
+ return x->fParent;
+}
+
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::deleteAtNode(Node* x) {
+ GrAssert(NULL != x);
+ validate();
+ --fCount;
+
+ bool hasLeft = NULL != x->fChildren[kLeft_Child];
+ bool hasRight = NULL != x->fChildren[kRight_Child];
+ Child c = hasLeft ? kLeft_Child : kRight_Child;
+
+ if (hasLeft && hasRight) {
+ // first and last can't have two children.
+ GrAssert(fFirst != x);
+ GrAssert(fLast != x);
+ // if x is an interior node then we find it's successor
+ // and swap them.
+ Node* s = x->fChildren[kRight_Child];
+ while (NULL != s->fChildren[kLeft_Child]) {
+ s = s->fChildren[kLeft_Child];
+ }
+ GrAssert(NULL != s);
+ // this might be expensive relative to swapping node ptrs around.
+ // depends on T.
+ x->fItem = s->fItem;
+ x = s;
+ c = kRight_Child;
+ } else if (NULL == x->fParent) {
+ // if x was the root we just replace it with its child and make
+ // the new root (if the tree is not empty) black.
+ GrAssert(fRoot == x);
+ fRoot = x->fChildren[c];
+ if (NULL != fRoot) {
+ fRoot->fParent = NULL;
+ fRoot->fColor = kBlack_Color;
+ if (x == fLast) {
+ GrAssert(c == kLeft_Child);
+ fLast = fRoot;
+ } else if (x == fFirst) {
+ GrAssert(c == kRight_Child);
+ fFirst = fRoot;
+ }
+ } else {
+ GrAssert(fFirst == fLast && x == fFirst);
+ fFirst = NULL;
+ fLast = NULL;
+ GrAssert(0 == fCount);
+ }
+ delete x;
+ validate();
+ return;
+ }
+
+ Child pc;
+ Node* p = x->fParent;
+ pc = p->fChildren[kLeft_Child] == x ? kLeft_Child : kRight_Child;
+
+ if (NULL == x->fChildren[c]) {
+ if (fLast == x) {
+ fLast = p;
+ GrAssert(p == PredecessorNode(x));
+ } else if (fFirst == x) {
+ fFirst = p;
+ GrAssert(p == SuccessorNode(x));
+ }
+ // x has two implicit black children.
+ Color xcolor = x->fColor;
+ p->fChildren[pc] = NULL;
+ delete x;
+ // when x is red it can be with an implicit black leaf without
+ // violating any of the red-black tree properties.
+ if (kRed_Color == xcolor) {
+ validate();
+ return;
+ }
+ // s is p's other child (x's sibling)
+ Node* s = p->fChildren[1-pc];
+
+ //s cannot be an implicit black node because the original
+ // black-height at x was >= 2 and s's black-height must equal the
+ // initial black height of x.
+ GrAssert(NULL != s);
+ GrAssert(p == s->fParent);
+
+ // assigned in loop
+ Node* sl;
+ Node* sr;
+ bool slRed;
+ bool srRed;
+
+ do {
+ // When we start this loop x may already be deleted it is/was
+ // p's child on its pc side. x's children are/were black. The
+ // first time through the loop they are implict children.
+ // On later passes we will be walking up the tree and they will
+ // be real nodes.
+ // The x side of p has a black-height that is one less than the
+ // s side. It must be rebalanced.
+ GrAssert(NULL != s);
+ GrAssert(p == s->fParent);
+ GrAssert(NULL == x || x->fParent == p);
+
+ //sl and sr are s's children, which may be implicit.
+ sl = s->fChildren[kLeft_Child];
+ sr = s->fChildren[kRight_Child];
+
+ // if the s is red we will rotate s and p, swap their colors so
+ // that x's new sibling is black
+ if (kRed_Color == s->fColor) {
+ // if s is red then it's parent must be black.
+ GrAssert(kBlack_Color == p->fColor);
+ // s's children must also be black since s is red. They can't
+ // be implicit since s is red and it's black-height is >= 2.
+ GrAssert(NULL != sl && kBlack_Color == sl->fColor);
+ GrAssert(NULL != sr && kBlack_Color == sr->fColor);
+ p->fColor = kRed_Color;
+ s->fColor = kBlack_Color;
+ if (kLeft_Child == pc) {
+ rotateLeft(p);
+ s = sl;
+ } else {
+ rotateRight(p);
+ s = sr;
+ }
+ sl = s->fChildren[kLeft_Child];
+ sr = s->fChildren[kRight_Child];
+ }
+ // x and s are now both black.
+ GrAssert(kBlack_Color == s->fColor);
+ GrAssert(kBlack_Color == x->fColor);
+ GrAssert(p == s->fParent);
+ GrAssert(p == x->fParent);
+
+ // when x is deleted its subtree will have reduced black-height.
+ slRed = (NULL != sl && kRed_Color == sl->fColor);
+ srRed = (NULL != sr && kRed_Color == sr->fColor);
+ if (!slRed && !srRed) {
+ // if s can be made red that will balance out x's removal
+ // to make both subtrees of p have the same black-height.
+ if (kBlack_Color == p->fColor) {
+ s->fColor = kRed_Color;
+ // now subtree at p has black-height of one less than
+ // p's parent's other child's subtree. We move x up to
+ // p and go through the loop again. At the top of loop
+ // we assumed x and x's children are black, which holds
+ // by above ifs.
+ // if p is the root there is no other subtree to balance
+ // against.
+ x = p;
+ p = x->fParent;
+ if (NULL == p) {
+ GrAssert(fRoot == x);
+ validate();
+ return;
+ } else {
+ pc = p->fChildren[kLeft_Child] == x ? kLeft_Child :
+ kRight_Child;
+
+ }
+ s = p->fChildren[1-pc];
+ GrAssert(NULL != s);
+ GrAssert(p == s->fParent);
+ continue;
+ } else if (kRed_Color == p->fColor) {
+ // we can make p black and s red. This balance out p's
+ // two subtrees and keep the same black-height as it was
+ // before the delete.
+ s->fColor = kRed_Color;
+ p->fColor = kBlack_Color;
+ validate();
+ return;
+ }
+ }
+ break;
+ } while (true);
+ // if we made it here one or both of sl and sr is red.
+ // s and x are black. We make sure that a red child is on
+ // the same side of s as s is of p.
+ GrAssert(slRed || srRed);
+ if (kLeft_Child == pc && !srRed) {
+ s->fColor = kRed_Color;
+ sl->fColor = kBlack_Color;
+ rotateRight(s);
+ sr = s;
+ s = sl;
+ //sl = s->fChildren[kLeft_Child]; don't need this
+ } else if (kRight_Child == pc && !slRed) {
+ s->fColor = kRed_Color;
+ sr->fColor = kBlack_Color;
+ rotateLeft(s);
+ sl = s;
+ s = sr;
+ //sr = s->fChildren[kRight_Child]; don't need this
+ }
+ // now p is either red or black, x and s are red and s's 1-pc
+ // child is red.
+ // We rotate p towards x, pulling s up to replace p. We make
+ // p be black and s takes p's old color.
+ // Whether p was red or black, we've increased its pc subtree
+ // rooted at x by 1 (balancing the imbalance at the start) and
+ // we've also its subtree rooted at s's black-height by 1. This
+ // can be balanced by making s's red child be black.
+ s->fColor = p->fColor;
+ p->fColor = kBlack_Color;
+ if (kLeft_Child == pc) {
+ GrAssert(NULL != sr && kRed_Color == sr->fColor);
+ sr->fColor = kBlack_Color;
+ rotateLeft(p);
+ } else {
+ GrAssert(NULL != sl && kRed_Color == sl->fColor);
+ sl->fColor = kBlack_Color;
+ rotateRight(p);
+ }
+ }
+ else {
+ // x has exactly one implicit black child. x cannot be red.
+ // Proof by contradiction: Assume X is red. Let c0 be x's implicit
+ // child and c1 be its non-implicit child. c1 must be black because
+ // red nodes always have two black children. Then the two subtrees
+ // of x rooted at c0 and c1 will have different black-heights.
+ GrAssert(kBlack_Color == x->fColor);
+ // So we know x is black and has one implicit black child, c0. c1
+ // must be red, otherwise the subtree at c1 will have a different
+ // black-height than the subtree rooted at c0.
+ GrAssert(kRed_Color == x->fChildren[c]->fColor);
+ // replace x with c1, making c1 black, preserves all red-black tree
+ // props.
+ Node* c1 = x->fChildren[c];
+ if (x == fFirst) {
+ GrAssert(c == kRight_Child);
+ fFirst = c1;
+ while (NULL != fFirst->fChildren[kLeft_Child]) {
+ fFirst = fFirst->fChildren[kLeft_Child];
+ }
+ GrAssert(fFirst == SuccessorNode(x));
+ } else if (x == fLast) {
+ GrAssert(c == kLeft_Child);
+ fLast = c1;
+ while (NULL != fLast->fChildren[kRight_Child]) {
+ fLast = fLast->fChildren[kRight_Child];
+ }
+ GrAssert(fLast == PredecessorNode(x));
+ }
+ c1->fParent = p;
+ p->fChildren[pc] = c1;
+ c1->fColor = kBlack_Color;
+ delete x;
+ validate();
+ }
+ validate();
+}
+
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::RecursiveDelete(Node* x) {
+ if (NULL != x) {
+ RecursiveDelete(x->fChildren[kLeft_Child]);
+ RecursiveDelete(x->fChildren[kRight_Child]);
+ delete x;
+ }
+}
+
+#if GR_DEBUG
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::validate() const {
+ if (fCount) {
+ GrAssert(NULL == fRoot->fParent);
+ GrAssert(NULL != fFirst);
+ GrAssert(NULL != fLast);
+
+ GrAssert(kBlack_Color == fRoot->fColor);
+ if (1 == fCount) {
+ GrAssert(fFirst == fRoot);
+ GrAssert(fLast == fRoot);
+ GrAssert(0 == fRoot->fChildren[kLeft_Child]);
+ GrAssert(0 == fRoot->fChildren[kRight_Child]);
+ }
+ } else {
+ GrAssert(NULL == fRoot);
+ GrAssert(NULL == fFirst);
+ GrAssert(NULL == fLast);
+ }
+#if DEEP_VALIDATE
+ int bh;
+ int count = checkNode(fRoot, &bh);
+ GrAssert(count == fCount);
+#endif
+}
+
+template <typename T, typename C>
+int GrRedBlackTree<T,C>::checkNode(Node* n, int* bh) const {
+ if (NULL != n) {
+ GrAssert(validateChildRelations(n, false));
+ if (kBlack_Color == n->fColor) {
+ *bh += 1;
+ }
+ GrAssert(!fComp(n->fItem, fFirst->fItem));
+ GrAssert(!fComp(fLast->fItem, n->fItem));
+ int leftBh = *bh;
+ int rightBh = *bh;
+ int cl = checkNode(n->fChildren[kLeft_Child], &leftBh);
+ int cr = checkNode(n->fChildren[kRight_Child], &rightBh);
+ GrAssert(leftBh == rightBh);
+ *bh = leftBh;
+ return 1 + cl + cr;
+ }
+ return 0;
+}
+
+template <typename T, typename C>
+bool GrRedBlackTree<T,C>::validateChildRelations(const Node* n,
+ bool allowRedRed) const {
+ if (NULL != n) {
+ if (NULL != n->fChildren[kLeft_Child] ||
+ NULL != n->fChildren[kRight_Child]) {
+ if (n->fChildren[kLeft_Child] == n->fChildren[kRight_Child]) {
+ return validateChildRelationsFailed();
+ }
+ if (n->fChildren[kLeft_Child] == n->fParent &&
+ NULL != n->fParent) {
+ return validateChildRelationsFailed();
+ }
+ if (n->fChildren[kRight_Child] == n->fParent &&
+ NULL != n->fParent) {
+ return validateChildRelationsFailed();
+ }
+ if (NULL != n->fChildren[kLeft_Child]) {
+ if (!allowRedRed &&
+ kRed_Color == n->fChildren[kLeft_Child]->fColor &&
+ kRed_Color == n->fColor) {
+ return validateChildRelationsFailed();
+ }
+ if (n->fChildren[kLeft_Child]->fParent != n) {
+ return validateChildRelationsFailed();
+ }
+ if (!(fComp(n->fChildren[kLeft_Child]->fItem, n->fItem) ||
+ (!fComp(n->fChildren[kLeft_Child]->fItem, n->fItem) &&
+ !fComp(n->fItem, n->fChildren[kLeft_Child]->fItem)))) {
+ return validateChildRelationsFailed();
+ }
+ }
+ if (NULL != n->fChildren[kRight_Child]) {
+ if (!allowRedRed &&
+ kRed_Color == n->fChildren[kRight_Child]->fColor &&
+ kRed_Color == n->fColor) {
+ return validateChildRelationsFailed();
+ }
+ if (n->fChildren[kRight_Child]->fParent != n) {
+ return validateChildRelationsFailed();
+ }
+ if (!(fComp(n->fItem, n->fChildren[kRight_Child]->fItem) ||
+ (!fComp(n->fChildren[kRight_Child]->fItem, n->fItem) &&
+ !fComp(n->fItem, n->fChildren[kRight_Child]->fItem)))) {
+ return validateChildRelationsFailed();
+ }
+ }
+ }
+ }
+ return true;
+}
+#endif
+
+#include "GrRandom.h"
+
+template <typename T, typename C>
+void GrRedBlackTree<T,C>::UnitTest() {
+ GrRedBlackTree<int> tree;
+ typedef GrRedBlackTree<int>::Iter iter;
+
+ GrRandom r;
+
+ int count[100] = {0};
+ // add 10K ints
+ for (int i = 0; i < 10000; ++i) {
+ int x = r.nextU()%100;
+ Iter xi = tree.insert(x);
+ GrAssert(*xi == x);
+ ++count[x];
+ }
+
+ tree.insert(0);
+ ++count[0];
+ tree.insert(99);
+ ++count[99];
+ GrAssert(*tree.begin() == 0);
+ GrAssert(*tree.last() == 99);
+ GrAssert(--(++tree.begin()) == tree.begin());
+ GrAssert(--tree.end() == tree.last());
+ GrAssert(tree.count() == 10002);
+
+ int c = 0;
+ // check that we iterate through the correct number of
+ // elements and they are properly sorted.
+ for (Iter a = tree.begin(); tree.end() != a; ++a) {
+ Iter b = a;
+ ++b;
+ ++c;
+ GrAssert(b == tree.end() || *a <= *b);
+ }
+ GrAssert(c == tree.count());
+
+ // check that the tree reports the correct number of each int
+ // and that we can iterate through them correctly both forward
+ // and backward.
+ for (int i = 0; i < 100; ++i) {
+ int c;
+ c = tree.countOf(i);
+ GrAssert(c == count[i]);
+ c = 0;
+ Iter iter = tree.findFirst(i);
+ while (iter != tree.end() && *iter == i) {
+ ++c;
+ ++iter;
+ }
+ GrAssert(count[i] == c);
+ c = 0;
+ iter = tree.findLast(i);
+ if (iter != tree.end()) {
+ do {
+ if (*iter == i) {
+ ++c;
+ } else {
+ break;
+ }
+ if (iter != tree.begin()) {
+ --iter;
+ } else {
+ break;
+ }
+ } while (true);
+ }
+ GrAssert(c == count[i]);
+ }
+ // remove all the ints between 25 and 74. Randomly chose to remove
+ // the first, last, or any entry for each.
+ for (int i = 25; i < 75; ++i) {
+ while (0 != tree.countOf(i)) {
+ --count[i];
+ int x = r.nextU() % 3;
+ Iter iter;
+ switch (x) {
+ case 0:
+ iter = tree.findFirst(i);
+ break;
+ case 1:
+ iter = tree.findLast(i);
+ break;
+ case 2:
+ default:
+ iter = tree.find(i);
+ break;
+ }
+ tree.remove(iter);
+ }
+ GrAssert(0 == count[i]);
+ GrAssert(tree.findFirst(i) == tree.end());
+ GrAssert(tree.findLast(i) == tree.end());
+ GrAssert(tree.find(i) == tree.end());
+ }
+ // remove all of the 0 entries. (tests removing begin())
+ GrAssert(*tree.begin() == 0);
+ GrAssert(*(--tree.end()) == 99);
+ while (0 != tree.countOf(0)) {
+ --count[0];
+ tree.remove(tree.find(0));
+ }
+ GrAssert(0 == count[0]);
+ GrAssert(tree.findFirst(0) == tree.end());
+ GrAssert(tree.findLast(0) == tree.end());
+ GrAssert(tree.find(0) == tree.end());
+ GrAssert(0 < *tree.begin());
+
+ // remove all the 99 entries (tests removing last()).
+ while (0 != tree.countOf(99)) {
+ --count[99];
+ tree.remove(tree.find(99));
+ }
+ GrAssert(0 == count[99]);
+ GrAssert(tree.findFirst(99) == tree.end());
+ GrAssert(tree.findLast(99) == tree.end());
+ GrAssert(tree.find(99) == tree.end());
+ GrAssert(99 > *(--tree.end()));
+ GrAssert(tree.last() == --tree.end());
+
+ // Make sure iteration still goes through correct number of entries
+ // and is still sorted correctly.
+ c = 0;
+ for (Iter a = tree.begin(); tree.end() != a; ++a) {
+ Iter b = a;
+ ++b;
+ ++c;
+ GrAssert(b == tree.end() || *a <= *b);
+ }
+ GrAssert(c == tree.count());
+
+ // repeat check that correct number of each entry is in the tree
+ // and iterates correctly both forward and backward.
+ for (int i = 0; i < 100; ++i) {
+ GrAssert(tree.countOf(i) == count[i]);
+ int c = 0;
+ Iter iter = tree.findFirst(i);
+ while (iter != tree.end() && *iter == i) {
+ ++c;
+ ++iter;
+ }
+ GrAssert(count[i] == c);
+ c = 0;
+ iter = tree.findLast(i);
+ if (iter != tree.end()) {
+ do {
+ if (*iter == i) {
+ ++c;
+ } else {
+ break;
+ }
+ if (iter != tree.begin()) {
+ --iter;
+ } else {
+ break;
+ }
+ } while (true);
+ }
+ GrAssert(count[i] == c);
+ }
+
+ // remove all entries
+ while (!tree.empty()) {
+ tree.remove(tree.begin());
+ }
+
+ // test reset on empty tree.
+ tree.reset();
+}
+
+#endif