From 16af3d59df872ca2fbbbde20785b532a3ab71fac Mon Sep 17 00:00:00 2001 From: Matei David Date: Wed, 12 Mar 2014 17:58:19 -0400 Subject: [PATCH 1/2] augmentation hooks now inside bstree --- include/boost/intrusive/bstree_algorithms.hpp | 62 +++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/include/boost/intrusive/bstree_algorithms.hpp b/include/boost/intrusive/bstree_algorithms.hpp index d155d6d9..258034d5 100644 --- a/include/boost/intrusive/bstree_algorithms.hpp +++ b/include/boost/intrusive/bstree_algorithms.hpp @@ -19,12 +19,56 @@ #include #include #include +#include namespace boost { namespace intrusive { /// @cond +namespace detail { + +template +struct extra_data_manager_generator +{ + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + static void clone_extra_data(node_ptr, const_node_ptr) {} + static void recompute_extra_data(node_ptr) {} + static void recompute_extra_data(node_ptr, node_ptr) {} +}; + +template +struct extra_data_manager_generator< NodeTraits, true > +{ + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + static void clone_extra_data(node_ptr dest, const_node_ptr src) { NodeTraits::clone_extra_data(dest, src); } + static void recompute_extra_data(node_ptr node) { NodeTraits::recompute_extra_data(node); } + static void recompute_extra_data(node_ptr start_node, node_ptr end_node) + { + for (node_ptr node = start_node; + node != end_node; + node = NodeTraits::get_parent(node)) + { + recompute_extra_data(node); + } + } +}; + +BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(clone_extra_data) +BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(recompute_extra_data) + +template +struct extra_data_manager + : extra_data_manager_generator< + NodeTraits, + has_static_member_function_clone_extra_data::value + and has_static_member_function_recompute_extra_data::value + > {}; + +} // namespace detail + //! This type is the information that will be filled by insert_unique_check template struct insert_commit_data_t @@ -150,6 +194,8 @@ class bstree_algorithms const node_ptr subtree_; }; + typedef detail::extra_data_manager extra_data_manager; + /// @endcond public: @@ -411,6 +457,9 @@ class bstree_algorithms NodeTraits::set_right(temp, node2); } } + //recompute extra data for both + extra_data_manager::recompute_extra_data(node1, header2); + extra_data_manager::recompute_extra_data(node2, header1); } //! Requires: node_to_be_replaced must be inserted in a tree @@ -489,6 +538,8 @@ class bstree_algorithms NodeTraits::set_right(temp, new_node); } } + //recompute extra data + extra_data_manager::recompute_extra_data(new_node, header); } //! Requires: 'node' is a node from the tree except the header. @@ -1523,6 +1574,8 @@ class bstree_algorithms //If z had 2 children, x_parent is the new parent of y (z_parent) BOOST_ASSERT(!x || NodeTraits::get_parent(x) == x_parent); info.x_parent = x_parent; + //recompute data upwards of lowest node touched + extra_data_manager::recompute_extra_data(x_parent, header); } //! Requires: node is a node of the tree but it's not the header. @@ -1728,6 +1781,8 @@ class bstree_algorithms NodeTraits::set_parent(new_node, parent_node); NodeTraits::set_right(new_node, node_ptr()); NodeTraits::set_left(new_node, node_ptr()); + //recompute data upwards of new node + extra_data_manager::recompute_extra_data(new_node, header); } //Fix header and own's parent data when replacing x with own, providing own's old data with parent @@ -1751,6 +1806,8 @@ class bstree_algorithms } NodeTraits::set_left(p_right, p); NodeTraits::set_parent(p, p_right); + extra_data_manager::recompute_extra_data(p); + extra_data_manager::recompute_extra_data(p_right); } // rotate p to left (with header and p's parent fixup) @@ -1772,6 +1829,8 @@ class bstree_algorithms } NodeTraits::set_right(p_left, p); NodeTraits::set_parent(p, p_left); + extra_data_manager::recompute_extra_data(p); + extra_data_manager::recompute_extra_data(p_left); } // rotate p to right (with header and p's parent fixup) @@ -1887,6 +1946,7 @@ class bstree_algorithms //We'll calculate leftmost and rightmost nodes while iterating node_ptr current = source_root; node_ptr insertion_point = target_sub_root = cloner(current); + extra_data_manager::clone_extra_data(target_sub_root, current); //We'll calculate leftmost and rightmost nodes while iterating node_ptr leftmost = target_sub_root; @@ -1906,6 +1966,7 @@ class bstree_algorithms node_ptr temp = insertion_point; //Clone and mark as leaf insertion_point = cloner(current); + extra_data_manager::clone_extra_data(insertion_point, current); NodeTraits::set_left (insertion_point, node_ptr()); NodeTraits::set_right (insertion_point, node_ptr()); //Insert left @@ -1922,6 +1983,7 @@ class bstree_algorithms node_ptr temp = insertion_point; //Clone and mark as leaf insertion_point = cloner(current); + extra_data_manager::clone_extra_data(insertion_point, current); NodeTraits::set_left (insertion_point, node_ptr()); NodeTraits::set_right (insertion_point, node_ptr()); //Insert right From d006ddcad3ca8640487dbbe4e2390e400170affe Mon Sep 17 00:00:00 2001 From: Matei David Date: Wed, 12 Mar 2014 18:16:17 -0400 Subject: [PATCH 2/2] added const bool to extra data manager struct --- include/boost/intrusive/bstree_algorithms.hpp | 29 +++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/include/boost/intrusive/bstree_algorithms.hpp b/include/boost/intrusive/bstree_algorithms.hpp index 258034d5..465c4c83 100644 --- a/include/boost/intrusive/bstree_algorithms.hpp +++ b/include/boost/intrusive/bstree_algorithms.hpp @@ -33,6 +33,7 @@ struct extra_data_manager_generator { typedef typename NodeTraits::node_ptr node_ptr; typedef typename NodeTraits::const_node_ptr const_node_ptr; + static const bool enabled = false; static void clone_extra_data(node_ptr, const_node_ptr) {} static void recompute_extra_data(node_ptr) {} static void recompute_extra_data(node_ptr, node_ptr) {} @@ -43,8 +44,15 @@ struct extra_data_manager_generator< NodeTraits, true > { typedef typename NodeTraits::node_ptr node_ptr; typedef typename NodeTraits::const_node_ptr const_node_ptr; - static void clone_extra_data(node_ptr dest, const_node_ptr src) { NodeTraits::clone_extra_data(dest, src); } - static void recompute_extra_data(node_ptr node) { NodeTraits::recompute_extra_data(node); } + static const bool enabled = true; + static void clone_extra_data(node_ptr dest, const_node_ptr src) + { + NodeTraits::clone_extra_data(dest, src); + } + static void recompute_extra_data(node_ptr node) + { + NodeTraits::recompute_extra_data(node); + } static void recompute_extra_data(node_ptr start_node, node_ptr end_node) { for (node_ptr node = start_node; @@ -61,10 +69,16 @@ BOOST_TTI_HAS_STATIC_MEMBER_FUNCTION(recompute_extra_data) template struct extra_data_manager - : extra_data_manager_generator< - NodeTraits, - has_static_member_function_clone_extra_data::value - and has_static_member_function_recompute_extra_data::value + : extra_data_manager_generator< + NodeTraits, + has_static_member_function_clone_extra_data< + NodeTraits, + void (typename NodeTraits::node_ptr, typename NodeTraits::const_node_ptr) + >::value + and has_static_member_function_recompute_extra_data< + NodeTraits, + void (typename NodeTraits::node_ptr) + >::value > {}; } // namespace detail @@ -170,6 +184,7 @@ class bstree_algorithms typedef typename NodeTraits::const_node_ptr const_node_ptr; typedef insert_commit_data_t insert_commit_data; typedef data_for_rebalance_t data_for_rebalance; + typedef detail::extra_data_manager extra_data_manager; /// @cond @@ -194,8 +209,6 @@ class bstree_algorithms const node_ptr subtree_; }; - typedef detail::extra_data_manager extra_data_manager; - /// @endcond public: