Ignore:
Timestamp:
2018-07-05T21:41:23Z (7 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
27f1bc0
Parents:
6175b78
git-author:
Dzejrou <dzejrou@…> (2018-05-13 22:57:14)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:23)
Message:

cpp: revamped rbtree so that it now stores equivalent keys in a list

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/cpp/include/internal/rbtree.hpp

    r6175b78 r73e3791  
    4141        class KeyComp, class Alloc, class Size,
    4242        class Iterator, class ConstIterator,
    43         class Policy
     43        class Policy, class Node
    4444    >
    4545    class rbtree
     
    5353            using key_extract    = KeyExtractor;
    5454
    55             using iterator             = Iterator;
    56             using const_iterator       = ConstIterator;
     55            using iterator       = Iterator;
     56            using const_iterator = ConstIterator;
    5757
    5858            using reverse_iterator       = std::reverse_iterator<iterator>;
    5959            using const_reverse_iterator = std::reverse_iterator<const_iterator>;
    6060
    61             using node_type = rbtree_node<value_type>;
     61            using node_type = Node;
    6262
    6363            rbtree(const key_compare& kcmp = key_compare{})
     
    100100            bool empty() const noexcept
    101101            {
    102                 return size_;
     102                return size_ == 0U;
    103103            }
    104104
     
    202202
    203203                node = delete_node(node);
    204                 return iterator{const_cast<node_type*>(node), node == nullptr};
     204                if (!node)
     205                    return iterator{find_largest_(), true};
     206                else
     207                    return iterator{const_cast<node_type*>(node), false};
    205208            }
    206209
     
    322325                    parent = current;
    323326                    if (key_compare_(key, key_extractor_(current->value)))
    324                         current = current->left;
     327                        current = current->left();
    325328                    else if (key_compare_(key_extractor_(current->value), key))
    326                         current = current->right;
     329                        current = current->right();
    327330                    else
    328331                        return current;
     
    337340                if (!node)
    338341                    return nullptr;
     342                if (auto tmp = node->get_node_for_deletion(); tmp != nullptr)
     343                {
     344                    /**
     345                     * This will kick in multi containers,
     346                     * we popped one node from a list of nodes
     347                     * with equivalent keys and we can delete it
     348                     * and return the original as it is still
     349                     * in place.
     350                     */
     351                    delete tmp;
     352
     353                    return node;
     354                }
    339355
    340356                --size_;
    341357
     358                if (node == root_)
     359                {
     360                    delete node;
     361                    root_ = nullptr;
     362
     363                    return nullptr;
     364                }
     365
    342366                auto succ = node->successor();
    343                 if (node->left && node->right)
     367                if (node->left() && node->right())
    344368                {
    345369                    node->swap(succ);
    346 
    347                     // Succ has at most one child.
    348                     delete_node(succ);
    349 
    350                     return node;
    351                 }
    352 
    353                 auto child = node->right ? node->right : node->left;
     370                    if (succ && !succ->parent())
     371                        root_ = succ;
     372
     373                    // Node now has at most one child.
     374                    // Also: If succ was nullptr, the swap
     375                    //       didn't do anything and we can
     376                    //       safely delete node.
     377                    return delete_node(node);
     378                }
     379
     380                auto child = node->right() ? node->right() : node->left();
    354381                if (!child)
    355382                {
     
    362389                {
    363390                    // Replace with the child.
    364                     child->parent = node->parent;
     391                    child->parent(node->parent());
    365392                    if (node->is_left_child())
    366                         child->parent->left = child;
     393                        child->parent()->left(child);
    367394                    else if (node->is_right_child())
    368                         child->parent->right = child;
     395                        child->parent()->right(child);
    369396
    370397                    // Repair if needed.
     
    380407            void insert_node(node_type* node, node_type* parent)
    381408            {
    382                 if (!node)
    383                     return;
    384 
    385                 ++size_;
    386                 if (!parent)
    387                 {
    388                     node->color = rbcolor::black;
    389                     root_ = node;
    390                 }
    391                 else
    392                 {
    393                     if (keys_comp(get_key(node->value), parent->value))
    394                         parent->add_left_child(node);
    395                     else
    396                         parent->add_right_child(node);
    397 
    398                     repair_after_insert_(node);
    399                     update_root_(node);
    400                 }
     409                Policy::insert(*this, node, parent);
    401410            }
    402411
     
    413422                {
    414423                    if (key_compare_(key, key_extractor_(current->value)))
    415                         current = current->left;
     424                        current = current->left();
    416425                    else if (key_compare_(key_extractor_(current->value), key))
    417                         current = current->right;
     426                        current = current->right();
    418427                    else
    419428                        return current;
     
    445454
    446455                root_ = const_cast<node_type*>(node);
    447                 while (root_->parent)
    448                     root_ = root_->parent;
     456                while (root_->parent())
     457                    root_ = root_->parent();
    449458            }
    450459
Note: See TracChangeset for help on using the changeset viewer.