28 #ifndef __MDDS_NODE_HXX__ 29 #define __MDDS_NODE_HXX__ 35 #include <boost/intrusive_ptr.hpp> 37 namespace mdds {
namespace __st {
39 #ifdef MDDS_DEBUG_NODE_BASE 40 size_t node_instance_count = 0;
48 node_base(
bool _is_leaf) : parent(nullptr), is_leaf(_is_leaf) {}
55 typedef typename T::nonleaf_value_type nonleaf_value_type;
56 typedef typename T::fill_nonleaf_value_handler fill_nonleaf_value_handler;
57 typedef typename T::init_handler init_handler;
58 typedef typename T::dispose_handler dispose_handler;
60 typedef typename T::to_string_handler to_string_handler;
62 nonleaf_value_type value_nonleaf;
68 fill_nonleaf_value_handler _hdl_fill_nonleaf;
69 init_handler _hdl_init;
70 dispose_handler _hdl_dispose;
72 to_string_handler _hdl_to_string;
93 value_nonleaf = r.value_nonleaf;
105 value_nonleaf = r.value_nonleaf;
121 return value_nonleaf == r.value_nonleaf;
126 _hdl_fill_nonleaf(*
this, left_node, right_node);
129 #ifdef MDDS_UNIT_TEST 130 void dump_value()
const 132 ::std::cout << _hdl_to_string(*
this);
135 ::std::string to_string()
const 137 return _hdl_to_string(*
this);
145 typedef ::boost::intrusive_ptr<node> node_ptr;
147 typedef typename T::leaf_value_type leaf_value_type;
148 typedef typename T::init_handler init_handler;
149 typedef typename T::dispose_handler dispose_handler;
150 #ifdef MDDS_UNIT_TEST 151 typedef typename T::to_string_handler to_string_handler;
154 static size_t get_instance_count()
156 #ifdef MDDS_DEBUG_NODE_BASE 157 return node_instance_count;
163 leaf_value_type value_leaf;
170 init_handler _hdl_init;
171 dispose_handler _hdl_dispose;
172 #ifdef MDDS_UNIT_TEST 173 to_string_handler _hdl_to_string;
179 #ifdef MDDS_DEBUG_NODE_BASE 180 ++node_instance_count;
191 #ifdef MDDS_DEBUG_NODE_BASE 192 ++node_instance_count;
194 value_leaf = r.value_leaf;
206 value_leaf = r.value_leaf;
212 #ifdef MDDS_DEBUG_NODE_BASE 213 --node_instance_count;
223 bool equals(
const node& r)
const 225 return value_leaf == r.value_leaf;
228 #ifdef MDDS_UNIT_TEST 229 void dump_value()
const 231 ::std::cout << _hdl_to_string(*
this);
234 ::std::string to_string()
const 236 return _hdl_to_string(*
this);
242 inline void intrusive_ptr_add_ref(
node<T>* p)
248 inline void intrusive_ptr_release(
node<T>* p)
256 void link_nodes(
typename node<T>::node_ptr& left,
typename node<T>::node_ptr& right)
267 typedef typename mdds::__st::node<T>::node_ptr leaf_node_ptr;
269 typedef std::vector<nonleaf_node> nonleaf_node_pool_type;
272 m_pool(pool), m_pool_pos(pool.begin()), m_pool_pos_end(pool.end()) {}
274 nonleaf_node* build(
const leaf_node_ptr& left_leaf_node)
280 leaf_node_ptr node1 = left_leaf_node;
282 std::vector<nonleaf_node*> node_list;
285 leaf_node_ptr node2 = node1->next;
286 nonleaf_node* parent_node = make_parent_node(node1.get(), node2.get());
287 node_list.push_back(parent_node);
289 if (!node2 || !node2->next)
296 return build_tree_non_leaf(node_list);
303 assert(m_pool_pos != m_pool_pos_end);
305 nonleaf_node* parent_node = &(*m_pool_pos);
307 node1->parent = parent_node;
308 parent_node->left = node1;
311 node2->parent = parent_node;
312 parent_node->
right = node2;
315 parent_node->fill_nonleaf_value(node1, node2);
319 nonleaf_node* build_tree_non_leaf(
const std::vector<nonleaf_node*>& node_list)
321 size_t node_count = node_list.size();
324 return node_list.front();
326 else if (node_count == 0)
329 std::vector<nonleaf_node*> new_node_list;
330 nonleaf_node* node1 =
nullptr;
331 typename std::vector<nonleaf_node*>::const_iterator it = node_list.begin();
332 typename std::vector<nonleaf_node*>::const_iterator it_end = node_list.end();
333 for (
bool even_itr =
false; it != it_end; ++it, even_itr = !even_itr)
337 nonleaf_node* node2 = *it;
338 nonleaf_node* parent_node = make_parent_node(node1, node2);
339 new_node_list.push_back(parent_node);
350 nonleaf_node* parent_node = make_parent_node(node1,
nullptr);
351 new_node_list.push_back(parent_node);
355 return build_tree_non_leaf(new_node_list);
358 nonleaf_node_pool_type& m_pool;
359 typename nonleaf_node_pool_type::iterator m_pool_pos;
360 typename nonleaf_node_pool_type::iterator m_pool_pos_end;
365 void disconnect_all_nodes(
node<T>* p)
376 void disconnect_leaf_nodes(
node<T>* left_node,
node<T>* right_node)
378 if (!left_node || !right_node)
386 disconnect_all_nodes(cur_node);
387 cur_node = next_node;
389 while (cur_node != right_node);
391 disconnect_all_nodes(right_node);
395 size_t count_leaf_nodes(
const node<T>* left_end,
const node<T>* right_end)
397 size_t leaf_count = 1;
399 const node<T>* p_end = right_end;
400 for (; p != p_end; p = p->
next.get(), ++leaf_count)
406 inline size_t count_needed_nonleaf_nodes(
size_t leaf_count)
408 size_t nonleaf_count = 0;
414 if ((leaf_count % 2) == 1)
419 nonleaf_count += leaf_count;
422 return nonleaf_count;
425 #ifdef MDDS_UNIT_TEST 427 template<
typename _Leaf,
typename _NonLeaf>
430 typedef std::vector<const node_base*> node_list_type;
433 static size_t dump(
const node_base* root_node)
438 node_list_type node_list;
439 node_list.push_back(root_node);
440 return dump_layer(node_list, 0);
444 static size_t dump_layer(
const node_list_type& node_list,
unsigned int level)
449 if (node_list.empty())
452 size_t node_count = node_list.size();
454 bool is_leaf = node_list.front()->is_leaf;
455 cout <<
"level " << level <<
" (" << (is_leaf?
"leaf":
"non-leaf") <<
")" << endl;
457 node_list_type new_list;
458 typename node_list_type::const_iterator it = node_list.begin(), it_end = node_list.end();
459 for (; it != it_end; ++it)
469 static_cast<const _Leaf*
>(p)->dump_value();
471 static_cast<const _NonLeaf*
>(p)->dump_value();
476 if (static_cast<const _NonLeaf*>(p)->left)
478 new_list.push_back(static_cast<const _NonLeaf*>(p)->left);
479 if (static_cast<const _NonLeaf*>(p)->right)
480 new_list.push_back(static_cast<const _NonLeaf*>(p)->right);
485 if (!new_list.empty())
486 node_count += dump_layer(new_list, level+1);
node_base * right
left child nonleaf_node
Definition: node.hpp:65
bool is_leaf
parent nonleaf_node
Definition: node.hpp:46
nonleaf_node & operator=(const nonleaf_node &r)
Definition: node.hpp:99
nonleaf_node(const nonleaf_node &r)
Definition: node.hpp:88
Definition: flat_segment_tree.hpp:46
node & operator=(const node &r)
Definition: node.hpp:200
size_t refcount
next sibling leaf node.
Definition: node.hpp:168
node_ptr next
previous sibling leaf node.
Definition: node.hpp:166
node(const node &r)
Definition: node.hpp:189