1 /*************************************************************************
3 * Copyright (c) 2008-2009 Kohei Yoshida
5 * Permission is hereby granted, free of charge, to any person
6 * obtaining a copy of this software and associated documentation
7 * files (the "Software"), to deal in the Software without
8 * restriction, including without limitation the rights to use,
9 * copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
26 ************************************************************************/
28 #ifndef __MDDS_FLATSEGMENTTREE_HXX__
29 #define __MDDS_FLATSEGMENTTREE_HXX__
42 template<typename _Key
, typename _Value
>
43 class flat_segment_tree
46 typedef _Key key_type
;
47 typedef _Value value_type
;
49 struct nonleaf_value_type
51 key_type low
; /// low range value (inclusive)
52 key_type high
; /// high range value (non-inclusive)
55 struct leaf_value_type
61 struct node
: public node_base
64 nonleaf_value_type value_nonleaf
;
65 leaf_value_type value_leaf
;
77 virtual void fill_nonleaf_value(const node_base_ptr
& left_node
, const node_base_ptr
& right_node
)
79 // Parent node should carry the range of all of its child nodes.
81 value_nonleaf
.low
= left_node
->is_leaf
? get_node(left_node
)->value_leaf
.key
: get_node(left_node
)->value_nonleaf
.low
;
83 // Having a left node is prerequisite.
88 if (right_node
->is_leaf
)
90 // When the child nodes are leaf nodes, the upper bound
91 // must be the value of the node that comes after the
92 // right leaf node (if such node exists).
94 if (right_node
->right
)
95 value_nonleaf
.high
= get_node(right_node
->right
)->value_leaf
.key
;
97 value_nonleaf
.high
= get_node(right_node
)->value_leaf
.key
;
101 value_nonleaf
.high
= get_node(right_node
)->value_nonleaf
.high
;
105 value_nonleaf
.high
= left_node
->is_leaf
? get_node(left_node
)->value_leaf
.key
: get_node(left_node
)->value_nonleaf
.high
;
108 virtual void dump_value() const
113 cout
<< "(" << value_leaf
.key
<< ")";
117 cout
<< "(" << value_nonleaf
.low
<< "-" << value_nonleaf
.high
<< ")";
122 virtual node_base
* create_new(bool leaf
) const
124 return new node(leaf
);
129 * Get a pointer of concrete node type from the base pointer.
131 * @param base_node base node pointer (ref-counted)
133 * @return raw pointer of concrete node type
135 static node
* get_node(const node_base_ptr
& base_node
)
137 return static_cast<node
*>(base_node
.get());
140 flat_segment_tree(key_type min_val
, key_type max_val
, value_type init_val
) :
141 m_root_node(static_cast<node
*>(NULL
)),
142 m_left_leaf(new node(true)),
143 m_right_leaf(new node(true)),
144 m_init_val(init_val
),
147 // we need to create two end nodes during initialization.
148 get_node(m_left_leaf
)->value_leaf
.key
= min_val
;
149 get_node(m_left_leaf
)->value_leaf
.value
= init_val
;
150 m_left_leaf
->right
= m_right_leaf
;
152 get_node(m_right_leaf
)->value_leaf
.key
= max_val
;
153 m_right_leaf
->left
= m_left_leaf
;
158 // Go through all leaf nodes, and disconnect their links.
159 node_base
* cur_node
= m_left_leaf
.get();
162 node_base
* next_node
= cur_node
->right
.get();
163 disconnect_node(cur_node
);
164 cur_node
= next_node
;
166 while (cur_node
!= m_right_leaf
.get());
168 disconnect_node(m_right_leaf
.get());
169 clear_tree(m_root_node
);
170 disconnect_node(m_root_node
.get());
174 * Insert a new segment into the tree.
176 * @param start start value of the segment being inserted. The value is
178 * @param end end value of the segment being inserted. The value is not
180 * @param val value associated with this segment.
182 void insert_segment(key_type start
, key_type end
, value_type val
)
184 if (end
< get_node(m_left_leaf
)->value_leaf
.key
|| start
> get_node(m_right_leaf
)->value_leaf
.key
)
185 // The new segment does not overlap the current interval.
188 if (start
< get_node(m_left_leaf
)->value_leaf
.key
)
189 // The start value should not be smaller than the current minimum.
190 start
= get_node(m_left_leaf
)->value_leaf
.key
;
192 if (end
> get_node(m_right_leaf
)->value_leaf
.key
)
193 // The end value should not be larger than the current maximum.
194 end
= get_node(m_right_leaf
)->value_leaf
.key
;
199 // Find the node with value that either equals or is greater than the
202 node_base_ptr start_pos
= get_insertion_pos_leaf(start
, m_left_leaf
);
204 // Insertion position not found. Bail out.
207 node_base_ptr end_pos
= get_insertion_pos_leaf(end
, start_pos
);
209 end_pos
= m_right_leaf
;
211 node_base_ptr new_start_node
;
212 value_type old_value
;
214 // Set the start node.
216 if (get_node(start_pos
)->value_leaf
.key
== start
)
218 // Re-use the existing node, but save the old value for later.
220 if (start_pos
->left
&& get_node(start_pos
->left
)->value_leaf
.value
== val
)
222 // Extend the existing segment.
223 old_value
= get_node(start_pos
)->value_leaf
.value
;
224 new_start_node
= start_pos
->left
;
228 // Update the value of the existing node.
229 old_value
= get_node(start_pos
)->value_leaf
.value
;
230 get_node(start_pos
)->value_leaf
.value
= val
;
231 new_start_node
= start_pos
;
234 else if (get_node(start_pos
->left
)->value_leaf
.value
== val
)
236 // Extend the existing segment.
237 old_value
= get_node(start_pos
->left
)->value_leaf
.value
;
238 new_start_node
= start_pos
->left
;
242 // Insert a new node before the insertion position node.
243 node_base_ptr
new_node(new node(true));
244 get_node(new_node
)->value_leaf
.key
= start
;
245 get_node(new_node
)->value_leaf
.value
= val
;
246 new_start_node
= new_node
;
248 node_base_ptr left_node
= start_pos
->left
;
249 old_value
= get_node(left_node
)->value_leaf
.value
;
251 // Link to the left node.
252 link_nodes(left_node
, new_node
);
254 // Link to the right node.
255 link_nodes(new_node
, start_pos
);
258 node_base_ptr cur_node
= new_start_node
->right
;
259 while (cur_node
!= end_pos
)
261 // Disconnect the link between the current node and the previous node.
262 cur_node
->left
->right
.reset();
263 cur_node
->left
.reset();
264 old_value
= get_node(cur_node
)->value_leaf
.value
;
266 cur_node
= cur_node
->right
;
271 if (get_node(end_pos
)->value_leaf
.key
== end
)
273 // The new segment ends exactly at the end node position.
275 if (end_pos
->right
&& get_node(end_pos
)->value_leaf
.value
== val
)
277 // Remove this node, and connect the new start node with the
278 // node that comes after this node.
279 new_start_node
->right
= end_pos
->right
;
281 end_pos
->right
->left
= new_start_node
;
282 disconnect_node(end_pos
.get());
286 // Just link the new segment to this node.
287 new_start_node
->right
= end_pos
;
288 end_pos
->left
= new_start_node
;
291 else if (old_value
== val
)
293 link_nodes(new_start_node
, end_pos
);
297 // Insert a new node before the insertion position node.
298 node_base_ptr
new_node(new node(true));
299 get_node(new_node
)->value_leaf
.key
= end
;
300 get_node(new_node
)->value_leaf
.value
= old_value
;
302 // Link to the left node.
303 link_nodes(new_start_node
, new_node
);
305 // Link to the right node.
306 link_nodes(new_node
, end_pos
);
309 m_valid_tree
= false;
313 * Remove a segment specified by the start and end key values, and shift
314 * the remaining segments (i.e. those segments that come after the removed
317 * @param start start value of the segment being removed.
318 * @param end end value of the segment being removed.
320 void shift_segment_left(key_type start
, key_type end
)
325 key_type left_leaf_key
= get_node(m_left_leaf
)->value_leaf
.key
;
326 key_type right_leaf_key
= get_node(m_right_leaf
)->value_leaf
.key
;
327 if (start
< left_leaf_key
|| end
< left_leaf_key
)
331 if (start
> right_leaf_key
|| end
> right_leaf_key
)
332 // invalid key value.
335 node_base_ptr node_pos
;
336 if (left_leaf_key
== start
)
337 node_pos
= m_left_leaf
;
339 // Get the first node with a key value equal to or greater than the
340 // start key value. But we want to skip the leftmost node.
341 node_pos
= get_insertion_pos_leaf(start
, m_left_leaf
->right
);
346 key_type segment_size
= end
- start
;
348 if (end
< get_node(node_pos
)->value_leaf
.key
)
350 // The removed segment does not overlap with any nodes. Simply
351 // shift the key values of those nodes that come after the removed
353 shift_leaf_key_left(node_pos
, m_right_leaf
, segment_size
);
354 m_valid_tree
= false;
358 // Move the first node to the starting position, and from there search
359 // for the first node whose key value is greater than the end value.
360 get_node(node_pos
)->value_leaf
.key
= start
;
361 node_base_ptr start_pos
= node_pos
;
362 node_pos
= node_pos
->right
;
363 value_type last_seg_value
= get_node(start_pos
)->value_leaf
.value
;
364 while (get_node(node_pos
) != get_node(m_right_leaf
) && get_node(node_pos
)->value_leaf
.key
<= end
)
366 last_seg_value
= get_node(node_pos
)->value_leaf
.value
;
367 node_base_ptr next
= node_pos
->right
;
368 disconnect_node(node_pos
.get());
372 get_node(start_pos
)->value_leaf
.value
= last_seg_value
;
373 start_pos
->right
= node_pos
;
374 node_pos
->left
= start_pos
;
375 if (start_pos
->left
&& get_node(start_pos
->left
)->value_leaf
.value
== get_node(start_pos
)->value_leaf
.value
)
377 // Removing a segment resulted in two consecutive segments with
378 // identical value. Combine them by removing the 2nd redundant
380 start_pos
->left
->right
= start_pos
->right
;
381 start_pos
->right
->left
= start_pos
->left
;
382 disconnect_node(start_pos
.get());
385 shift_leaf_key_left(node_pos
, m_right_leaf
, segment_size
);
386 m_valid_tree
= false;
390 * Shift all segments that occur at or after the specified start position
391 * to right by the size specified.
393 * @param pos position where the right-shift occurs.
394 * @param size amount of shift (must be greater than 0)
396 void shift_segment_right(key_type pos
, key_type size
, bool skip_start_node
)
401 if (pos
< get_node(m_left_leaf
)->value_leaf
.key
|| get_node(m_right_leaf
)->value_leaf
.key
<= pos
)
402 // specified position is out-of-bound
405 if (get_node(m_left_leaf
)->value_leaf
.key
== pos
)
407 // Position is at the leftmost node. Shift all the other nodes,
408 // and insert a new node at (pos + size) position.
409 node_base_ptr cur_node
= m_left_leaf
->right
;
410 shift_leaf_key_right(cur_node
, m_right_leaf
, size
);
412 if (get_node(m_left_leaf
)->value_leaf
.value
!= m_init_val
)
414 // The leftmost leaf node has a non-initial value. We need to
415 // insert a new node to carry that value after the shift.
416 node_base_ptr
new_node(new node(true));
417 get_node(new_node
)->value_leaf
.key
= pos
+ size
;
418 get_node(new_node
)->value_leaf
.value
= get_node(m_left_leaf
)->value_leaf
.value
;
419 get_node(m_left_leaf
)->value_leaf
.value
= m_init_val
;
420 new_node
->left
= m_left_leaf
;
421 new_node
->right
= m_left_leaf
->right
;
422 m_left_leaf
->right
= new_node
;
425 m_valid_tree
= false;
429 // Get the first node with a key value equal to or greater than the
430 // start key value. But we want to skip the leftmost node.
431 node_base_ptr cur_node
= get_insertion_pos_leaf(pos
, m_left_leaf
->right
);
433 // If the point of insertion is at an existing node position, don't
434 // shift that node but start with the one after it if that's
436 if (skip_start_node
&& cur_node
&& get_node(cur_node
)->value_leaf
.key
== pos
)
437 cur_node
= cur_node
->right
;
442 shift_leaf_key_right(cur_node
, m_right_leaf
, size
);
443 m_valid_tree
= false;
446 bool search(key_type key
, value_type
& value
, key_type
* start
= NULL
, key_type
* end
= NULL
) const
448 if (key
< get_node(m_left_leaf
)->value_leaf
.key
|| get_node(m_right_leaf
)->value_leaf
.key
<= key
)
449 // key value is out-of-bound.
452 const node
* pos
= get_insertion_pos_leaf(key
, get_node(m_left_leaf
));
453 if (pos
->value_leaf
.key
== key
)
455 value
= pos
->value_leaf
.value
;
457 *start
= pos
->value_leaf
.key
;
458 if (end
&& pos
->right
)
459 *end
= get_node(pos
->right
)->value_leaf
.key
;
462 else if (pos
->left
&& get_node(pos
->left
)->value_leaf
.key
< key
)
464 value
= get_node(pos
->left
)->value_leaf
.value
;
466 *start
= get_node(pos
->left
)->value_leaf
.key
;
468 *end
= pos
->value_leaf
.key
;
475 bool search_tree(key_type key
, value_type
& value
, key_type
* start
= NULL
, key_type
* end
= NULL
) const
477 if (!m_root_node
|| !m_valid_tree
)
479 // either tree has not been built, or is in an invalid state.
483 if (key
< get_node(m_left_leaf
)->value_leaf
.key
|| get_node(m_right_leaf
)->value_leaf
.key
<= key
)
485 // key value is out-of-bound.
489 // Descend down the tree through the last non-leaf layer.
491 node
* cur_node
= get_node(m_root_node
);
496 if (cur_node
->left
->is_leaf
)
499 const nonleaf_value_type
& v
= get_node(cur_node
->left
)->value_nonleaf
;
500 if (v
.low
<= key
&& key
< v
.high
)
502 cur_node
= get_node(cur_node
->left
);
508 // left child node can't be missing !
514 const nonleaf_value_type
& v
= get_node(cur_node
->right
)->value_nonleaf
;
515 if (v
.low
<= key
&& key
< v
.high
)
517 cur_node
= get_node(cur_node
->right
);
524 assert(cur_node
->left
->is_leaf
&& cur_node
->right
->is_leaf
);
526 key_type key1
= get_node(cur_node
->left
)->value_leaf
.key
;
527 key_type key2
= get_node(cur_node
->right
)->value_leaf
.key
;
529 if (key1
<= key
&& key
< key2
)
531 cur_node
= get_node(cur_node
->left
);
533 else if (key2
<= key
&& key
< cur_node
->value_nonleaf
.high
)
535 cur_node
= get_node(cur_node
->right
);
545 value
= cur_node
->value_leaf
.value
;
547 *start
= cur_node
->value_leaf
.key
;
551 assert(cur_node
->right
);
553 *end
= get_node(cur_node
->right
)->value_leaf
.key
;
555 // This should never happen, but just in case....
556 *end
= get_node(m_right_leaf
)->value_leaf
.key
;
567 clear_tree(m_root_node
);
568 m_root_node
= ::mdds::build_tree(m_left_leaf
);
572 bool is_tree_valid() const
578 void dump_tree() const
584 assert(!"attempted to dump an invalid tree!");
586 size_t node_count
= ::mdds::dump_tree(m_root_node
);
587 size_t node_instance_count
= node_base::get_instance_count();
589 cout
<< "tree node count = " << node_count
<< " node instance count = " << node_instance_count
<< endl
;
590 assert(node_count
== node_instance_count
);
593 void dump_leaf_nodes() const
598 cout
<< "------------------------------------------" << endl
;
600 node_base_ptr cur_node
= m_left_leaf
;
604 cout
<< " node " << node_id
++ << ": key = " << get_node(cur_node
)->value_leaf
.key
605 << "; value = " << get_node(cur_node
)->value_leaf
.value
607 cur_node
= cur_node
->right
;
609 cout
<< endl
<< " node instance count = " << node_base::get_instance_count() << endl
;
613 * Verify keys in the leaf nodes.
615 * @param key_values vector containing key values in the left-to-right
616 * order, including the key value of the rightmost leaf
619 bool verify_keys(const ::std::vector
<key_type
>& key_values
) const
621 node
* cur_node
= get_node(m_left_leaf
);
622 typename ::std::vector
<key_type
>::const_iterator itr
= key_values
.begin(), itr_end
= key_values
.end();
623 for (; itr
!= itr_end
; ++itr
)
626 // Position past the right-mode node. Invalid.
629 if (cur_node
->value_leaf
.key
!= *itr
)
630 // Key values differ.
633 cur_node
= get_node(cur_node
->right
);
637 // At this point, we expect the current node to be at the position
638 // past the right-most node, which is NULL.
645 * Verify values in the leaf nodes.
647 * @param values vector containing values to verify against, in the
648 * left-to-right order, <i>not</i> including the value of
649 * the rightmost leaf node.
651 bool verify_values(const ::std::vector
<value_type
>& values
) const
653 node
* cur_node
= get_node(m_left_leaf
);
654 node
* end_node
= get_node(m_right_leaf
);
655 typename ::std::vector
<value_type
>::const_iterator itr
= values
.begin(), itr_end
= values
.end();
656 for (; itr
!= itr_end
; ++itr
)
658 if (cur_node
== end_node
|| !cur_node
)
661 if (cur_node
->value_leaf
.value
!= *itr
)
662 // Key values differ.
665 cur_node
= get_node(cur_node
->right
);
668 if (cur_node
!= end_node
)
669 // At this point, we expect the current node to be at the end of
680 node_base_ptr
get_insertion_pos_leaf(key_type key
, const node_base_ptr
& start_pos
) const
682 node_base_ptr cur_node
= start_pos
;
685 if (key
<= get_node(cur_node
)->value_leaf
.key
)
687 // Found the insertion position.
690 cur_node
= cur_node
->right
;
692 return node_base_ptr();
695 const node
* get_insertion_pos_leaf(key_type key
, const node
* start_pos
) const
697 const node
* cur_node
= start_pos
;
700 if (key
<= cur_node
->value_leaf
.key
)
702 // Found the insertion position.
705 cur_node
= get_node(cur_node
->right
);
710 static void shift_leaf_key_left(node_base_ptr
& begin_node
, node_base_ptr
& end_node
, key_type shift_value
)
712 node
* cur_node_p
= get_node(begin_node
);
713 node
* end_node_p
= get_node(end_node
);
714 while (cur_node_p
!= end_node_p
)
716 cur_node_p
->value_leaf
.key
-= shift_value
;
717 cur_node_p
= get_node(cur_node_p
->right
);
721 static void shift_leaf_key_right(node_base_ptr
& cur_node
, node_base_ptr
& end_node
, key_type shift_value
)
723 key_type end_node_key
= get_node(end_node
)->value_leaf
.key
;
724 while (get_node(cur_node
) != get_node(end_node
))
726 get_node(cur_node
)->value_leaf
.key
+= shift_value
;
727 if (get_node(cur_node
)->value_leaf
.key
< end_node_key
)
729 // The node is still in-bound. Keep shifting.
730 cur_node
= cur_node
->right
;
734 // This node has been pushed outside the end node position.
735 // Remove all nodes that follows, and connect the previous node
736 // with the end node.
738 node_base_ptr last_node
= cur_node
->left
;
739 while (get_node(cur_node
) != get_node(end_node
))
741 node_base_ptr next_node
= cur_node
->right
;
742 disconnect_node(cur_node
);
743 cur_node
= next_node
;
745 last_node
->right
= end_node
;
746 end_node
->left
= last_node
;
752 node_base_ptr m_root_node
;
753 node_base_ptr m_left_leaf
;
754 node_base_ptr m_right_leaf
;
755 value_type m_init_val
;