File indexing completed on 2024-05-12 16:35:09
0001 /************************************************************************* 0002 * 0003 * Copyright (c) 2008-2010 Kohei Yoshida 0004 * 0005 * Permission is hereby granted, free of charge, to any person 0006 * obtaining a copy of this software and associated documentation 0007 * files (the "Software"), to deal in the Software without 0008 * restriction, including without limitation the rights to use, 0009 * copy, modify, merge, publish, distribute, sublicense, and/or sell 0010 * copies of the Software, and to permit persons to whom the 0011 * Software is furnished to do so, subject to the following 0012 * conditions: 0013 * 0014 * The above copyright notice and this permission notice shall be 0015 * included in all copies or substantial portions of the Software. 0016 * 0017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 0018 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 0019 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 0020 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 0021 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 0022 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 0023 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 0024 * OTHER DEALINGS IN THE SOFTWARE. 0025 * 0026 ************************************************************************/ 0027 0028 #ifndef __MDDS_FLATSEGMENTTREE_HPP__ 0029 #define __MDDS_FLATSEGMENTTREE_HPP__ 0030 0031 #include <iostream> 0032 #include <utility> 0033 #include <cassert> 0034 #include <limits> 0035 0036 #include "node.hpp" 0037 0038 #ifdef UNIT_TEST 0039 #include <cstdio> 0040 #include <vector> 0041 #endif 0042 0043 namespace mdds { 0044 0045 template<typename _Key, typename _Value> 0046 class flat_segment_tree 0047 { 0048 public: 0049 typedef _Key key_type; 0050 typedef _Value value_type; 0051 0052 private: 0053 struct nonleaf_value_type 0054 { 0055 key_type low; /// low range value (inclusive) 0056 key_type high; /// high range value (non-inclusive) 0057 }; 0058 0059 struct leaf_value_type 0060 { 0061 key_type key; 0062 value_type value; 0063 }; 0064 #ifdef UNIT_TEST 0065 public: 0066 #endif 0067 struct node; 0068 typedef ::boost::intrusive_ptr<node> node_ptr; 0069 0070 struct node : public node_base<node_ptr, node> 0071 { 0072 union { 0073 nonleaf_value_type value_nonleaf; 0074 leaf_value_type value_leaf; 0075 }; 0076 0077 node(bool _is_leaf) : 0078 node_base<node_ptr, node>(_is_leaf) 0079 { 0080 } 0081 0082 node(const node& r) : 0083 node_base<node_ptr, node>(r) 0084 { 0085 if (this->is_leaf) 0086 { 0087 value_leaf.key = r.value_leaf.key; 0088 value_leaf.value = r.value_leaf.value; 0089 } 0090 else 0091 { 0092 value_nonleaf.low = r.value_nonleaf.low; 0093 value_nonleaf.high = r.value_nonleaf.high; 0094 } 0095 } 0096 0097 void dispose() 0098 { 0099 } 0100 0101 bool equals(const node& r) const 0102 { 0103 if (this->is_leaf != r.is_leaf) 0104 return false; 0105 0106 if (this->is_leaf) 0107 { 0108 if (value_leaf.key != r.value_leaf.key) 0109 return false; 0110 if (value_leaf.value != r.value_leaf.value) 0111 return false; 0112 } 0113 else 0114 { 0115 if (value_nonleaf.low != r.value_nonleaf.low) 0116 return false; 0117 if (value_nonleaf.high != r.value_nonleaf.high) 0118 return false; 0119 } 0120 0121 return true; 0122 } 0123 0124 void fill_nonleaf_value(const node_ptr& left_node, const node_ptr& right_node) 0125 { 0126 // Parent node should carry the range of all of its child nodes. 0127 if (left_node) 0128 value_nonleaf.low = left_node->is_leaf ? left_node->value_leaf.key : left_node->value_nonleaf.low; 0129 else 0130 // Having a left node is prerequisite. 0131 return; 0132 0133 if (right_node) 0134 { 0135 if (right_node->is_leaf) 0136 { 0137 // When the child nodes are leaf nodes, the upper bound 0138 // must be the value of the node that comes after the 0139 // right leaf node (if such node exists). 0140 0141 if (right_node->right) 0142 value_nonleaf.high = right_node->right->value_leaf.key; 0143 else 0144 value_nonleaf.high = right_node->value_leaf.key; 0145 } 0146 else 0147 { 0148 value_nonleaf.high = right_node->value_nonleaf.high; 0149 } 0150 } 0151 else 0152 value_nonleaf.high = left_node->is_leaf ? left_node->value_leaf.key : left_node->value_nonleaf.high; 0153 } 0154 0155 #ifdef UNIT_TEST 0156 void dump_value() const 0157 { 0158 using ::std::cout; 0159 if (this->is_leaf) 0160 { 0161 cout << "(" << value_leaf.key << ")"; 0162 } 0163 else 0164 { 0165 cout << "(" << value_nonleaf.low << "-" << value_nonleaf.high << ")"; 0166 } 0167 cout << " "; 0168 } 0169 #endif 0170 }; 0171 0172 private: 0173 class const_iterator_base 0174 { 0175 public: 0176 typedef flat_segment_tree<key_type, value_type> fst_type; 0177 0178 explicit const_iterator_base(const fst_type* _db, bool _end, bool _forward) : 0179 m_db(_db), m_pos(NULL), m_end_pos(_end), m_forward(_forward) 0180 { 0181 if (!_db) 0182 return; 0183 0184 if (m_forward) 0185 { 0186 // forward direction 0187 m_pos = _end ? _db->m_right_leaf.get() : _db->m_left_leaf.get(); 0188 } 0189 else 0190 { 0191 // reverse direction 0192 m_pos = _end ? _db->m_left_leaf.get() : _db->m_right_leaf.get(); 0193 } 0194 } 0195 0196 const_iterator_base(const const_iterator_base& r) : 0197 m_db(r.m_db), m_pos(r.m_pos), m_end_pos(r.m_end_pos), m_forward(r.m_forward) {} 0198 0199 const_iterator_base& operator=(const const_iterator_base& r) 0200 { 0201 m_db = r.m_db; 0202 m_pos = r.m_pos; 0203 return *this; 0204 } 0205 0206 const ::std::pair<key_type, value_type>* operator++() 0207 { 0208 assert(m_pos); 0209 if (m_forward) 0210 { 0211 if (m_pos == m_db->m_right_leaf.get()) 0212 m_end_pos = true; 0213 else 0214 m_pos = m_pos->right.get(); 0215 } 0216 else 0217 { 0218 if (m_pos == m_db->m_left_leaf.get()) 0219 m_end_pos = true; 0220 else 0221 m_pos = m_pos->left.get(); 0222 } 0223 0224 return operator->(); 0225 } 0226 0227 const ::std::pair<key_type, value_type>* operator--() 0228 { 0229 assert(m_pos); 0230 if (m_end_pos) 0231 m_end_pos = false; 0232 else 0233 m_pos = m_forward ? m_pos->left.get() : m_pos->right.get(); 0234 0235 return operator->(); 0236 } 0237 0238 bool operator==(const const_iterator_base& r) const 0239 { 0240 return (m_end_pos == r.m_end_pos) && (m_pos == r.m_pos); 0241 } 0242 0243 bool operator!=(const const_iterator_base& r) const 0244 { 0245 return !operator==(r); 0246 } 0247 0248 const ::std::pair<key_type, value_type>& operator*() 0249 { 0250 return get_current_node_pair(); 0251 } 0252 0253 const ::std::pair<key_type, value_type>* operator->() 0254 { 0255 return &get_current_node_pair(); 0256 } 0257 0258 private: 0259 const ::std::pair<key_type, value_type>& get_current_node_pair() 0260 { 0261 m_current_pair = ::std::pair<key_type, value_type>(m_pos->value_leaf.key, m_pos->value_leaf.value); 0262 return m_current_pair; 0263 } 0264 0265 const fst_type* m_db; 0266 const typename fst_type::node* m_pos; 0267 ::std::pair<key_type, value_type> m_current_pair; 0268 bool m_end_pos:1; 0269 bool m_forward:1; 0270 }; 0271 0272 public: 0273 class const_iterator : public const_iterator_base 0274 { 0275 friend class flat_segment_tree; 0276 public: 0277 const_iterator() : 0278 const_iterator_base(NULL, false, true) {} 0279 0280 private: 0281 explicit const_iterator(const typename const_iterator_base::fst_type* _db, bool _end) : 0282 const_iterator_base(_db, _end, true) {} 0283 }; 0284 0285 class const_reverse_iterator : public const_iterator_base 0286 { 0287 friend class flat_segment_tree; 0288 public: 0289 const_reverse_iterator() : 0290 const_iterator_base(NULL, false, false) {} 0291 private: 0292 explicit const_reverse_iterator(const typename const_iterator_base::fst_type* _db, bool _end) : 0293 const_iterator_base(_db, _end, false) {} 0294 }; 0295 0296 const_iterator begin() const 0297 { 0298 return const_iterator(this, false); 0299 } 0300 0301 const_iterator end() const 0302 { 0303 return const_iterator(this, true); 0304 } 0305 0306 const_reverse_iterator rbegin() const 0307 { 0308 return const_reverse_iterator(this, false); 0309 } 0310 0311 const_reverse_iterator rend() const 0312 { 0313 return const_reverse_iterator(this, true); 0314 } 0315 0316 flat_segment_tree(key_type min_val, key_type max_val, value_type init_val); 0317 0318 /** 0319 * Copy constructor only copies the leaf nodes. 0320 */ 0321 flat_segment_tree(const flat_segment_tree<key_type, value_type>& r); 0322 0323 ~flat_segment_tree(); 0324 0325 /** 0326 * Insert a new segment into the tree. It searches for the point of 0327 * insertion from the first leaf node. 0328 * 0329 * @param start_key start value of the segment being inserted. The value 0330 * is inclusive. 0331 * @param end_key end value of the segment being inserted. The value is 0332 * not inclusive. 0333 * @param val value associated with this segment. 0334 */ 0335 void insert_front(key_type start_key, key_type end_key, value_type val) 0336 { 0337 insert_segment_impl(start_key, end_key, val, true); 0338 } 0339 0340 /** 0341 * Insert a new segment into the tree. Unlike 0342 * the <code>insert_front</code>, this method searches for the point of 0343 * insertion from the last leaf node toward the first. 0344 */ 0345 void insert_back(key_type start_key, key_type end_key, value_type val) 0346 { 0347 insert_segment_impl(start_key, end_key, val, false); 0348 } 0349 0350 /** 0351 * Remove a segment specified by the start and end key values, and shift 0352 * the remaining segments (i.e. those segments that come after the removed 0353 * segment) to left. Note that the start and end positions of the segment 0354 * being removed <b>must</b> be within the base segment span. 0355 * 0356 * @param start_key start position of the segment being removed. 0357 * @param end_key end position of the segment being removed. 0358 */ 0359 void shift_left(key_type start_key, key_type end_key); 0360 0361 /** 0362 * Shift all segments that occur at or after the specified start position 0363 * to right by the size specified. 0364 * 0365 * @param pos position where the right-shift occurs. 0366 * @param size amount of shift (must be greater than 0) 0367 * @param skip_start_node if true, and the specified position is at an 0368 * existing node position, that node will 0369 * <i>not</i> be shifted. This argument has no 0370 * effect if the position specified does not 0371 * coincide with any of the existing nodes. 0372 */ 0373 void shift_right(key_type pos, key_type size, bool skip_start_node); 0374 0375 bool search(key_type key, value_type& value, key_type* start_key = NULL, key_type* end_key = NULL) const; 0376 0377 bool search_tree(key_type key, value_type& value, key_type* start_key = NULL, key_type* end_key = NULL) const; 0378 0379 void build_tree(); 0380 0381 bool is_tree_valid() const 0382 { 0383 return m_valid_tree; 0384 } 0385 0386 /** 0387 * Equality between two flat_segment_tree instances is evaluated by 0388 * comparing the keys and the values of the leaf nodes only. Neither the 0389 * non-leaf nodes nor the validity of the tree is evaluated. 0390 */ 0391 bool operator==(const flat_segment_tree<key_type, value_type>& r) const; 0392 0393 bool operator !=(const flat_segment_tree<key_type, value_type>& r) const 0394 { 0395 return !operator==(r); 0396 } 0397 0398 #ifdef UNIT_TEST 0399 node_ptr get_root_node() const 0400 { 0401 return m_root_node; 0402 } 0403 0404 void dump_tree() const 0405 { 0406 using ::std::cout; 0407 using ::std::endl; 0408 0409 if (!m_valid_tree) 0410 assert(!"attempted to dump an invalid tree!"); 0411 0412 size_t node_count = ::mdds::dump_tree(m_root_node); 0413 size_t node_instance_count = node_base<node_ptr, node>::get_instance_count(); 0414 0415 cout << "tree node count = " << node_count << " node instance count = " << node_instance_count << endl; 0416 assert(node_count == node_instance_count); 0417 } 0418 0419 void dump_leaf_nodes() const 0420 { 0421 using ::std::cout; 0422 using ::std::endl; 0423 0424 cout << "------------------------------------------" << endl; 0425 0426 node_ptr cur_node = m_left_leaf; 0427 long node_id = 0; 0428 while (cur_node) 0429 { 0430 cout << " node " << node_id++ << ": key = " << cur_node->value_leaf.key 0431 << "; value = " << cur_node->value_leaf.value 0432 << endl; 0433 cur_node = cur_node->right; 0434 } 0435 cout << endl << " node instance count = " << node_base<node_ptr, node>::get_instance_count() << endl; 0436 } 0437 0438 /** 0439 * Verify keys in the leaf nodes. 0440 * 0441 * @param key_values vector containing key values in the left-to-right 0442 * order, including the key value of the rightmost leaf 0443 * node. 0444 */ 0445 bool verify_keys(const ::std::vector<key_type>& key_values) const 0446 { 0447 node* cur_node = m_left_leaf.get(); 0448 typename ::std::vector<key_type>::const_iterator itr = key_values.begin(), itr_end = key_values.end(); 0449 for (; itr != itr_end; ++itr) 0450 { 0451 if (!cur_node) 0452 // Position past the right-mode node. Invalid. 0453 return false; 0454 0455 if (cur_node->value_leaf.key != *itr) 0456 // Key values differ. 0457 return false; 0458 0459 cur_node = cur_node->right.get(); 0460 } 0461 0462 if (cur_node) 0463 // At this point, we expect the current node to be at the position 0464 // past the right-most node, which is NULL. 0465 return false; 0466 0467 return true; 0468 } 0469 0470 /** 0471 * Verify values in the leaf nodes. 0472 * 0473 * @param values vector containing values to verify against, in the 0474 * left-to-right order, <i>not</i> including the value of 0475 * the rightmost leaf node. 0476 */ 0477 bool verify_values(const ::std::vector<value_type>& values) const 0478 { 0479 node* cur_node = m_left_leaf.get(); 0480 node* end_node = m_right_leaf.get(); 0481 typename ::std::vector<value_type>::const_iterator itr = values.begin(), itr_end = values.end(); 0482 for (; itr != itr_end; ++itr) 0483 { 0484 if (cur_node == end_node || !cur_node) 0485 return false; 0486 0487 if (cur_node->value_leaf.value != *itr) 0488 // Key values differ. 0489 return false; 0490 0491 cur_node = cur_node->right.get(); 0492 } 0493 0494 if (cur_node != end_node) 0495 // At this point, we expect the current node to be at the end of 0496 // range. 0497 return false; 0498 0499 return true; 0500 } 0501 #endif 0502 0503 private: 0504 flat_segment_tree(); // default constructor is not allowed. 0505 0506 void append_new_segment(key_type start_key) 0507 { 0508 if (m_right_leaf->left->value_leaf.key == start_key) 0509 { 0510 m_right_leaf->left->value_leaf.value = m_init_val; 0511 return; 0512 } 0513 0514 #ifdef UNIT_TEST 0515 // The start position must come after the position of the last node 0516 // before the right-most node. 0517 assert(m_right_leaf->left->value_leaf.key < start_key); 0518 #endif 0519 0520 if (m_right_leaf->left->value_leaf.value == m_init_val) 0521 // The existing segment has the same value. No need to insert a 0522 // new segment. 0523 return; 0524 0525 node_ptr new_node(new node(true)); 0526 new_node->value_leaf.key = start_key; 0527 new_node->value_leaf.value = m_init_val; 0528 new_node->left = m_right_leaf->left; 0529 new_node->right = m_right_leaf; 0530 m_right_leaf->left->right = new_node; 0531 m_right_leaf->left = new_node; 0532 m_valid_tree = false; 0533 } 0534 0535 void insert_segment_impl(key_type start_key, key_type end_key, value_type val, bool forward); 0536 0537 node_ptr get_insertion_pos_leaf(key_type key, const node_ptr& start_pos) const; 0538 node_ptr get_insertion_pos_leaf_reverse(key_type key, const node_ptr& start_pos) const; 0539 0540 const node* get_insertion_pos_leaf(key_type key, const node* start_pos) const; 0541 0542 static void shift_leaf_key_left(node_ptr& begin_node, node_ptr& end_node, key_type shift_value) 0543 { 0544 node* cur_node_p = begin_node.get(); 0545 node* end_node_p = end_node.get(); 0546 while (cur_node_p != end_node_p) 0547 { 0548 cur_node_p->value_leaf.key -= shift_value; 0549 cur_node_p = cur_node_p->right.get(); 0550 } 0551 } 0552 0553 static void shift_leaf_key_right(node_ptr& cur_node, node_ptr& end_node, key_type shift_value) 0554 { 0555 key_type end_node_key = end_node->value_leaf.key; 0556 while (cur_node.get() != end_node.get()) 0557 { 0558 cur_node->value_leaf.key += shift_value; 0559 if (cur_node->value_leaf.key < end_node_key) 0560 { 0561 // The node is still in-bound. Keep shifting. 0562 cur_node = cur_node->right; 0563 continue; 0564 } 0565 0566 // This node has been pushed outside the end node position. 0567 // Remove all nodes that follows, and connect the previous node 0568 // with the end node. 0569 0570 node_ptr last_node = cur_node->left; 0571 while (cur_node.get() != end_node.get()) 0572 { 0573 node_ptr next_node = cur_node->right; 0574 disconnect_all_nodes(cur_node.get()); 0575 cur_node = next_node; 0576 } 0577 last_node->right = end_node; 0578 end_node->left = last_node; 0579 return; 0580 } 0581 } 0582 0583 private: 0584 node_ptr m_root_node; 0585 node_ptr m_left_leaf; 0586 node_ptr m_right_leaf; 0587 value_type m_init_val; 0588 bool m_valid_tree; 0589 }; 0590 0591 template<typename _Key, typename _Value> 0592 flat_segment_tree<_Key, _Value>::flat_segment_tree(key_type min_val, key_type max_val, value_type init_val) : 0593 m_root_node(static_cast<node*>(NULL)), 0594 m_left_leaf(new node(true)), 0595 m_right_leaf(new node(true)), 0596 m_init_val(init_val), 0597 m_valid_tree(false) 0598 { 0599 // we need to create two end nodes during initialization. 0600 m_left_leaf->value_leaf.key = min_val; 0601 m_left_leaf->value_leaf.value = init_val; 0602 m_left_leaf->right = m_right_leaf; 0603 0604 m_right_leaf->value_leaf.key = max_val; 0605 m_right_leaf->left = m_left_leaf; 0606 0607 // We don't ever use the value of the right leaf node, but we need the 0608 // value to be always the same, to make it easier to check for 0609 // equality. 0610 m_right_leaf->value_leaf.value = ::std::numeric_limits<value_type>::max(); 0611 } 0612 0613 template<typename _Key, typename _Value> 0614 flat_segment_tree<_Key, _Value>::flat_segment_tree(const flat_segment_tree<_Key, _Value>& r) : 0615 m_root_node(static_cast<node*>(NULL)), 0616 m_left_leaf(new node(static_cast<const node&>(*r.m_left_leaf))), 0617 m_right_leaf(static_cast<node*>(NULL)), 0618 m_init_val(r.m_init_val), 0619 m_valid_tree(false) // tree is invalid because we only copy the leaf nodes. 0620 { 0621 // Copy all the leaf nodes from the original instance. 0622 node* src_node = r.m_left_leaf.get(); 0623 node_ptr dest_node = m_left_leaf; 0624 while (true) 0625 { 0626 dest_node->right.reset(new node(*src_node->right)); 0627 0628 // Move on to the next source node. 0629 src_node = src_node->right.get(); 0630 0631 // Move on to the next destination node, and have the next node point 0632 // back to the previous node. 0633 node_ptr old_node = dest_node; 0634 dest_node = dest_node->right; 0635 dest_node->left = old_node; 0636 0637 if (src_node == r.m_right_leaf.get()) 0638 { 0639 // Reached the right most leaf node. We can stop here. 0640 m_right_leaf = dest_node; 0641 break; 0642 } 0643 } 0644 } 0645 0646 template<typename _Key, typename _Value> 0647 flat_segment_tree<_Key, _Value>::~flat_segment_tree() 0648 { 0649 disconnect_leaf_nodes(m_left_leaf.get(), m_right_leaf.get()); 0650 clear_tree(m_root_node.get()); 0651 disconnect_all_nodes(m_root_node.get()); 0652 } 0653 0654 template<typename _Key, typename _Value> 0655 void flat_segment_tree<_Key, _Value>::insert_segment_impl(key_type start_key, key_type end_key, value_type val, bool forward) 0656 { 0657 if (end_key < m_left_leaf->value_leaf.key || start_key > m_right_leaf->value_leaf.key) 0658 // The new segment does not overlap the current interval. 0659 return; 0660 0661 if (start_key < m_left_leaf->value_leaf.key) 0662 // The start value should not be smaller than the current minimum. 0663 start_key = m_left_leaf->value_leaf.key; 0664 0665 if (end_key > m_right_leaf->value_leaf.key) 0666 // The end value should not be larger than the current maximum. 0667 end_key = m_right_leaf->value_leaf.key; 0668 0669 if (start_key >= end_key) 0670 return; 0671 0672 // Find the node with value that either equals or is greater than the 0673 // start value. 0674 0675 node_ptr start_pos; 0676 if (forward) 0677 { 0678 start_pos = get_insertion_pos_leaf(start_key, m_left_leaf); 0679 } 0680 else 0681 { 0682 start_pos = get_insertion_pos_leaf_reverse(start_key, m_right_leaf); 0683 if (start_pos) 0684 start_pos = start_pos->right; 0685 else 0686 start_pos = m_left_leaf; 0687 } 0688 if (!start_pos) 0689 { 0690 // Insertion position not found. Bail out. 0691 assert(!"Insertion position not found. Bail out"); 0692 return; 0693 } 0694 0695 0696 node_ptr end_pos = get_insertion_pos_leaf(end_key, start_pos); 0697 if (!end_pos) 0698 end_pos = m_right_leaf; 0699 0700 node_ptr new_start_node; 0701 value_type old_value; 0702 0703 // Set the start node. 0704 0705 if (start_pos->value_leaf.key == start_key) 0706 { 0707 // Re-use the existing node, but save the old value for later. 0708 0709 if (start_pos->left && start_pos->left->value_leaf.value == val) 0710 { 0711 // Extend the existing segment. 0712 old_value = start_pos->value_leaf.value; 0713 new_start_node = start_pos->left; 0714 } 0715 else 0716 { 0717 // Update the value of the existing node. 0718 old_value = start_pos->value_leaf.value; 0719 start_pos->value_leaf.value = val; 0720 new_start_node = start_pos; 0721 } 0722 } 0723 else if (start_pos->left->value_leaf.value == val) 0724 { 0725 // Extend the existing segment. 0726 old_value = start_pos->left->value_leaf.value; 0727 new_start_node = start_pos->left; 0728 } 0729 else 0730 { 0731 // Insert a new node before the insertion position node. 0732 node_ptr new_node(new node(true)); 0733 new_node->value_leaf.key = start_key; 0734 new_node->value_leaf.value = val; 0735 new_start_node = new_node; 0736 0737 node_ptr left_node = start_pos->left; 0738 old_value = left_node->value_leaf.value; 0739 0740 // Link to the left node. 0741 link_nodes(left_node, new_node); 0742 0743 // Link to the right node. 0744 link_nodes(new_node, start_pos); 0745 } 0746 0747 node_ptr cur_node = new_start_node->right; 0748 while (cur_node != end_pos) 0749 { 0750 // Disconnect the link between the current node and the previous node. 0751 cur_node->left->right.reset(); 0752 cur_node->left.reset(); 0753 old_value = cur_node->value_leaf.value; 0754 0755 cur_node = cur_node->right; 0756 } 0757 0758 // Set the end node. 0759 0760 if (end_pos->value_leaf.key == end_key) 0761 { 0762 // The new segment ends exactly at the end node position. 0763 0764 if (end_pos->right && end_pos->value_leaf.value == val) 0765 { 0766 // Remove this node, and connect the new start node with the 0767 // node that comes after this node. 0768 new_start_node->right = end_pos->right; 0769 if (end_pos->right) 0770 end_pos->right->left = new_start_node; 0771 disconnect_all_nodes(end_pos.get()); 0772 } 0773 else 0774 { 0775 // Just link the new segment to this node. 0776 new_start_node->right = end_pos; 0777 end_pos->left = new_start_node; 0778 } 0779 } 0780 else if (old_value == val) 0781 { 0782 link_nodes(new_start_node, end_pos); 0783 } 0784 else 0785 { 0786 // Insert a new node before the insertion position node. 0787 node_ptr new_node(new node(true)); 0788 new_node->value_leaf.key = end_key; 0789 new_node->value_leaf.value = old_value; 0790 0791 // Link to the left node. 0792 link_nodes(new_start_node, new_node); 0793 0794 // Link to the right node. 0795 link_nodes(new_node, end_pos); 0796 } 0797 0798 m_valid_tree = false; 0799 } 0800 0801 template<typename _Key, typename _Value> 0802 void flat_segment_tree<_Key, _Value>::shift_left(key_type start_key, key_type end_key) 0803 { 0804 if (start_key >= end_key) 0805 return; 0806 0807 key_type left_leaf_key = m_left_leaf->value_leaf.key; 0808 key_type right_leaf_key = m_right_leaf->value_leaf.key; 0809 if (start_key < left_leaf_key || end_key < left_leaf_key) 0810 // invalid key value 0811 return; 0812 0813 if (start_key > right_leaf_key || end_key > right_leaf_key) 0814 // invalid key value. 0815 return; 0816 0817 node_ptr node_pos; 0818 if (left_leaf_key == start_key) 0819 node_pos = m_left_leaf; 0820 else 0821 // Get the first node with a key value equal to or greater than the 0822 // start key value. But we want to skip the leftmost node. 0823 node_pos = get_insertion_pos_leaf(start_key, m_left_leaf->right); 0824 0825 if (!node_pos) 0826 return; 0827 0828 key_type segment_size = end_key - start_key; 0829 0830 if (node_pos == m_right_leaf) 0831 { 0832 // The segment being removed begins after the last node before the 0833 // right-most node. 0834 0835 if (right_leaf_key <= end_key) 0836 { 0837 // The end position equals or is past the right-most node. 0838 append_new_segment(start_key); 0839 } 0840 else 0841 { 0842 // The end position stops before the right-most node. Simply 0843 // append the blank segment to the end. 0844 append_new_segment(right_leaf_key - segment_size); 0845 } 0846 return; 0847 } 0848 0849 if (end_key < node_pos->value_leaf.key) 0850 { 0851 // The removed segment does not overlap with any nodes. Simply 0852 // shift the key values of those nodes that come after the removed 0853 // segment. 0854 shift_leaf_key_left(node_pos, m_right_leaf, segment_size); 0855 append_new_segment(right_leaf_key - segment_size); 0856 m_valid_tree = false; 0857 return; 0858 } 0859 0860 // Move the first node to the starting position, and from there search 0861 // for the first node whose key value is greater than the end value. 0862 node_pos->value_leaf.key = start_key; 0863 node_ptr start_pos = node_pos; 0864 node_pos = node_pos->right; 0865 value_type last_seg_value = start_pos->value_leaf.value; 0866 while (node_pos.get() != m_right_leaf.get() && node_pos->value_leaf.key <= end_key) 0867 { 0868 last_seg_value = node_pos->value_leaf.value; 0869 node_ptr next = node_pos->right; 0870 disconnect_all_nodes(node_pos.get()); 0871 node_pos = next; 0872 } 0873 0874 start_pos->value_leaf.value = last_seg_value; 0875 start_pos->right = node_pos; 0876 node_pos->left = start_pos; 0877 if (start_pos->left && start_pos->left->value_leaf.value == start_pos->value_leaf.value) 0878 { 0879 // Removing a segment resulted in two consecutive segments with 0880 // identical value. Combine them by removing the 2nd redundant 0881 // node. 0882 start_pos->left->right = start_pos->right; 0883 start_pos->right->left = start_pos->left; 0884 disconnect_all_nodes(start_pos.get()); 0885 } 0886 0887 shift_leaf_key_left(node_pos, m_right_leaf, segment_size); 0888 m_valid_tree = false; 0889 0890 // Insert at the end a new segment with the initial base value, for 0891 // the length of the removed segment. 0892 append_new_segment(right_leaf_key - segment_size); 0893 } 0894 0895 template<typename _Key, typename _Value> 0896 void flat_segment_tree<_Key, _Value>::shift_right(key_type pos, key_type size, bool skip_start_node) 0897 { 0898 if (size <= 0) 0899 return; 0900 0901 if (pos < m_left_leaf->value_leaf.key || m_right_leaf->value_leaf.key <= pos) 0902 // specified position is out-of-bound 0903 return; 0904 0905 if (m_left_leaf->value_leaf.key == pos) 0906 { 0907 // Position is at the leftmost node. Shift all the other nodes, 0908 // and insert a new node at (pos + size) position. 0909 node_ptr cur_node = m_left_leaf->right; 0910 shift_leaf_key_right(cur_node, m_right_leaf, size); 0911 0912 if (m_left_leaf->value_leaf.value != m_init_val) 0913 { 0914 // The leftmost leaf node has a non-initial value. We need to 0915 // insert a new node to carry that value after the shift. 0916 node_ptr new_node(new node(true)); 0917 new_node->value_leaf.key = pos + size; 0918 new_node->value_leaf.value = m_left_leaf->value_leaf.value; 0919 m_left_leaf->value_leaf.value = m_init_val; 0920 new_node->left = m_left_leaf; 0921 new_node->right = m_left_leaf->right; 0922 m_left_leaf->right = new_node; 0923 } 0924 0925 m_valid_tree = false; 0926 return; 0927 } 0928 0929 // Get the first node with a key value equal to or greater than the 0930 // start key value. But we want to skip the leftmost node. 0931 node_ptr cur_node = get_insertion_pos_leaf(pos, m_left_leaf->right); 0932 0933 // If the point of insertion is at an existing node position, don't 0934 // shift that node but start with the one after it if that's 0935 // requested. 0936 if (skip_start_node && cur_node && cur_node->value_leaf.key == pos) 0937 cur_node = cur_node->right; 0938 0939 if (!cur_node) 0940 return; 0941 0942 shift_leaf_key_right(cur_node, m_right_leaf, size); 0943 m_valid_tree = false; 0944 } 0945 0946 template<typename _Key, typename _Value> 0947 bool flat_segment_tree<_Key, _Value>::search( 0948 key_type key, value_type& value, key_type* start_key, key_type* end_key) const 0949 { 0950 if (key < m_left_leaf->value_leaf.key || m_right_leaf->value_leaf.key <= key) 0951 // key value is out-of-bound. 0952 return false; 0953 0954 const node* pos = get_insertion_pos_leaf(key, m_left_leaf.get()); 0955 if (pos->value_leaf.key == key) 0956 { 0957 value = pos->value_leaf.value; 0958 if (start_key) 0959 *start_key = pos->value_leaf.key; 0960 if (end_key && pos->right) 0961 *end_key = pos->right->value_leaf.key; 0962 return true; 0963 } 0964 else if (pos->left && pos->left->value_leaf.key < key) 0965 { 0966 value = pos->left->value_leaf.value; 0967 if (start_key) 0968 *start_key = pos->left->value_leaf.key; 0969 if (end_key) 0970 *end_key = pos->value_leaf.key; 0971 return true; 0972 } 0973 0974 return false; 0975 } 0976 0977 template<typename _Key, typename _Value> 0978 bool flat_segment_tree<_Key, _Value>::search_tree( 0979 key_type key, value_type& value, key_type* start_key, key_type* end_key) const 0980 { 0981 if (!m_root_node || !m_valid_tree) 0982 { 0983 // either tree has not been built, or is in an invalid state. 0984 return false; 0985 } 0986 0987 if (key < m_left_leaf->value_leaf.key || m_right_leaf->value_leaf.key <= key) 0988 { 0989 // key value is out-of-bound. 0990 return false; 0991 } 0992 0993 // Descend down the tree through the last non-leaf layer. 0994 0995 node* cur_node = m_root_node.get(); 0996 while (true) 0997 { 0998 if (cur_node->left) 0999 { 1000 if (cur_node->left->is_leaf) 1001 break; 1002 1003 const nonleaf_value_type& v = cur_node->left->value_nonleaf; 1004 if (v.low <= key && key < v.high) 1005 { 1006 cur_node = cur_node->left.get(); 1007 continue; 1008 } 1009 } 1010 else 1011 { 1012 // left child node can't be missing ! 1013 return false; 1014 } 1015 1016 if (cur_node->right) 1017 { 1018 const nonleaf_value_type& v = cur_node->right->value_nonleaf; 1019 if (v.low <= key && key < v.high) 1020 { 1021 cur_node = cur_node->right.get(); 1022 continue; 1023 } 1024 } 1025 return false; 1026 } 1027 1028 assert(cur_node->left->is_leaf && cur_node->right->is_leaf); 1029 1030 key_type key1 = cur_node->left->value_leaf.key; 1031 key_type key2 = cur_node->right->value_leaf.key; 1032 1033 if (key1 <= key && key < key2) 1034 { 1035 cur_node = cur_node->left.get(); 1036 } 1037 else if (key2 <= key && key < cur_node->value_nonleaf.high) 1038 { 1039 cur_node = cur_node->right.get(); 1040 } 1041 else 1042 cur_node = NULL; 1043 1044 if (!cur_node) 1045 { 1046 return false; 1047 } 1048 1049 value = cur_node->value_leaf.value; 1050 if (start_key) 1051 *start_key = cur_node->value_leaf.key; 1052 1053 if (end_key) 1054 { 1055 assert(cur_node->right); 1056 if (cur_node->right) 1057 *end_key = cur_node->right->value_leaf.key; 1058 else 1059 // This should never happen, but just in case.... 1060 *end_key = m_right_leaf->value_leaf.key; 1061 } 1062 1063 return true; 1064 } 1065 1066 template<typename _Key, typename _Value> 1067 void flat_segment_tree<_Key, _Value>::build_tree() 1068 { 1069 if (!m_left_leaf) 1070 return; 1071 1072 clear_tree(m_root_node.get()); 1073 m_root_node = ::mdds::build_tree<node_ptr, node>(m_left_leaf); 1074 m_valid_tree = true; 1075 } 1076 1077 template<typename _Key, typename _Value> 1078 bool flat_segment_tree<_Key, _Value>::operator==(const flat_segment_tree<key_type, value_type>& r) const 1079 { 1080 const node* n1 = m_left_leaf.get(); 1081 const node* n2 = r.m_left_leaf.get(); 1082 1083 if ((!n1 && n2) || (n1 && !n2)) 1084 // Either one of them is NULL; 1085 return false; 1086 1087 while (n1) 1088 { 1089 if (!n2) 1090 return false; 1091 1092 if (!n1->equals(*n2)) 1093 return false; 1094 1095 n1 = n1->right.get(); 1096 n2 = n2->right.get(); 1097 } 1098 1099 if (n2) 1100 // n1 is NULL, but n2 is not. 1101 return false; 1102 1103 // All leaf nodes are equal. 1104 return true; 1105 } 1106 1107 template<typename _Key, typename _Value> 1108 typename flat_segment_tree<_Key, _Value>::node_ptr 1109 flat_segment_tree<_Key, _Value>::get_insertion_pos_leaf( 1110 key_type key, const node_ptr& start_pos) const 1111 { 1112 node_ptr cur_node = start_pos; 1113 while (cur_node) 1114 { 1115 if (key <= cur_node->value_leaf.key) 1116 { 1117 // Found the insertion position. 1118 return cur_node; 1119 } 1120 cur_node = cur_node->right; 1121 } 1122 return node_ptr(); 1123 } 1124 1125 template<typename _Key, typename _Value> 1126 typename flat_segment_tree<_Key, _Value>::node_ptr 1127 flat_segment_tree<_Key, _Value>::get_insertion_pos_leaf_reverse( 1128 key_type key, const node_ptr& start_pos) const 1129 { 1130 node_ptr cur_node = start_pos; 1131 while (cur_node) 1132 { 1133 if (key > cur_node->value_leaf.key) 1134 { 1135 // Found the insertion position. 1136 return cur_node; 1137 } 1138 cur_node = cur_node->left; 1139 } 1140 return node_ptr(); 1141 } 1142 1143 template<typename _Key, typename _Value> 1144 const typename flat_segment_tree<_Key, _Value>::node* 1145 flat_segment_tree<_Key, _Value>::get_insertion_pos_leaf(key_type key, const node* start_pos) const 1146 { 1147 const node* cur_node = start_pos; 1148 while (cur_node) 1149 { 1150 if (key <= cur_node->value_leaf.key) 1151 { 1152 // Found the insertion position. 1153 return cur_node; 1154 } 1155 cur_node = cur_node->right.get(); 1156 } 1157 return NULL; 1158 } 1159 1160 } // namespace mdds 1161 1162 #endif