Commit be46391e authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

[2090] Limit number of calls to get*()

If they are called multiple times, it is stored into a variable.
Segfaults, needs a fix (again).
parent 118ceb3b
......@@ -419,8 +419,9 @@ RBNode<T>::abstractSuccessor(typename RBNode<T>::RBNodePtr RBNode<T>::*left,
// subtree.
if (current->*right != RBNode<T>::NULL_NODE()) {
current = (current->*right).get();
while (current->*left != RBNode<T>::NULL_NODE()) {
current = (current->*left).get();
const RBNode<T>* left_n;
while ((left_n = (current->*left).get()) != RBNode<T>::NULL_NODE()) {
current = left_n;
}
return (current);
}
......@@ -1090,9 +1091,11 @@ RBTree<T>::deleteHelper(RBNode<T>* root) {
RBNode<T>* node = root;
while (root->getLeft() != NULLNODE || root->getRight() != NULLNODE) {
while (node->getLeft() != NULLNODE || node->getRight() != NULLNODE) {
node = (node->getLeft() != NULLNODE) ? node->getLeft() :
node->getRight();
RBNode<T>* left(NULLNODE);
RBNode<T>* right(NULLNODE);
while ((left = node->getLeft()) != NULLNODE ||
(right = node->getRight()) != NULLNODE) {
node = (left != NULLNODE) ? left : right;
}
RBNode<T>* parent = node->getParent();
......@@ -1193,8 +1196,9 @@ RBTree<T>::nextNode(RBTreeNodeChain<T>& node_path) const {
const RBNode<T>* node = node_path.top();
// if node has sub domain, the next domain is the smallest
// domain in sub domain tree
if (node->getDown() != NULLNODE) {
const RBNode<T>* left_most = node->getDown();
const RBNode<T>* down = node->getDown();
if (down != NULLNODE) {
const RBNode<T>* left_most = down;
while (left_most->left_ != NULLNODE) {
left_most = left_most->getLeft();
}
......@@ -1265,11 +1269,12 @@ RBTree<T>::previousNode(RBTreeNodeChain<T>& node_path) const {
node_path.push(current);
// Go a level down and as much right there as possible
current = current->getDown();
while (current->getRight() != NULLNODE) {
const RBNode<T>* right(NULLNODE);
while ((right = current->getRight()) != NULLNODE) {
// A small trick. The current may be NULLNODE, but
// such node has the right_ pointer and it is equal
// to NULLNODE.
current = current->getRight();
current = right;
}
}
// Now, the one on top of the path is the one we want. We
......@@ -1343,12 +1348,14 @@ RBTree<T>::previousNode(RBTreeNodeChain<T>& node_path) const {
node_path.push(node);
// Try going as deep as possible, keeping on the right side of the trees
while (node->getDown() != NULLNODE) {
const RBNode<T>* down;
while ((down = node->getDown()) != NULLNODE) {
// Move to the tree below
node = node->getDown();
node = down;
// And get as much to the right of the tree as possible
while (node->getRight() != NULLNODE) {
node = node->getRight();
const RBNode<T>* right(NULLNODE);
while ((right = node->getRight()) != NULLNODE) {
node = right;
}
// Now, we found the right-most node in the sub-tree, we need to
// include it in the path
......@@ -1470,39 +1477,43 @@ RBTree<T>::insertRebalance(typename RBNode<T>::RBNodePtr* root,
RBNode<T>* node)
{
RBNode<T>* uncle;
while (node != *root && node->getParent()->color_ == RBNode<T>::RED) {
if (node->getParent() == node->getParent()->getParent()->getLeft()) {
uncle = node->getParent()->getParent()->getRight();
RBNode<T>* parent;
while (node != *root &&
(parent = node->getParent())->color_ == RBNode<T>::RED) {
if (parent == parent->getParent()->getLeft()) {
uncle = parent->getParent()->getRight();
if (uncle->color_ == RBNode<T>::RED) {
node->getParent()->color_ = RBNode<T>::BLACK;
parent->color_ = RBNode<T>::BLACK;
uncle->color_ = RBNode<T>::BLACK;
node->getParent()->getParent()->color_ = RBNode<T>::RED;
node = node->getParent()->getParent();
parent->getParent()->color_ = RBNode<T>::RED;
node = parent->getParent();
} else {
if (node == node->getParent()->getRight()) {
node = node->getParent();
if (node == parent->getRight()) {
node = parent;
parent = node->getParent();
leftRotate(root, node);
}
node->getParent()->color_ = RBNode<T>::BLACK;
node->getParent()->getParent()->color_ = RBNode<T>::RED;
rightRotate(root, node->getParent()->getParent());
parent->color_ = RBNode<T>::BLACK;
parent->getParent()->color_ = RBNode<T>::RED;
rightRotate(root, parent->getParent());
}
} else {
uncle = node->getParent()->getParent()->getLeft();
uncle = parent->getParent()->getLeft();
if (uncle->color_ == RBNode<T>::RED) {
node->getParent()->color_ = RBNode<T>::BLACK;
parent->color_ = RBNode<T>::BLACK;
uncle->color_ = RBNode<T>::BLACK;
node->getParent()->getParent()->color_ = RBNode<T>::RED;
node = node->getParent()->getParent();
parent->getParent()->color_ = RBNode<T>::RED;
node = parent->getParent();
} else {
if (node == node->getParent()->getLeft()) {
node = node->getParent();
if (node == parent->getLeft()) {
node = parent;
parent = node->getParent();
rightRotate(root, node);
}
node->getParent()->color_ = RBNode<T>::BLACK;
node->getParent()->getParent()->color_ = RBNode<T>::RED;
leftRotate(root, node->getParent()->getParent());
parent->color_ = RBNode<T>::BLACK;
parent->getParent()->color_ = RBNode<T>::RED;
leftRotate(root, parent->getParent());
}
}
}
......@@ -1515,17 +1526,19 @@ template <typename T>
RBNode<T>*
RBTree<T>::leftRotate(typename RBNode<T>::RBNodePtr* root, RBNode<T>* node) {
RBNode<T>* right = node->getRight();
node->right_ = right->getLeft();
if (right->getLeft() != NULLNODE)
right->getLeft()->parent_ = node;
RBNode<T>* rleft = right->getLeft();
node->right_ = rleft;
if (rleft != NULLNODE)
rleft->parent_ = node;
right->parent_ = node->getParent();
RBNode<T>* parent = node->getParent();
right->parent_ = parent;
if (node->getParent() != NULLNODE) {
if (node == node->getParent()->getLeft()) {
node->getParent()->left_ = right;
if (parent != NULLNODE) {
if (node == parent->getLeft()) {
parent->left_ = right;
} else {
node->getParent()->right_ = right;
parent->right_ = right;
}
} else {
*root = right;
......@@ -1540,17 +1553,19 @@ template <typename T>
RBNode<T>*
RBTree<T>::rightRotate(typename RBNode<T>::RBNodePtr* root, RBNode<T>* node) {
RBNode<T>* left = node->getLeft();
node->left_ = left->getRight();
if (left->getRight() != NULLNODE)
left->getRight()->parent_ = node;
RBNode<T>* lright = left->getRight();
node->left_ = lright;
if (lright != NULLNODE)
lright->parent_ = node;
left->parent_ = node->getParent();
RBNode<T>* parent = node->getParent();
left->parent_ = parent;
if (node->parent_ != NULLNODE) {
if (node == node->getParent()->getRight()) {
node->getParent()->right_ = left;
if (node == parent->getRight()) {
parent->right_ = left;
} else {
node->getParent()->left_ = left;
parent->left_ = left;
}
} else {
*root = left;
......@@ -1585,10 +1600,11 @@ RBTree<T>::dumpTreeHelper(std::ostream& os, const RBNode<T>* node,
<< ((node->color_ == RBNode<T>::BLACK) ? "black" : "red") << ")";
os << ((node->isEmpty()) ? "[invisible] \n" : "\n");
if (node->getDown() != NULLNODE) {
const RBNode<T>* down = node->getDown();
if (down != NULLNODE) {
indent(os, depth + 1);
os << "begin down from " << node->name_.toText() << "\n";
dumpTreeHelper(os, node->getDown(), depth + 1);
dumpTreeHelper(os, down, depth + 1);
indent(os, depth + 1);
os << "end down from " << node->name_.toText() << "\n";
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment