void rbtree_node::remove(rbtree_node** root) { rbtree_node* node = this; rbtree_node* child; rbtree_node* parent; int color; // // Satisfy Precondition: node has at most one non-null child // if (!node->left) { child = node->right; } else if (!node->right) { child = node->left; } else { rbtree_node* old = node; // // Locate a node that satisfies the precondition to swap with the node to be removed // node = node->right; while (node->left) node = node->left; // // Node satisfies precondition // child = node->right; // // Swap nodes (swap <-> (node <-> child)) // parent = node->parent(); color = node->color(); if (child) child->parent(parent); if (parent == old) { parent->right = child; parent = node; } else { parent->left = child; } node->_parent = old->_parent; node->left = old->left; node->right = old->right; if (old->parent()) { UL_ASSERT((old->parent()->right == old) || (old->parent()->left == old)); if (old->parent()->left == old) { old->parent()->left = node; } else { old->parent()->right = node; } } else { *root = node; } old->left->parent(node); if (old->right) old->right->parent(node); goto rm_color; } // // Replace Node with Child // parent = node->parent(); color = node->color(); if (child) { child->parent(parent); } if (parent) { UL_ASSERT((parent->right == node) || (parent->left == node)); if (parent->left == node) { parent->left = child; } else { parent->right = child; } } else { *root = child; } rm_color: // // Adjust Red-Black tree properties if node is black // if (color == black) { remove_color(child, parent, root); } UL_ASSERT(!*root || (*root)->color() == black); // // Bug prevention // this->_parent = 0; this->left = nullptr; this->right = nullptr; }
static void remove_color(ul::rbtree_node* node, ul::rbtree_node* parent, ul::rbtree_node** root) { ul::rbtree_node* sibling; // // Case 1 // if (node && node->color() == ul::rbtree_node::red) { node->color(ul::rbtree_node::black); // // Cases: 2, 3, 4, 5, 6 // // To reduce a number of repeated comparisions for the sibling, the code was duplicated and, // as a result, dead code paths were removed. // } else while (parent) { UL_ASSERT((node == parent->left) || (node == parent->right)); if (node == parent->left) { sibling = parent->right; if (sibling->color() == ul::rbtree_node::red) { parent->color(ul::rbtree_node::red); sibling->color(ul::rbtree_node::black); rotate_left(parent, root); sibling = parent->right; } if (sibling->color() == ul::rbtree_node::black) { if (!sibling->right || sibling->right->color() == ul::rbtree_node::black) { if (!sibling->left || sibling->left->color() == ul::rbtree_node::black) { if (parent->color() == ul::rbtree_node::black) { sibling->color(ul::rbtree_node::red); node = parent; parent = node->parent(); continue; } else { sibling->color(ul::rbtree_node::red); parent->color(ul::rbtree_node::black); break; } } else { sibling->color(ul::rbtree_node::red); sibling->left->color(ul::rbtree_node::black); rotate_right(sibling, root); sibling = parent->right; } } sibling->color(parent->color()); parent->color(ul::rbtree_node::black); if (sibling->right) sibling->right->color(ul::rbtree_node::black); rotate_left(parent, root); } } else { sibling = parent->left; if (sibling->color() == ul::rbtree_node::red) { parent->color(ul::rbtree_node::red); sibling->color(ul::rbtree_node::black); rotate_right(parent, root); sibling = parent->left; } if (sibling->color() == ul::rbtree_node::black) { if (!sibling->left || sibling->left->color() == ul::rbtree_node::black) { if (!sibling->right || sibling->right->color() == ul::rbtree_node::black) { if (parent->color() == ul::rbtree_node::black) { sibling->color(ul::rbtree_node::red); node = parent; parent = node->parent(); continue; } else { sibling->color(ul::rbtree_node::red); parent->color(ul::rbtree_node::black); break; } } else { sibling->color(ul::rbtree_node::red); sibling->right->color(ul::rbtree_node::black); rotate_left(sibling, root); sibling = parent->left; } } sibling->color(parent->color()); parent->color(ul::rbtree_node::black); if (sibling->left) sibling->left->color(ul::rbtree_node::black); rotate_right(parent, root); } } break; } }
ViewableObjectFactory* HistoryManager::GetFactory(ID id) { UL_ASSERT(data.find(id) != data.end()); UL_ASSERT(data[id].factory != NULL); return data[id].factory; }
int HistoryManager::GetModifiedTime(ID id) { UL_ASSERT(data.find(id) != data.end()); return data[id].modifiedTime; }
std::string HistoryManager::GetValue(ID id) { UL_ASSERT(data.find(id) != data.end()); return data[id].value; }
void HistoryManager::SetFactory(ID id, ViewableObjectFactory* factory) { UL_ASSERT(data.find(id) != data.end()); data[id].factory = factory; }
void HistoryManager::SetValue(ID id, std::string value) { UL_ASSERT(data.find(id) != data.end()); data[id].value = value; }
void HistoryManager::SetHistory(ID id, std::set<ValueID> history) { UL_ASSERT(data.find(id) != data.end()); data[id].history = history; data[id].modifiedTime = time; }
void HistoryManager::SetVisible(ID id, bool visible) { UL_ASSERT(data.find(id) != data.end()); data[id].visible = visible; }
bool HistoryManager::IsVisible(ID id) { UL_ASSERT(data.find(id) != data.end()); return data[id].visible; }
std::set<ValueID> HistoryManager::GetHistory(ID id) { UL_ASSERT(data.find(id) != data.end()); return data[id].history; }