mdds
flat_segment_tree.hpp
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
3  *
4  * Copyright (c) 2008-2017 Kohei Yoshida
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use,
10  * copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following
13  * conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  * OTHER DEALINGS IN THE SOFTWARE.
26  *
27  ************************************************************************/
28 
29 #ifndef INCLUDED_MDDS_FLAT_SEGMENT_TREE_HPP
30 #define INCLUDED_MDDS_FLAT_SEGMENT_TREE_HPP
31 
32 #include <iostream>
33 #include <sstream>
34 #include <utility>
35 #include <cassert>
36 
37 #include "mdds/node.hpp"
38 #include "mdds/flat_segment_tree_itr.hpp"
39 #include "mdds/global.hpp"
40 
41 #ifdef MDDS_UNIT_TEST
42 #include <cstdio>
43 #include <vector>
44 #endif
45 
46 namespace mdds {
47 
48 template<typename _Key, typename _Value>
50 {
51 public:
52  typedef _Key key_type;
53  typedef _Value value_type;
54  typedef size_t size_type;
55 
57  {
58  key_type low;
59  key_type high;
60 
61  bool operator== (const nonleaf_value_type& r) const
62  {
63  return low == r.low && high == r.high;
64  }
65 
67  : low(0)
68  , high(0)
69  {
70  }
71  };
72 
74  {
75  key_type key;
76  value_type value;
77 
78  bool operator== (const leaf_value_type& r) const
79  {
80  return key == r.key && value == r.value;
81  }
82 
84  : key(0)
85  , value()
86  {
87  }
88  };
89 
90  // Handlers required by the node template class.
92  struct init_handler;
93  struct dispose_handler;
94 #ifdef MDDS_UNIT_TEST
95  struct to_string_handler;
96 #endif
97 
99  typedef typename node::node_ptr node_ptr;
100 
102 
104  {
105  void operator() (__st::nonleaf_node<flat_segment_tree>& _self, const __st::node_base* left_node, const __st::node_base* right_node)
106  {
107  // Parent node should carry the range of all of its child nodes.
108  if (left_node)
109  {
110  _self.value_nonleaf.low =
111  left_node->is_leaf ?
112  static_cast<const node*>(left_node)->value_leaf.key :
113  static_cast<const nonleaf_node*>(left_node)->value_nonleaf.low;
114  }
115  else
116  {
117  // Having a left node is prerequisite.
118  throw general_error("flat_segment_tree::fill_nonleaf_value_handler: Having a left node is prerequisite.");
119  }
120 
121  if (right_node)
122  {
123  if (right_node->is_leaf)
124  {
125  // When the child nodes are leaf nodes, the upper bound
126  // must be the value of the node that comes after the
127  // right leaf node (if such node exists).
128  const node* p = static_cast<const node*>(right_node);
129  if (p->next)
130  _self.value_nonleaf.high = p->next->value_leaf.key;
131  else
132  _self.value_nonleaf.high = p->value_leaf.key;
133  }
134  else
135  {
136  _self.value_nonleaf.high = static_cast<const nonleaf_node*>(right_node)->value_nonleaf.high;
137  }
138  }
139  else
140  {
141  _self.value_nonleaf.high =
142  left_node->is_leaf ?
143  static_cast<const node*>(left_node)->value_leaf.key :
144  static_cast<const nonleaf_node*>(left_node)->value_nonleaf.high;
145  }
146  }
147  };
148 
149 #ifdef MDDS_UNIT_TEST
150  struct to_string_handler
151  {
152  std::string operator() (const node& _self) const
153  {
154  std::ostringstream os;
155  os << "(" << _self.value_leaf.key << ") ";
156  return os.str();
157  }
158 
159  std::string operator() (const mdds::__st::nonleaf_node<flat_segment_tree>& _self) const
160  {
161  std::ostringstream os;
162  os << "(" << _self.value_nonleaf.low << "-" << _self.value_nonleaf.high << ") ";
163  return os.str();
164  }
165  };
166 #endif
167 
169  {
170  void operator() (node& /*_self*/) {}
171  void operator() (__st::nonleaf_node<flat_segment_tree>& /*_self*/) {}
172  };
173 
175  {
176  void operator() (node& /*_self*/) {}
177  void operator() (__st::nonleaf_node<flat_segment_tree>& /*_self*/) {}
178  };
179 
180 private:
181 
182  friend struct ::mdds::__fst::itr_forward_handler<flat_segment_tree>;
183  friend struct ::mdds::__fst::itr_reverse_handler<flat_segment_tree>;
184 
185 public:
187  flat_segment_tree, ::mdds::__fst::itr_forward_handler<flat_segment_tree> >
188  {
189  typedef ::mdds::__fst::const_iterator_base<
191  base_type;
192  friend class flat_segment_tree;
193  public:
194  const_iterator() :
195  base_type(nullptr, false) {}
196 
197  private:
198  explicit const_iterator(const typename base_type::fst_type* _db, bool _end) :
199  base_type(_db, _end) {}
200 
201  explicit const_iterator(const typename base_type::fst_type* _db, const node* p) :
202  base_type(_db, p) {}
203  };
204 
206  flat_segment_tree, ::mdds::__fst::itr_reverse_handler<flat_segment_tree> >
207  {
208  typedef ::mdds::__fst::const_iterator_base<
210  base_type;
211  friend class flat_segment_tree;
212  public:
214  base_type(nullptr, false) {}
215  private:
216  explicit const_reverse_iterator(const typename base_type::fst_type* _db, bool _end) :
217  base_type(_db, _end) {}
218  };
219 
221 
230  {
231  return const_iterator(this, false);
232  }
233 
243  {
244  return const_iterator(this, true);
245  }
246 
256  {
257  return const_reverse_iterator(this, false);
258  }
259 
270  {
271  return const_reverse_iterator(this, true);
272  }
273 
285 
298 
310  flat_segment_tree(key_type min_val, key_type max_val, value_type init_val);
311 
316 
318 
324 
331 
337  void clear();
338 
353  std::pair<const_iterator, bool>
354  insert_front(key_type start_key, key_type end_key, value_type val)
355  {
356  return insert_segment_impl(start_key, end_key, val, true);
357  }
358 
374  std::pair<const_iterator, bool>
375  insert_back(key_type start_key, key_type end_key, value_type val)
376  {
377  return insert_segment_impl(start_key, end_key, val, false);
378  }
379 
395  std::pair<const_iterator, bool>
396  insert(const const_iterator& pos, key_type start_key, key_type end_key, value_type val);
397 
407  void shift_left(key_type start_key, key_type end_key);
408 
421  void shift_right(key_type pos, key_type size, bool skip_start_node);
422 
440  std::pair<const_iterator, bool>
441  search(key_type key, value_type& value, key_type* start_key = nullptr, key_type* end_key = nullptr) const;
442 
461  std::pair<const_iterator, bool>
462  search(const const_iterator& pos, key_type key, value_type& value, key_type* start_key = nullptr, key_type* end_key = nullptr) const;
463 
483  std::pair<const_iterator, bool>
484  search_tree(key_type key, value_type& value, key_type* start_key = nullptr, key_type* end_key = nullptr) const;
485 
491  void build_tree();
492 
497  bool is_tree_valid() const
498  {
499  return m_valid_tree;
500  }
501 
508 
509  bool operator !=(const flat_segment_tree<key_type, value_type>& r) const
510  {
511  return !operator==(r);
512  }
513 
514  key_type min_key() const
515  {
516  return m_left_leaf->value_leaf.key;
517  }
518 
519  key_type max_key() const
520  {
521  return m_right_leaf->value_leaf.key;
522  }
523 
524  value_type default_value() const
525  {
526  return m_init_val;
527  }
528 
534  size_type leaf_size() const;
535 
536 #ifdef MDDS_UNIT_TEST
537  nonleaf_node* get_root_node() const
538  {
539  return m_root_node;
540  }
541 
542  void dump_tree() const
543  {
544  using ::std::cout;
545  using ::std::endl;
546 
547  if (!m_valid_tree)
548  assert(!"attempted to dump an invalid tree!");
549 
550  size_t node_count = mdds::__st::tree_dumper<node, nonleaf_node>::dump(m_root_node);
551  size_t node_instance_count = node::get_instance_count();
552  size_t leaf_count = leaf_size();
553 
554  cout << "tree node count = " << node_count << "; node instance count = "
555  << node_instance_count << "; leaf node count = " << leaf_count << endl;
556 
557  assert(leaf_count == node_instance_count);
558  }
559 
560  void dump_leaf_nodes() const
561  {
562  using ::std::cout;
563  using ::std::endl;
564 
565  cout << "------------------------------------------" << endl;
566 
567  node_ptr cur_node = m_left_leaf;
568  long node_id = 0;
569  while (cur_node)
570  {
571  cout << " node " << node_id++ << ": key = " << cur_node->value_leaf.key
572  << "; value = " << cur_node->value_leaf.value
573  << endl;
574  cur_node = cur_node->next;
575  }
576  cout << endl << " node instance count = " << node::get_instance_count() << endl;
577  }
578 
586  bool verify_keys(const ::std::vector<key_type>& key_values) const
587  {
588  {
589  // Start from the left-most node, and traverse right.
590  node* cur_node = m_left_leaf.get();
591  typename ::std::vector<key_type>::const_iterator itr = key_values.begin(), itr_end = key_values.end();
592  for (; itr != itr_end; ++itr)
593  {
594  if (!cur_node)
595  // Position past the right-mode node. Invalid.
596  return false;
597 
598  if (cur_node->value_leaf.key != *itr)
599  // Key values differ.
600  return false;
601 
602  cur_node = cur_node->next.get();
603  }
604 
605  if (cur_node)
606  // At this point, we expect the current node to be at the position
607  // past the right-most node, which is nullptr.
608  return false;
609  }
610 
611  {
612  // Start from the right-most node, and traverse left.
613  node* cur_node = m_right_leaf.get();
614  typename ::std::vector<key_type>::const_reverse_iterator itr = key_values.rbegin(), itr_end = key_values.rend();
615  for (; itr != itr_end; ++itr)
616  {
617  if (!cur_node)
618  // Position past the left-mode node. Invalid.
619  return false;
620 
621  if (cur_node->value_leaf.key != *itr)
622  // Key values differ.
623  return false;
624 
625  cur_node = cur_node->prev.get();
626  }
627 
628  if (cur_node)
629  // Likewise, we expect the current position to be past the
630  // left-most node, in which case the node value is nullptr.
631  return false;
632  }
633 
634  return true;
635  }
636 
644  bool verify_values(const ::std::vector<value_type>& values) const
645  {
646  node* cur_node = m_left_leaf.get();
647  node* end_node = m_right_leaf.get();
648  typename ::std::vector<value_type>::const_iterator itr = values.begin(), itr_end = values.end();
649  for (; itr != itr_end; ++itr)
650  {
651  if (cur_node == end_node || !cur_node)
652  return false;
653 
654  if (cur_node->value_leaf.value != *itr)
655  // Key values differ.
656  return false;
657 
658  cur_node = cur_node->next.get();
659  }
660 
661  if (cur_node != end_node)
662  // At this point, we expect the current node to be at the end of
663  // range.
664  return false;
665 
666  return true;
667  }
668 #endif
669 
670 private:
671  flat_segment_tree(); // default constructor is not allowed.
672 
673  void append_new_segment(key_type start_key)
674  {
675  if (m_right_leaf->prev->value_leaf.key == start_key)
676  {
677  m_right_leaf->prev->value_leaf.value = m_init_val;
678  return;
679  }
680 
681 #ifdef MDDS_UNIT_TEST
682  // The start position must come after the position of the last node
683  // before the right-most node.
684  assert(m_right_leaf->prev->value_leaf.key < start_key);
685 #endif
686 
687  if (m_right_leaf->prev->value_leaf.value == m_init_val)
688  // The existing segment has the same value. No need to insert a
689  // new segment.
690  return;
691 
692  node_ptr new_node(new node);
693  new_node->value_leaf.key = start_key;
694  new_node->value_leaf.value = m_init_val;
695  new_node->prev = m_right_leaf->prev;
696  new_node->next = m_right_leaf;
697  m_right_leaf->prev->next = new_node;
698  m_right_leaf->prev = new_node;
699  m_valid_tree = false;
700  }
701 
702  ::std::pair<const_iterator, bool>
703  insert_segment_impl(key_type start_key, key_type end_key, value_type val, bool forward);
704 
705  ::std::pair<const_iterator, bool>
706  insert_to_pos(node_ptr& start_pos, key_type start_key, key_type end_key, value_type val);
707 
708  ::std::pair<const_iterator, bool>
709  search_impl(const node* pos, key_type key, value_type& value, key_type* start_key, key_type* end_key) const;
710 
711  const node* get_insertion_pos_leaf_reverse(key_type key, const node* start_pos) const;
712 
713  const node* get_insertion_pos_leaf(key_type key, const node* start_pos) const;
714 
715  static void shift_leaf_key_left(node_ptr& begin_node, node_ptr& end_node, key_type shift_value)
716  {
717  node* cur_node_p = begin_node.get();
718  node* end_node_p = end_node.get();
719  while (cur_node_p != end_node_p)
720  {
721  cur_node_p->value_leaf.key -= shift_value;
722  cur_node_p = cur_node_p->next.get();
723  }
724  }
725 
726  static void shift_leaf_key_right(node_ptr& cur_node, node_ptr& end_node, key_type shift_value)
727  {
728  key_type end_node_key = end_node->value_leaf.key;
729  while (cur_node.get() != end_node.get())
730  {
731  cur_node->value_leaf.key += shift_value;
732  if (cur_node->value_leaf.key < end_node_key)
733  {
734  // The node is still in-bound. Keep shifting.
735  cur_node = cur_node->next;
736  continue;
737  }
738 
739  // This node has been pushed outside the end node position.
740  // Remove all nodes that follows, and connect the previous node
741  // with the end node.
742 
743  node_ptr last_node = cur_node->prev;
744  while (cur_node.get() != end_node.get())
745  {
746  node_ptr next_node = cur_node->next;
747  disconnect_all_nodes(cur_node.get());
748  cur_node = next_node;
749  }
750  last_node->next = end_node;
751  end_node->prev = last_node;
752  return;
753  }
754  }
755 
756  void destroy();
757 
765  bool adjust_segment_range(key_type& start_key, key_type& end_key) const;
766 
767 private:
768  std::vector<nonleaf_node> m_nonleaf_node_pool;
769 
770  nonleaf_node* m_root_node;
771  node_ptr m_left_leaf;
772  node_ptr m_right_leaf;
773  value_type m_init_val;
774  bool m_valid_tree;
775 };
776 
777 template<typename _Key, typename _Value>
778 void
780 {
781  left.swap(right);
782 }
783 
784 } // namespace mdds
785 
786 #include "flat_segment_tree_def.inl"
787 
788 #endif
789 
790 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::pair< const_iterator, bool > insert_front(key_type start_key, key_type end_key, value_type val)
Definition: flat_segment_tree.hpp:354
void shift_left(key_type start_key, key_type end_key)
Definition: flat_segment_tree.hpp:205
const_segment_iterator end_segment() const
bool is_leaf
parent nonleaf_node
Definition: node.hpp:46
bool operator==(const nonleaf_value_type &r) const
high range value (non-inclusive)
Definition: flat_segment_tree.hpp:61
bool is_tree_valid() const
Definition: flat_segment_tree.hpp:497
std::pair< const_iterator, bool > search_tree(key_type key, value_type &value, key_type *start_key=nullptr, key_type *end_key=nullptr) const
std::pair< const_iterator, bool > insert(const const_iterator &pos, key_type start_key, key_type end_key, value_type val)
const_reverse_iterator rend() const
Definition: flat_segment_tree.hpp:269
Definition: flat_segment_tree_itr.hpp:37
Definition: flat_segment_tree.hpp:73
const_reverse_iterator rbegin() const
Definition: flat_segment_tree.hpp:255
const_iterator begin() const
Definition: flat_segment_tree.hpp:229
Definition: node.hpp:43
void swap(flat_segment_tree< key_type, value_type > &other)
const_iterator end() const
Definition: flat_segment_tree.hpp:242
Definition: node.hpp:53
Definition: global.hpp:58
std::pair< const_iterator, bool > search(key_type key, value_type &value, key_type *start_key=nullptr, key_type *end_key=nullptr) const
std::pair< const_iterator, bool > insert_back(key_type start_key, key_type end_key, value_type val)
Definition: flat_segment_tree.hpp:375
Definition: flat_segment_tree.hpp:49
Definition: flat_segment_tree.hpp:46
key_type high
low range value (inclusive)
Definition: flat_segment_tree.hpp:59
Definition: flat_segment_tree.hpp:56
flat_segment_tree< key_type, value_type > & operator=(const flat_segment_tree< key_type, value_type > &other)
Definition: flat_segment_tree_itr.hpp:67
const_segment_iterator begin_segment() const
Definition: flat_segment_tree_itr.hpp:94
size_type leaf_size() const
Definition: node.hpp:143
void shift_right(key_type pos, key_type size, bool skip_start_node)
Definition: flat_segment_tree.hpp:186
Definition: flat_segment_tree.hpp:103
Definition: flat_segment_tree.hpp:174
node_ptr next
previous sibling leaf node.
Definition: node.hpp:166
Definition: flat_segment_tree_itr.hpp:185
Definition: flat_segment_tree.hpp:168