Alien-boost-mini
view release on metacpan or search on metacpan
include/boost/intrusive/bstree_algorithms.hpp view on Meta::CPAN
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If the comparison throws.
template<class NodePtrCompare>
BOOST_INTRUSIVE_FORCEINLINE static void transfer_equal
(const node_ptr & header1, NodePtrCompare comp, const node_ptr &header2, const node_ptr & z)
{
data_for_rebalance ignored;
transfer_equal(header1, comp, header2, z, ignored);
}
//! <b>Requires</b>: node is a tree node but not the header.
//!
//! <b>Effects</b>: Unlinks the node and rebalances the tree.
//!
//! <b>Complexity</b>: Average complexity is constant time.
//!
//! <b>Throws</b>: Nothing.
static void unlink(const node_ptr & node)
{
node_ptr x = NodeTraits::get_parent(node);
if(x){
while(!base_type::is_header(x))
x = NodeTraits::get_parent(x);
erase(x, node);
}
}
//! <b>Requires</b>: header must be the header of a tree.
//!
//! <b>Effects</b>: Rebalances the tree.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear.
static void rebalance(const node_ptr & header)
{
node_ptr root = NodeTraits::get_parent(header);
if(root){
rebalance_subtree(root);
}
}
//! <b>Requires</b>: old_root is a node of a tree. It shall not be null.
//!
//! <b>Effects</b>: Rebalances the subtree rooted at old_root.
//!
//! <b>Returns</b>: The new root of the subtree.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear.
static node_ptr rebalance_subtree(const node_ptr & old_root)
{
//Taken from:
//"Tree rebalancing in optimal time and space"
//Quentin F. Stout and Bette L. Warren
//To avoid irregularities in the algorithm (old_root can be a
//left or right child or even the root of the tree) just put the
//root as the right child of its parent. Before doing this backup
//information to restore the original relationship after
//the algorithm is applied.
node_ptr super_root = NodeTraits::get_parent(old_root);
BOOST_INTRUSIVE_INVARIANT_ASSERT(super_root);
//Get root info
node_ptr super_root_right_backup = NodeTraits::get_right(super_root);
bool super_root_is_header = NodeTraits::get_parent(super_root) == old_root;
bool old_root_is_right = is_right_child(old_root);
NodeTraits::set_right(super_root, old_root);
std::size_t size;
subtree_to_vine(super_root, size);
vine_to_subtree(super_root, size);
node_ptr new_root = NodeTraits::get_right(super_root);
//Recover root
if(super_root_is_header){
NodeTraits::set_right(super_root, super_root_right_backup);
NodeTraits::set_parent(super_root, new_root);
}
else if(old_root_is_right){
NodeTraits::set_right(super_root, new_root);
}
else{
NodeTraits::set_right(super_root, super_root_right_backup);
NodeTraits::set_left(super_root, new_root);
}
return new_root;
}
//! <b>Effects</b>: Asserts the integrity of the container with additional checks provided by the user.
//!
//! <b>Requires</b>: header must be the header of a tree.
//!
//! <b>Complexity</b>: Linear time.
//!
//! <b>Note</b>: The method might not have effect when asserts are turned off (e.g., with NDEBUG).
//! Experimental function, interface might change in future versions.
template<class Checker>
static void check(const const_node_ptr& header, Checker checker, typename Checker::return_type& checker_return)
{
const_node_ptr root_node_ptr = NodeTraits::get_parent(header);
if (!root_node_ptr){
// check left&right header pointers
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_left(header) == header);
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_right(header) == header);
}
else{
// check parent pointer of root node
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_parent(root_node_ptr) == header);
// check subtree from root
check_subtree(root_node_ptr, checker, checker_return);
// check left&right header pointers
const_node_ptr p = root_node_ptr;
while (NodeTraits::get_left(p)) { p = NodeTraits::get_left(p); }
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_left(header) == p);
p = root_node_ptr;
while (NodeTraits::get_right(p)) { p = NodeTraits::get_right(p); }
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_right(header) == p);
}
}
protected:
template<class NodePtrCompare>
static bool transfer_unique
(const node_ptr & header1, NodePtrCompare comp, const node_ptr &header2, const node_ptr & z, data_for_rebalance &info)
{
insert_commit_data commit_data;
bool const transferable = insert_unique_check(header1, z, comp, commit_data).second;
if(transferable){
erase(header2, z, info);
insert_commit(header1, z, commit_data);
}
return transferable;
}
template<class NodePtrCompare>
static void transfer_equal
(const node_ptr & header1, NodePtrCompare comp, const node_ptr &header2, const node_ptr & z, data_for_rebalance &info)
{
insert_commit_data commit_data;
insert_equal_upper_bound_check(header1, z, comp, commit_data);
erase(header2, z, info);
insert_commit(header1, z, commit_data);
( run in 0.469 second using v1.01-cache-2.11-cpan-9bca49b1385 )