/src/mdds-1.3.1/include/mdds/flat_segment_tree_def.inl
Line | Count | Source |
1 | | /************************************************************************* |
2 | | * |
3 | | * Copyright (c) 2010-2017 Kohei Yoshida |
4 | | * |
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 |
12 | | * conditions: |
13 | | * |
14 | | * The above copyright notice and this permission notice shall be |
15 | | * included in all copies or substantial portions of the Software. |
16 | | * |
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. |
25 | | * |
26 | | ************************************************************************/ |
27 | | |
28 | | namespace mdds { |
29 | | |
30 | | template<typename _Key, typename _Value> |
31 | | typename flat_segment_tree<_Key, _Value>::const_segment_iterator |
32 | | flat_segment_tree<_Key, _Value>::begin_segment() const |
33 | | { |
34 | | return const_segment_iterator(m_left_leaf.get(), m_left_leaf->next.get()); |
35 | | } |
36 | | |
37 | | template<typename _Key, typename _Value> |
38 | | typename flat_segment_tree<_Key, _Value>::const_segment_iterator |
39 | | flat_segment_tree<_Key, _Value>::end_segment() const |
40 | | { |
41 | | return const_segment_iterator(m_right_leaf.get(), nullptr); |
42 | | } |
43 | | |
44 | | template<typename _Key, typename _Value> |
45 | | flat_segment_tree<_Key, _Value>::flat_segment_tree(key_type min_val, key_type max_val, value_type init_val) : |
46 | 501 | m_root_node(nullptr), |
47 | 501 | m_left_leaf(new node), |
48 | 501 | m_right_leaf(new node), |
49 | 392 | m_init_val(init_val), |
50 | 501 | m_valid_tree(false) |
51 | 501 | { |
52 | | // we need to create two end nodes during initialization. |
53 | 501 | m_left_leaf->value_leaf.key = min_val; |
54 | 501 | m_left_leaf->value_leaf.value = init_val; |
55 | 501 | m_left_leaf->next = m_right_leaf; |
56 | | |
57 | 501 | m_right_leaf->value_leaf.key = max_val; |
58 | 501 | m_right_leaf->prev = m_left_leaf; |
59 | | |
60 | | // We don't ever use the value of the right leaf node, but we need the |
61 | | // value to be always the same, to make it easier to check for |
62 | | // equality. |
63 | 501 | m_right_leaf->value_leaf.value = init_val; |
64 | 501 | } mdds::flat_segment_tree<unsigned int, float>::flat_segment_tree(unsigned int, unsigned int, float) Line | Count | Source | 46 | 196 | m_root_node(nullptr), | 47 | 196 | m_left_leaf(new node), | 48 | 196 | m_right_leaf(new node), | 49 | 196 | m_init_val(init_val), | 50 | 196 | m_valid_tree(false) | 51 | 196 | { | 52 | | // we need to create two end nodes during initialization. | 53 | 196 | m_left_leaf->value_leaf.key = min_val; | 54 | 196 | m_left_leaf->value_leaf.value = init_val; | 55 | 196 | m_left_leaf->next = m_right_leaf; | 56 | | | 57 | 196 | m_right_leaf->value_leaf.key = max_val; | 58 | 196 | m_right_leaf->prev = m_left_leaf; | 59 | | | 60 | | // We don't ever use the value of the right leaf node, but we need the | 61 | | // value to be always the same, to make it easier to check for | 62 | | // equality. | 63 | 196 | m_right_leaf->value_leaf.value = init_val; | 64 | 196 | } |
mdds::flat_segment_tree<unsigned int, bool>::flat_segment_tree(unsigned int, unsigned int, bool) Line | Count | Source | 46 | 196 | m_root_node(nullptr), | 47 | 196 | m_left_leaf(new node), | 48 | 196 | m_right_leaf(new node), | 49 | 196 | m_init_val(init_val), | 50 | 196 | m_valid_tree(false) | 51 | 196 | { | 52 | | // we need to create two end nodes during initialization. | 53 | 196 | m_left_leaf->value_leaf.key = min_val; | 54 | 196 | m_left_leaf->value_leaf.value = init_val; | 55 | 196 | m_left_leaf->next = m_right_leaf; | 56 | | | 57 | 196 | m_right_leaf->value_leaf.key = max_val; | 58 | 196 | m_right_leaf->prev = m_left_leaf; | 59 | | | 60 | | // We don't ever use the value of the right leaf node, but we need the | 61 | | // value to be always the same, to make it easier to check for | 62 | | // equality. | 63 | 196 | m_right_leaf->value_leaf.value = init_val; | 64 | 196 | } |
mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >::flat_segment_tree(unsigned int, unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle>) Line | Count | Source | 46 | 109 | m_root_node(nullptr), | 47 | 109 | m_left_leaf(new node), | 48 | 109 | m_right_leaf(new node), | 49 | 109 | m_init_val(init_val), | 50 | 109 | m_valid_tree(false) | 51 | 109 | { | 52 | | // we need to create two end nodes during initialization. | 53 | 109 | m_left_leaf->value_leaf.key = min_val; | 54 | 109 | m_left_leaf->value_leaf.value = init_val; | 55 | 109 | m_left_leaf->next = m_right_leaf; | 56 | | | 57 | 109 | m_right_leaf->value_leaf.key = max_val; | 58 | 109 | m_right_leaf->prev = m_left_leaf; | 59 | | | 60 | | // We don't ever use the value of the right leaf node, but we need the | 61 | | // value to be always the same, to make it easier to check for | 62 | | // equality. | 63 | 109 | m_right_leaf->value_leaf.value = init_val; | 64 | 109 | } |
|
65 | | |
66 | | template<typename _Key, typename _Value> |
67 | | flat_segment_tree<_Key, _Value>::flat_segment_tree(const flat_segment_tree<_Key, _Value>& r) : |
68 | 327 | m_root_node(nullptr), |
69 | 327 | m_left_leaf(new node(static_cast<const node&>(*r.m_left_leaf))), |
70 | 327 | m_right_leaf(static_cast<node*>(nullptr)), |
71 | 327 | m_init_val(r.m_init_val), |
72 | 327 | m_valid_tree(false) // tree is invalid because we only copy the leaf nodes. |
73 | 327 | { |
74 | | // Copy all the leaf nodes from the original instance. |
75 | 327 | node* src_node = r.m_left_leaf.get(); |
76 | 327 | node_ptr dest_node = m_left_leaf; |
77 | 543 | while (true) |
78 | 543 | { |
79 | 543 | dest_node->next.reset(new node(*src_node->next)); |
80 | | |
81 | | // Move on to the next source node. |
82 | 543 | src_node = src_node->next.get(); |
83 | | |
84 | | // Move on to the next destination node, and have the next node point |
85 | | // back to the previous node. |
86 | 543 | node_ptr old_node = dest_node; |
87 | 543 | dest_node = dest_node->next; |
88 | 543 | dest_node->prev = old_node; |
89 | | |
90 | 543 | if (src_node == r.m_right_leaf.get()) |
91 | 327 | { |
92 | | // Reached the right most leaf node. We can stop here. |
93 | 327 | m_right_leaf = dest_node; |
94 | 327 | break; |
95 | 327 | } |
96 | 543 | } |
97 | 327 | } |
98 | | |
99 | | template<typename _Key, typename _Value> |
100 | | flat_segment_tree<_Key, _Value>::~flat_segment_tree() |
101 | 828 | { |
102 | 828 | destroy(); |
103 | 828 | } mdds::flat_segment_tree<unsigned int, bool>::~flat_segment_tree() Line | Count | Source | 101 | 196 | { | 102 | 196 | destroy(); | 103 | 196 | } |
mdds::flat_segment_tree<unsigned int, float>::~flat_segment_tree() Line | Count | Source | 101 | 196 | { | 102 | 196 | destroy(); | 103 | 196 | } |
mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >::~flat_segment_tree() Line | Count | Source | 101 | 436 | { | 102 | 436 | destroy(); | 103 | 436 | } |
|
104 | | |
105 | | template<typename _Key, typename _Value> |
106 | | flat_segment_tree<_Key, _Value>& |
107 | | flat_segment_tree<_Key, _Value>::operator=(const flat_segment_tree<_Key, _Value>& other) |
108 | 0 | { |
109 | 0 | flat_segment_tree<_Key, _Value> copy(other); |
110 | 0 | swap(copy); |
111 | 0 | return *this; |
112 | 0 | } |
113 | | |
114 | | template<typename _Key, typename _Value> |
115 | | void |
116 | | flat_segment_tree<_Key, _Value>::swap(flat_segment_tree<_Key, _Value>& other) |
117 | 0 | { |
118 | 0 | using std::swap; |
119 | 0 | swap(m_root_node, other.m_root_node); |
120 | 0 | swap(m_left_leaf, other.m_left_leaf); |
121 | 0 | swap(m_right_leaf, other.m_right_leaf); |
122 | 0 | swap(m_init_val, other.m_init_val); |
123 | 0 | swap(m_valid_tree, other.m_valid_tree); |
124 | 0 | } |
125 | | |
126 | | template<typename _Key, typename _Value> |
127 | | void |
128 | | flat_segment_tree<_Key, _Value>::clear() |
129 | | { |
130 | | // the border nodes should not be destroyed--add a ref to keep them alive |
131 | | node_ptr left(m_left_leaf); |
132 | | node_ptr right(m_right_leaf); |
133 | | |
134 | | // destroy the tree |
135 | | destroy(); |
136 | | |
137 | | // and construct the default tree |
138 | | __st::link_nodes<flat_segment_tree>(m_left_leaf, m_right_leaf); |
139 | | m_left_leaf->value_leaf.value = m_init_val; |
140 | | m_valid_tree = false; |
141 | | } |
142 | | |
143 | | template<typename _Key, typename _Value> |
144 | | ::std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> |
145 | | flat_segment_tree<_Key, _Value>::insert_segment_impl(key_type start_key, key_type end_key, value_type val, bool forward) |
146 | 1.34k | { |
147 | 1.34k | typedef std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> ret_type; |
148 | | |
149 | 1.34k | if (!adjust_segment_range(start_key, end_key)) |
150 | 0 | return ret_type(const_iterator(this, true), false); |
151 | | |
152 | | // Find the node with value that either equals or is greater than the |
153 | | // start value. |
154 | | |
155 | 1.34k | node_ptr start_pos; |
156 | 1.34k | if (forward) |
157 | 0 | { |
158 | 0 | const node* p = get_insertion_pos_leaf(start_key, m_left_leaf.get()); |
159 | 0 | start_pos.reset(const_cast<node*>(p)); |
160 | 0 | } |
161 | 1.34k | else |
162 | 1.34k | { |
163 | 1.34k | const node* p = get_insertion_pos_leaf_reverse(start_key, m_right_leaf.get()); |
164 | 1.34k | if (p) |
165 | 1.03k | start_pos = p->next; |
166 | 312 | else |
167 | 312 | start_pos = m_left_leaf; |
168 | 1.34k | } |
169 | 1.34k | if (!start_pos) |
170 | 0 | { |
171 | | // Insertion position not found. Bail out. |
172 | 0 | assert(!"Insertion position not found. Bail out"); |
173 | 0 | return ret_type(const_iterator(this, true), false); |
174 | 0 | } |
175 | | |
176 | 1.34k | return insert_to_pos(start_pos, start_key, end_key, val); |
177 | 1.34k | } mdds::flat_segment_tree<unsigned int, float>::insert_segment_impl(unsigned int, unsigned int, float, bool) Line | Count | Source | 146 | 621 | { | 147 | 621 | typedef std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> ret_type; | 148 | | | 149 | 621 | if (!adjust_segment_range(start_key, end_key)) | 150 | 0 | return ret_type(const_iterator(this, true), false); | 151 | | | 152 | | // Find the node with value that either equals or is greater than the | 153 | | // start value. | 154 | | | 155 | 621 | node_ptr start_pos; | 156 | 621 | if (forward) | 157 | 0 | { | 158 | 0 | const node* p = get_insertion_pos_leaf(start_key, m_left_leaf.get()); | 159 | 0 | start_pos.reset(const_cast<node*>(p)); | 160 | 0 | } | 161 | 621 | else | 162 | 621 | { | 163 | 621 | const node* p = get_insertion_pos_leaf_reverse(start_key, m_right_leaf.get()); | 164 | 621 | if (p) | 165 | 464 | start_pos = p->next; | 166 | 157 | else | 167 | 157 | start_pos = m_left_leaf; | 168 | 621 | } | 169 | 621 | if (!start_pos) | 170 | 0 | { | 171 | | // Insertion position not found. Bail out. | 172 | 0 | assert(!"Insertion position not found. Bail out"); | 173 | 0 | return ret_type(const_iterator(this, true), false); | 174 | 0 | } | 175 | | | 176 | 621 | return insert_to_pos(start_pos, start_key, end_key, val); | 177 | 621 | } |
mdds::flat_segment_tree<unsigned int, bool>::insert_segment_impl(unsigned int, unsigned int, bool, bool) Line | Count | Source | 146 | 616 | { | 147 | 616 | typedef std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> ret_type; | 148 | | | 149 | 616 | if (!adjust_segment_range(start_key, end_key)) | 150 | 0 | return ret_type(const_iterator(this, true), false); | 151 | | | 152 | | // Find the node with value that either equals or is greater than the | 153 | | // start value. | 154 | | | 155 | 616 | node_ptr start_pos; | 156 | 616 | if (forward) | 157 | 0 | { | 158 | 0 | const node* p = get_insertion_pos_leaf(start_key, m_left_leaf.get()); | 159 | 0 | start_pos.reset(const_cast<node*>(p)); | 160 | 0 | } | 161 | 616 | else | 162 | 616 | { | 163 | 616 | const node* p = get_insertion_pos_leaf_reverse(start_key, m_right_leaf.get()); | 164 | 616 | if (p) | 165 | 461 | start_pos = p->next; | 166 | 155 | else | 167 | 155 | start_pos = m_left_leaf; | 168 | 616 | } | 169 | 616 | if (!start_pos) | 170 | 0 | { | 171 | | // Insertion position not found. Bail out. | 172 | 0 | assert(!"Insertion position not found. Bail out"); | 173 | 0 | return ret_type(const_iterator(this, true), false); | 174 | 0 | } | 175 | | | 176 | 616 | return insert_to_pos(start_pos, start_key, end_key, val); | 177 | 616 | } |
mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >::insert_segment_impl(unsigned int, unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle>, bool) Line | Count | Source | 146 | 108 | { | 147 | 108 | typedef std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> ret_type; | 148 | | | 149 | 108 | if (!adjust_segment_range(start_key, end_key)) | 150 | 0 | return ret_type(const_iterator(this, true), false); | 151 | | | 152 | | // Find the node with value that either equals or is greater than the | 153 | | // start value. | 154 | | | 155 | 108 | node_ptr start_pos; | 156 | 108 | if (forward) | 157 | 0 | { | 158 | 0 | const node* p = get_insertion_pos_leaf(start_key, m_left_leaf.get()); | 159 | 0 | start_pos.reset(const_cast<node*>(p)); | 160 | 0 | } | 161 | 108 | else | 162 | 108 | { | 163 | 108 | const node* p = get_insertion_pos_leaf_reverse(start_key, m_right_leaf.get()); | 164 | 108 | if (p) | 165 | 108 | start_pos = p->next; | 166 | 0 | else | 167 | 0 | start_pos = m_left_leaf; | 168 | 108 | } | 169 | 108 | if (!start_pos) | 170 | 0 | { | 171 | | // Insertion position not found. Bail out. | 172 | 0 | assert(!"Insertion position not found. Bail out"); | 173 | 0 | return ret_type(const_iterator(this, true), false); | 174 | 0 | } | 175 | | | 176 | 108 | return insert_to_pos(start_pos, start_key, end_key, val); | 177 | 108 | } |
|
178 | | |
179 | | template<typename _Key, typename _Value> |
180 | | ::std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> |
181 | | flat_segment_tree<_Key, _Value>::insert_to_pos( |
182 | | node_ptr& start_pos, key_type start_key, key_type end_key, value_type val) |
183 | 1.34k | { |
184 | 1.34k | node_ptr end_pos; |
185 | 1.34k | { |
186 | 1.34k | const node* p = get_insertion_pos_leaf(end_key, start_pos.get()); |
187 | 1.34k | end_pos.reset(const_cast<node*>(p)); |
188 | 1.34k | } |
189 | 1.34k | if (!end_pos) |
190 | 0 | end_pos = m_right_leaf; |
191 | | |
192 | 1.34k | node_ptr new_start_node; |
193 | 1.34k | value_type old_value; |
194 | | |
195 | | // Set the start node. |
196 | | |
197 | 1.34k | bool changed = false; |
198 | | |
199 | 1.34k | if (start_pos->value_leaf.key == start_key) |
200 | 775 | { |
201 | | // Re-use the existing node, but save the old value for later. |
202 | | |
203 | 775 | if (start_pos->prev && start_pos->prev->value_leaf.value == val) |
204 | 462 | { |
205 | | // Extend the existing segment. |
206 | 462 | old_value = start_pos->value_leaf.value; |
207 | 462 | new_start_node = start_pos->prev; |
208 | 462 | } |
209 | 313 | else |
210 | 313 | { |
211 | | // Update the value of the existing node. |
212 | 313 | old_value = start_pos->value_leaf.value; |
213 | 313 | start_pos->value_leaf.value = val; |
214 | 313 | new_start_node = start_pos; |
215 | | |
216 | 313 | changed = (old_value != val); |
217 | 313 | } |
218 | 775 | } |
219 | 570 | else if (start_pos->prev->value_leaf.value == val) |
220 | 461 | { |
221 | | // Extend the existing segment. |
222 | 461 | old_value = start_pos->prev->value_leaf.value; |
223 | 461 | new_start_node = start_pos->prev; |
224 | 461 | } |
225 | 109 | else |
226 | 109 | { |
227 | | // Insert a new node before the insertion position node. |
228 | 109 | node_ptr new_node(new node); |
229 | 109 | new_node->value_leaf.key = start_key; |
230 | 109 | new_node->value_leaf.value = val; |
231 | 109 | new_start_node = new_node; |
232 | | |
233 | 109 | node_ptr left_node = start_pos->prev; |
234 | 109 | old_value = left_node->value_leaf.value; |
235 | | |
236 | | // Link to the left node. |
237 | 109 | __st::link_nodes<flat_segment_tree>(left_node, new_node); |
238 | | |
239 | | // Link to the right node. |
240 | 109 | __st::link_nodes<flat_segment_tree>(new_node, start_pos); |
241 | 109 | changed = true; |
242 | 109 | } |
243 | | |
244 | 1.34k | node_ptr cur_node = new_start_node->next; |
245 | 1.80k | while (cur_node != end_pos) |
246 | 462 | { |
247 | | // Disconnect the link between the current node and the previous node. |
248 | 462 | cur_node->prev->next.reset(); |
249 | 462 | cur_node->prev.reset(); |
250 | 462 | old_value = cur_node->value_leaf.value; |
251 | | |
252 | 462 | cur_node = cur_node->next; |
253 | 462 | changed = true; |
254 | 462 | } |
255 | | |
256 | | // Set the end node. |
257 | | |
258 | 1.34k | if (end_pos->value_leaf.key == end_key) |
259 | 166 | { |
260 | | // The new segment ends exactly at the end node position. |
261 | | |
262 | 166 | if (end_pos->next && end_pos->value_leaf.value == val) |
263 | 0 | { |
264 | | // Remove this node, and connect the new start node with the |
265 | | // node that comes after this node. |
266 | 0 | new_start_node->next = end_pos->next; |
267 | 0 | if (end_pos->next) |
268 | 0 | end_pos->next->prev = new_start_node; |
269 | 0 | disconnect_all_nodes(end_pos.get()); |
270 | 0 | changed = true; |
271 | 0 | } |
272 | 166 | else if (new_start_node->next != end_pos) |
273 | 81 | { |
274 | | // Just link the new segment to this node. |
275 | 81 | new_start_node->next = end_pos; |
276 | 81 | end_pos->prev = new_start_node; |
277 | 81 | changed = true; |
278 | 81 | } |
279 | 166 | } |
280 | 1.17k | else if (old_value == val) |
281 | 534 | { |
282 | 534 | if (new_start_node->next != end_pos) |
283 | 0 | { |
284 | 0 | __st::link_nodes<flat_segment_tree>(new_start_node, end_pos); |
285 | 0 | changed = true; |
286 | 0 | } |
287 | 534 | } |
288 | 645 | else |
289 | 645 | { |
290 | | // Insert a new node before the insertion position node. |
291 | 645 | node_ptr new_node(new node); |
292 | 645 | new_node->value_leaf.key = end_key; |
293 | 645 | new_node->value_leaf.value = old_value; |
294 | | |
295 | | // Link to the left node. |
296 | 645 | __st::link_nodes<flat_segment_tree>(new_start_node, new_node); |
297 | | |
298 | | // Link to the right node. |
299 | 645 | __st::link_nodes<flat_segment_tree>(new_node, end_pos); |
300 | 645 | changed = true; |
301 | 645 | } |
302 | | |
303 | 1.34k | if (changed) |
304 | 728 | m_valid_tree = false; |
305 | | |
306 | 1.34k | return ::std::pair<const_iterator, bool>( |
307 | 1.34k | const_iterator(this, new_start_node.get()), changed); |
308 | 1.34k | } mdds::flat_segment_tree<unsigned int, float>::insert_to_pos(boost::intrusive_ptr<mdds::__st::node<mdds::flat_segment_tree<unsigned int, float> > >&, unsigned int, unsigned int, float) Line | Count | Source | 183 | 621 | { | 184 | 621 | node_ptr end_pos; | 185 | 621 | { | 186 | 621 | const node* p = get_insertion_pos_leaf(end_key, start_pos.get()); | 187 | 621 | end_pos.reset(const_cast<node*>(p)); | 188 | 621 | } | 189 | 621 | if (!end_pos) | 190 | 0 | end_pos = m_right_leaf; | 191 | | | 192 | 621 | node_ptr new_start_node; | 193 | 621 | value_type old_value; | 194 | | | 195 | | // Set the start node. | 196 | | | 197 | 621 | bool changed = false; | 198 | | | 199 | 621 | if (start_pos->value_leaf.key == start_key) | 200 | 620 | { | 201 | | // Re-use the existing node, but save the old value for later. | 202 | | | 203 | 620 | if (start_pos->prev && start_pos->prev->value_leaf.value == val) | 204 | 462 | { | 205 | | // Extend the existing segment. | 206 | 462 | old_value = start_pos->value_leaf.value; | 207 | 462 | new_start_node = start_pos->prev; | 208 | 462 | } | 209 | 158 | else | 210 | 158 | { | 211 | | // Update the value of the existing node. | 212 | 158 | old_value = start_pos->value_leaf.value; | 213 | 158 | start_pos->value_leaf.value = val; | 214 | 158 | new_start_node = start_pos; | 215 | | | 216 | 158 | changed = (old_value != val); | 217 | 158 | } | 218 | 620 | } | 219 | 1 | else if (start_pos->prev->value_leaf.value == val) | 220 | 0 | { | 221 | | // Extend the existing segment. | 222 | 0 | old_value = start_pos->prev->value_leaf.value; | 223 | 0 | new_start_node = start_pos->prev; | 224 | 0 | } | 225 | 1 | else | 226 | 1 | { | 227 | | // Insert a new node before the insertion position node. | 228 | 1 | node_ptr new_node(new node); | 229 | 1 | new_node->value_leaf.key = start_key; | 230 | 1 | new_node->value_leaf.value = val; | 231 | 1 | new_start_node = new_node; | 232 | | | 233 | 1 | node_ptr left_node = start_pos->prev; | 234 | 1 | old_value = left_node->value_leaf.value; | 235 | | | 236 | | // Link to the left node. | 237 | 1 | __st::link_nodes<flat_segment_tree>(left_node, new_node); | 238 | | | 239 | | // Link to the right node. | 240 | 1 | __st::link_nodes<flat_segment_tree>(new_node, start_pos); | 241 | 1 | changed = true; | 242 | 1 | } | 243 | | | 244 | 621 | node_ptr cur_node = new_start_node->next; | 245 | 1.08k | while (cur_node != end_pos) | 246 | 462 | { | 247 | | // Disconnect the link between the current node and the previous node. | 248 | 462 | cur_node->prev->next.reset(); | 249 | 462 | cur_node->prev.reset(); | 250 | 462 | old_value = cur_node->value_leaf.value; | 251 | | | 252 | 462 | cur_node = cur_node->next; | 253 | 462 | changed = true; | 254 | 462 | } | 255 | | | 256 | | // Set the end node. | 257 | | | 258 | 621 | if (end_pos->value_leaf.key == end_key) | 259 | 83 | { | 260 | | // The new segment ends exactly at the end node position. | 261 | | | 262 | 83 | if (end_pos->next && end_pos->value_leaf.value == val) | 263 | 0 | { | 264 | | // Remove this node, and connect the new start node with the | 265 | | // node that comes after this node. | 266 | 0 | new_start_node->next = end_pos->next; | 267 | 0 | if (end_pos->next) | 268 | 0 | end_pos->next->prev = new_start_node; | 269 | 0 | disconnect_all_nodes(end_pos.get()); | 270 | 0 | changed = true; | 271 | 0 | } | 272 | 83 | else if (new_start_node->next != end_pos) | 273 | 81 | { | 274 | | // Just link the new segment to this node. | 275 | 81 | new_start_node->next = end_pos; | 276 | 81 | end_pos->prev = new_start_node; | 277 | 81 | changed = true; | 278 | 81 | } | 279 | 83 | } | 280 | 538 | else if (old_value == val) | 281 | 1 | { | 282 | 1 | if (new_start_node->next != end_pos) | 283 | 0 | { | 284 | 0 | __st::link_nodes<flat_segment_tree>(new_start_node, end_pos); | 285 | 0 | changed = true; | 286 | 0 | } | 287 | 1 | } | 288 | 537 | else | 289 | 537 | { | 290 | | // Insert a new node before the insertion position node. | 291 | 537 | node_ptr new_node(new node); | 292 | 537 | new_node->value_leaf.key = end_key; | 293 | 537 | new_node->value_leaf.value = old_value; | 294 | | | 295 | | // Link to the left node. | 296 | 537 | __st::link_nodes<flat_segment_tree>(new_start_node, new_node); | 297 | | | 298 | | // Link to the right node. | 299 | 537 | __st::link_nodes<flat_segment_tree>(new_node, end_pos); | 300 | 537 | changed = true; | 301 | 537 | } | 302 | | | 303 | 621 | if (changed) | 304 | 620 | m_valid_tree = false; | 305 | | | 306 | 621 | return ::std::pair<const_iterator, bool>( | 307 | 621 | const_iterator(this, new_start_node.get()), changed); | 308 | 621 | } |
mdds::flat_segment_tree<unsigned int, bool>::insert_to_pos(boost::intrusive_ptr<mdds::__st::node<mdds::flat_segment_tree<unsigned int, bool> > >&, unsigned int, unsigned int, bool) Line | Count | Source | 183 | 616 | { | 184 | 616 | node_ptr end_pos; | 185 | 616 | { | 186 | 616 | const node* p = get_insertion_pos_leaf(end_key, start_pos.get()); | 187 | 616 | end_pos.reset(const_cast<node*>(p)); | 188 | 616 | } | 189 | 616 | if (!end_pos) | 190 | 0 | end_pos = m_right_leaf; | 191 | | | 192 | 616 | node_ptr new_start_node; | 193 | 616 | value_type old_value; | 194 | | | 195 | | // Set the start node. | 196 | | | 197 | 616 | bool changed = false; | 198 | | | 199 | 616 | if (start_pos->value_leaf.key == start_key) | 200 | 155 | { | 201 | | // Re-use the existing node, but save the old value for later. | 202 | | | 203 | 155 | if (start_pos->prev && start_pos->prev->value_leaf.value == val) | 204 | 0 | { | 205 | | // Extend the existing segment. | 206 | 0 | old_value = start_pos->value_leaf.value; | 207 | 0 | new_start_node = start_pos->prev; | 208 | 0 | } | 209 | 155 | else | 210 | 155 | { | 211 | | // Update the value of the existing node. | 212 | 155 | old_value = start_pos->value_leaf.value; | 213 | 155 | start_pos->value_leaf.value = val; | 214 | 155 | new_start_node = start_pos; | 215 | | | 216 | 155 | changed = (old_value != val); | 217 | 155 | } | 218 | 155 | } | 219 | 461 | else if (start_pos->prev->value_leaf.value == val) | 220 | 461 | { | 221 | | // Extend the existing segment. | 222 | 461 | old_value = start_pos->prev->value_leaf.value; | 223 | 461 | new_start_node = start_pos->prev; | 224 | 461 | } | 225 | 0 | else | 226 | 0 | { | 227 | | // Insert a new node before the insertion position node. | 228 | 0 | node_ptr new_node(new node); | 229 | 0 | new_node->value_leaf.key = start_key; | 230 | 0 | new_node->value_leaf.value = val; | 231 | 0 | new_start_node = new_node; | 232 | |
| 233 | 0 | node_ptr left_node = start_pos->prev; | 234 | 0 | old_value = left_node->value_leaf.value; | 235 | | | 236 | | // Link to the left node. | 237 | 0 | __st::link_nodes<flat_segment_tree>(left_node, new_node); | 238 | | | 239 | | // Link to the right node. | 240 | 0 | __st::link_nodes<flat_segment_tree>(new_node, start_pos); | 241 | 0 | changed = true; | 242 | 0 | } | 243 | | | 244 | 616 | node_ptr cur_node = new_start_node->next; | 245 | 616 | while (cur_node != end_pos) | 246 | 0 | { | 247 | | // Disconnect the link between the current node and the previous node. | 248 | 0 | cur_node->prev->next.reset(); | 249 | 0 | cur_node->prev.reset(); | 250 | 0 | old_value = cur_node->value_leaf.value; | 251 | |
| 252 | 0 | cur_node = cur_node->next; | 253 | 0 | changed = true; | 254 | 0 | } | 255 | | | 256 | | // Set the end node. | 257 | | | 258 | 616 | if (end_pos->value_leaf.key == end_key) | 259 | 83 | { | 260 | | // The new segment ends exactly at the end node position. | 261 | | | 262 | 83 | if (end_pos->next && end_pos->value_leaf.value == val) | 263 | 0 | { | 264 | | // Remove this node, and connect the new start node with the | 265 | | // node that comes after this node. | 266 | 0 | new_start_node->next = end_pos->next; | 267 | 0 | if (end_pos->next) | 268 | 0 | end_pos->next->prev = new_start_node; | 269 | 0 | disconnect_all_nodes(end_pos.get()); | 270 | 0 | changed = true; | 271 | 0 | } | 272 | 83 | else if (new_start_node->next != end_pos) | 273 | 0 | { | 274 | | // Just link the new segment to this node. | 275 | 0 | new_start_node->next = end_pos; | 276 | 0 | end_pos->prev = new_start_node; | 277 | 0 | changed = true; | 278 | 0 | } | 279 | 83 | } | 280 | 533 | else if (old_value == val) | 281 | 533 | { | 282 | 533 | if (new_start_node->next != end_pos) | 283 | 0 | { | 284 | 0 | __st::link_nodes<flat_segment_tree>(new_start_node, end_pos); | 285 | 0 | changed = true; | 286 | 0 | } | 287 | 533 | } | 288 | 0 | else | 289 | 0 | { | 290 | | // Insert a new node before the insertion position node. | 291 | 0 | node_ptr new_node(new node); | 292 | 0 | new_node->value_leaf.key = end_key; | 293 | 0 | new_node->value_leaf.value = old_value; | 294 | | | 295 | | // Link to the left node. | 296 | 0 | __st::link_nodes<flat_segment_tree>(new_start_node, new_node); | 297 | | | 298 | | // Link to the right node. | 299 | 0 | __st::link_nodes<flat_segment_tree>(new_node, end_pos); | 300 | 0 | changed = true; | 301 | 0 | } | 302 | | | 303 | 616 | if (changed) | 304 | 0 | m_valid_tree = false; | 305 | | | 306 | 616 | return ::std::pair<const_iterator, bool>( | 307 | 616 | const_iterator(this, new_start_node.get()), changed); | 308 | 616 | } |
mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >::insert_to_pos(boost::intrusive_ptr<mdds::__st::node<mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> > > >&, unsigned int, unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle>) Line | Count | Source | 183 | 108 | { | 184 | 108 | node_ptr end_pos; | 185 | 108 | { | 186 | 108 | const node* p = get_insertion_pos_leaf(end_key, start_pos.get()); | 187 | 108 | end_pos.reset(const_cast<node*>(p)); | 188 | 108 | } | 189 | 108 | if (!end_pos) | 190 | 0 | end_pos = m_right_leaf; | 191 | | | 192 | 108 | node_ptr new_start_node; | 193 | 108 | value_type old_value; | 194 | | | 195 | | // Set the start node. | 196 | | | 197 | 108 | bool changed = false; | 198 | | | 199 | 108 | if (start_pos->value_leaf.key == start_key) | 200 | 0 | { | 201 | | // Re-use the existing node, but save the old value for later. | 202 | |
| 203 | 0 | if (start_pos->prev && start_pos->prev->value_leaf.value == val) | 204 | 0 | { | 205 | | // Extend the existing segment. | 206 | 0 | old_value = start_pos->value_leaf.value; | 207 | 0 | new_start_node = start_pos->prev; | 208 | 0 | } | 209 | 0 | else | 210 | 0 | { | 211 | | // Update the value of the existing node. | 212 | 0 | old_value = start_pos->value_leaf.value; | 213 | 0 | start_pos->value_leaf.value = val; | 214 | 0 | new_start_node = start_pos; | 215 | |
| 216 | 0 | changed = (old_value != val); | 217 | 0 | } | 218 | 0 | } | 219 | 108 | else if (start_pos->prev->value_leaf.value == val) | 220 | 0 | { | 221 | | // Extend the existing segment. | 222 | 0 | old_value = start_pos->prev->value_leaf.value; | 223 | 0 | new_start_node = start_pos->prev; | 224 | 0 | } | 225 | 108 | else | 226 | 108 | { | 227 | | // Insert a new node before the insertion position node. | 228 | 108 | node_ptr new_node(new node); | 229 | 108 | new_node->value_leaf.key = start_key; | 230 | 108 | new_node->value_leaf.value = val; | 231 | 108 | new_start_node = new_node; | 232 | | | 233 | 108 | node_ptr left_node = start_pos->prev; | 234 | 108 | old_value = left_node->value_leaf.value; | 235 | | | 236 | | // Link to the left node. | 237 | 108 | __st::link_nodes<flat_segment_tree>(left_node, new_node); | 238 | | | 239 | | // Link to the right node. | 240 | 108 | __st::link_nodes<flat_segment_tree>(new_node, start_pos); | 241 | 108 | changed = true; | 242 | 108 | } | 243 | | | 244 | 108 | node_ptr cur_node = new_start_node->next; | 245 | 108 | while (cur_node != end_pos) | 246 | 0 | { | 247 | | // Disconnect the link between the current node and the previous node. | 248 | 0 | cur_node->prev->next.reset(); | 249 | 0 | cur_node->prev.reset(); | 250 | 0 | old_value = cur_node->value_leaf.value; | 251 | |
| 252 | 0 | cur_node = cur_node->next; | 253 | 0 | changed = true; | 254 | 0 | } | 255 | | | 256 | | // Set the end node. | 257 | | | 258 | 108 | if (end_pos->value_leaf.key == end_key) | 259 | 0 | { | 260 | | // The new segment ends exactly at the end node position. | 261 | |
| 262 | 0 | if (end_pos->next && end_pos->value_leaf.value == val) | 263 | 0 | { | 264 | | // Remove this node, and connect the new start node with the | 265 | | // node that comes after this node. | 266 | 0 | new_start_node->next = end_pos->next; | 267 | 0 | if (end_pos->next) | 268 | 0 | end_pos->next->prev = new_start_node; | 269 | 0 | disconnect_all_nodes(end_pos.get()); | 270 | 0 | changed = true; | 271 | 0 | } | 272 | 0 | else if (new_start_node->next != end_pos) | 273 | 0 | { | 274 | | // Just link the new segment to this node. | 275 | 0 | new_start_node->next = end_pos; | 276 | 0 | end_pos->prev = new_start_node; | 277 | 0 | changed = true; | 278 | 0 | } | 279 | 0 | } | 280 | 108 | else if (old_value == val) | 281 | 0 | { | 282 | 0 | if (new_start_node->next != end_pos) | 283 | 0 | { | 284 | 0 | __st::link_nodes<flat_segment_tree>(new_start_node, end_pos); | 285 | 0 | changed = true; | 286 | 0 | } | 287 | 0 | } | 288 | 108 | else | 289 | 108 | { | 290 | | // Insert a new node before the insertion position node. | 291 | 108 | node_ptr new_node(new node); | 292 | 108 | new_node->value_leaf.key = end_key; | 293 | 108 | new_node->value_leaf.value = old_value; | 294 | | | 295 | | // Link to the left node. | 296 | 108 | __st::link_nodes<flat_segment_tree>(new_start_node, new_node); | 297 | | | 298 | | // Link to the right node. | 299 | 108 | __st::link_nodes<flat_segment_tree>(new_node, end_pos); | 300 | 108 | changed = true; | 301 | 108 | } | 302 | | | 303 | 108 | if (changed) | 304 | 108 | m_valid_tree = false; | 305 | | | 306 | 108 | return ::std::pair<const_iterator, bool>( | 307 | 108 | const_iterator(this, new_start_node.get()), changed); | 308 | 108 | } |
|
309 | | |
310 | | template<typename _Key, typename _Value> |
311 | | ::std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> |
312 | | flat_segment_tree<_Key, _Value>::insert( |
313 | | const const_iterator& pos, key_type start_key, key_type end_key, value_type val) |
314 | | { |
315 | | const node* p = pos.get_pos(); |
316 | | if (!p || this != pos.get_parent()) |
317 | | { |
318 | | // Switch to normal insert. |
319 | | return insert_front(start_key, end_key, val); |
320 | | } |
321 | | |
322 | | assert(p->is_leaf); |
323 | | |
324 | | if (start_key < p->value_leaf.key) |
325 | | { |
326 | | // Specified position is already past the start key position. Not good. |
327 | | return insert_front(start_key, end_key, val); |
328 | | } |
329 | | |
330 | | if (!adjust_segment_range(start_key, end_key)) |
331 | | { |
332 | | typedef std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> ret_type; |
333 | | return ret_type(const_iterator(this, true), false); |
334 | | } |
335 | | |
336 | | p = get_insertion_pos_leaf(start_key, p); |
337 | | node_ptr start_pos(const_cast<node*>(p)); |
338 | | return insert_to_pos(start_pos, start_key, end_key, val); |
339 | | } |
340 | | |
341 | | template<typename _Key, typename _Value> |
342 | | void flat_segment_tree<_Key, _Value>::shift_left(key_type start_key, key_type end_key) |
343 | | { |
344 | | if (start_key >= end_key) |
345 | | return; |
346 | | |
347 | | key_type left_leaf_key = m_left_leaf->value_leaf.key; |
348 | | key_type right_leaf_key = m_right_leaf->value_leaf.key; |
349 | | if (start_key < left_leaf_key || end_key < left_leaf_key) |
350 | | // invalid key value |
351 | | return; |
352 | | |
353 | | if (start_key > right_leaf_key || end_key > right_leaf_key) |
354 | | // invalid key value. |
355 | | return; |
356 | | |
357 | | node_ptr node_pos; |
358 | | if (left_leaf_key == start_key) |
359 | | node_pos = m_left_leaf; |
360 | | else |
361 | | { |
362 | | // Get the first node with a key value equal to or greater than the |
363 | | // start key value. But we want to skip the leftmost node. |
364 | | const node* p = get_insertion_pos_leaf(start_key, m_left_leaf->next.get()); |
365 | | node_pos.reset(const_cast<node*>(p)); |
366 | | } |
367 | | |
368 | | if (!node_pos) |
369 | | return; |
370 | | |
371 | | key_type segment_size = end_key - start_key; |
372 | | |
373 | | if (node_pos == m_right_leaf) |
374 | | { |
375 | | // The segment being removed begins after the last node before the |
376 | | // right-most node. |
377 | | |
378 | | if (right_leaf_key <= end_key) |
379 | | { |
380 | | // The end position equals or is past the right-most node. |
381 | | append_new_segment(start_key); |
382 | | } |
383 | | else |
384 | | { |
385 | | // The end position stops before the right-most node. Simply |
386 | | // append the blank segment to the end. |
387 | | append_new_segment(right_leaf_key - segment_size); |
388 | | } |
389 | | return; |
390 | | } |
391 | | |
392 | | if (end_key < node_pos->value_leaf.key) |
393 | | { |
394 | | // The removed segment does not overlap with any nodes. Simply |
395 | | // shift the key values of those nodes that come after the removed |
396 | | // segment. |
397 | | shift_leaf_key_left(node_pos, m_right_leaf, segment_size); |
398 | | append_new_segment(right_leaf_key - segment_size); |
399 | | m_valid_tree = false; |
400 | | return; |
401 | | } |
402 | | |
403 | | // Move the first node to the starting position, and from there search |
404 | | // for the first node whose key value is greater than the end value. |
405 | | node_pos->value_leaf.key = start_key; |
406 | | node_ptr start_pos = node_pos; |
407 | | node_pos = node_pos->next; |
408 | | value_type last_seg_value = start_pos->value_leaf.value; |
409 | | while (node_pos.get() != m_right_leaf.get() && node_pos->value_leaf.key <= end_key) |
410 | | { |
411 | | last_seg_value = node_pos->value_leaf.value; |
412 | | node_ptr next = node_pos->next; |
413 | | disconnect_all_nodes(node_pos.get()); |
414 | | node_pos = next; |
415 | | } |
416 | | |
417 | | start_pos->value_leaf.value = last_seg_value; |
418 | | start_pos->next = node_pos; |
419 | | node_pos->prev = start_pos; |
420 | | if (start_pos->prev && start_pos->prev->value_leaf.value == start_pos->value_leaf.value) |
421 | | { |
422 | | // Removing a segment resulted in two consecutive segments with |
423 | | // identical value. Combine them by removing the 2nd redundant |
424 | | // node. |
425 | | start_pos->prev->next = start_pos->next; |
426 | | start_pos->next->prev = start_pos->prev; |
427 | | disconnect_all_nodes(start_pos.get()); |
428 | | } |
429 | | |
430 | | shift_leaf_key_left(node_pos, m_right_leaf, segment_size); |
431 | | m_valid_tree = false; |
432 | | |
433 | | // Insert at the end a new segment with the initial base value, for |
434 | | // the length of the removed segment. |
435 | | append_new_segment(right_leaf_key - segment_size); |
436 | | } |
437 | | |
438 | | template<typename _Key, typename _Value> |
439 | | void flat_segment_tree<_Key, _Value>::shift_right(key_type pos, key_type size, bool skip_start_node) |
440 | | { |
441 | | if (size <= 0) |
442 | | return; |
443 | | |
444 | | if (pos < m_left_leaf->value_leaf.key || m_right_leaf->value_leaf.key <= pos) |
445 | | // specified position is out-of-bound |
446 | | return; |
447 | | |
448 | | if (m_left_leaf->value_leaf.key == pos) |
449 | | { |
450 | | // Position is at the leftmost node. Shift all the other nodes, |
451 | | // and insert a new node at (pos + size) position. |
452 | | node_ptr cur_node = m_left_leaf->next; |
453 | | shift_leaf_key_right(cur_node, m_right_leaf, size); |
454 | | |
455 | | if (m_left_leaf->value_leaf.value != m_init_val && !skip_start_node) |
456 | | { |
457 | | if (size < m_right_leaf->value_leaf.key - m_left_leaf->value_leaf.key) |
458 | | { |
459 | | // The leftmost leaf node has a non-initial value. We need to |
460 | | // insert a new node to carry that value after the shift. |
461 | | node_ptr new_node(new node); |
462 | | new_node->value_leaf.key = pos + size; |
463 | | new_node->value_leaf.value = m_left_leaf->value_leaf.value; |
464 | | m_left_leaf->value_leaf.value = m_init_val; |
465 | | new_node->prev = m_left_leaf; |
466 | | new_node->next = m_left_leaf->next; |
467 | | m_left_leaf->next->prev = new_node; |
468 | | m_left_leaf->next = new_node; |
469 | | } |
470 | | else |
471 | | { |
472 | | // We shifted out the whole range, so there would be no new |
473 | | // node inserted. Just set default value. |
474 | | m_left_leaf->value_leaf.value = m_init_val; |
475 | | } |
476 | | } |
477 | | |
478 | | m_valid_tree = false; |
479 | | return; |
480 | | } |
481 | | |
482 | | // Get the first node with a key value equal to or greater than the |
483 | | // start key value. But we want to skip the leftmost node. |
484 | | const node* p = get_insertion_pos_leaf(pos, m_left_leaf->next.get()); |
485 | | node_ptr cur_node(const_cast<node*>(p)); |
486 | | |
487 | | // If the point of insertion is at an existing node position, don't |
488 | | // shift that node but start with the one after it if that's |
489 | | // requested. |
490 | | if (skip_start_node && cur_node && cur_node->value_leaf.key == pos) |
491 | | cur_node = cur_node->next; |
492 | | |
493 | | if (!cur_node) |
494 | | return; |
495 | | |
496 | | shift_leaf_key_right(cur_node, m_right_leaf, size); |
497 | | m_valid_tree = false; |
498 | | } |
499 | | |
500 | | template<typename _Key, typename _Value> |
501 | | ::std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> |
502 | | flat_segment_tree<_Key, _Value>::search_impl(const node* pos, |
503 | | key_type key, value_type& value, key_type* start_key, key_type* end_key) const |
504 | | { |
505 | | typedef ::std::pair<const_iterator, bool> ret_type; |
506 | | |
507 | | if (pos->value_leaf.key == key) |
508 | | { |
509 | | value = pos->value_leaf.value; |
510 | | if (start_key) |
511 | | *start_key = pos->value_leaf.key; |
512 | | if (end_key && pos->next) |
513 | | *end_key = pos->next->value_leaf.key; |
514 | | return ret_type(const_iterator(this, pos), true); |
515 | | } |
516 | | else if (pos->prev && pos->prev->value_leaf.key < key) |
517 | | { |
518 | | value = pos->prev->value_leaf.value; |
519 | | if (start_key) |
520 | | *start_key = pos->prev->value_leaf.key; |
521 | | if (end_key) |
522 | | *end_key = pos->value_leaf.key; |
523 | | return ret_type(const_iterator(this, pos->prev.get()), true); |
524 | | } |
525 | | |
526 | | return ret_type(const_iterator(this, true), false); |
527 | | } |
528 | | |
529 | | template<typename _Key, typename _Value> |
530 | | ::std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> |
531 | | flat_segment_tree<_Key, _Value>::search( |
532 | | key_type key, value_type& value, key_type* start_key, key_type* end_key) const |
533 | | { |
534 | | typedef ::std::pair<const_iterator, bool> ret_type; |
535 | | |
536 | | if (key < m_left_leaf->value_leaf.key || m_right_leaf->value_leaf.key <= key) |
537 | | // key value is out-of-bound. |
538 | | return ret_type(const_iterator(this, true), false); |
539 | | |
540 | | const node* pos = get_insertion_pos_leaf(key, m_left_leaf.get()); |
541 | | return search_impl(pos, key, value, start_key, end_key); |
542 | | } |
543 | | |
544 | | template<typename _Key, typename _Value> |
545 | | ::std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> |
546 | | flat_segment_tree<_Key, _Value>::search(const const_iterator& pos, |
547 | | key_type key, value_type& value, key_type* start_key, key_type* end_key) const |
548 | | { |
549 | | typedef ::std::pair<const_iterator, bool> ret_type; |
550 | | |
551 | | if (key < m_left_leaf->value_leaf.key || m_right_leaf->value_leaf.key <= key) |
552 | | // key value is out-of-bound. |
553 | | return ret_type(const_iterator(this, true), false); |
554 | | |
555 | | const node* p = pos.get_pos(); |
556 | | if (!p || this != pos.get_parent()) |
557 | | { |
558 | | // Switch to normal search. |
559 | | return search(key, value, start_key, end_key); |
560 | | } |
561 | | |
562 | | assert(p->is_leaf); |
563 | | |
564 | | if (key < p->value_leaf.key) |
565 | | { |
566 | | // Specified position is already past the start key position. Fall |
567 | | // back to normal search. |
568 | | return search(key, value, start_key, end_key); |
569 | | } |
570 | | |
571 | | p = get_insertion_pos_leaf(key, p); |
572 | | return search_impl(p, key, value, start_key, end_key); |
573 | | } |
574 | | |
575 | | template<typename _Key, typename _Value> |
576 | | std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> |
577 | | flat_segment_tree<_Key, _Value>::search_tree( |
578 | | key_type key, value_type& value, key_type* start_key, key_type* end_key) const |
579 | 458 | { |
580 | 458 | typedef std::pair<const_iterator, bool> ret_type; |
581 | 458 | if (!m_root_node || !m_valid_tree) |
582 | 0 | { |
583 | | // either tree has not been built, or is in an invalid state. |
584 | 0 | return ret_type(const_iterator(this, true), false); |
585 | 0 | } |
586 | | |
587 | 458 | if (key < m_left_leaf->value_leaf.key || m_right_leaf->value_leaf.key <= key) |
588 | 0 | { |
589 | | // key value is out-of-bound. |
590 | 0 | return ret_type(const_iterator(this, true), false); |
591 | 0 | } |
592 | | |
593 | | // Descend down the tree through the last non-leaf layer. |
594 | | |
595 | 458 | const nonleaf_node* cur_node = m_root_node; |
596 | 912 | while (true) |
597 | 912 | { |
598 | 912 | if (cur_node->left) |
599 | 912 | { |
600 | 912 | if (cur_node->left->is_leaf) |
601 | 458 | break; |
602 | | |
603 | 454 | const nonleaf_node* left_nonleaf = static_cast<const nonleaf_node*>(cur_node->left); |
604 | 454 | const nonleaf_value_type& v = left_nonleaf->value_nonleaf; |
605 | 454 | if (v.low <= key && key < v.high) |
606 | 309 | { |
607 | | // Descend one level through the left child node. |
608 | 309 | cur_node = left_nonleaf; |
609 | 309 | continue; |
610 | 309 | } |
611 | 454 | } |
612 | 0 | else |
613 | 0 | { |
614 | | // left child node can't be missing ! |
615 | 0 | return ret_type(const_iterator(this, true), false); |
616 | 0 | } |
617 | | |
618 | 145 | if (cur_node->right) |
619 | 145 | { |
620 | 145 | assert(!cur_node->right->is_leaf); |
621 | 145 | const nonleaf_node* right_nonleaf = static_cast<const nonleaf_node*>(cur_node->right); |
622 | 145 | const nonleaf_value_type& v = right_nonleaf->value_nonleaf; |
623 | 145 | if (v.low <= key && key < v.high) |
624 | 145 | { |
625 | | // Descend one level through the right child node. |
626 | 145 | cur_node = right_nonleaf; |
627 | 145 | continue; |
628 | 145 | } |
629 | 145 | } |
630 | 0 | return ret_type(const_iterator(this, true), false); |
631 | 145 | } |
632 | | |
633 | | // Current node must be a non-leaf whose child nodes are leaf nodes. |
634 | 458 | assert(cur_node->left->is_leaf && cur_node->right->is_leaf); |
635 | | |
636 | 458 | const node* dest_node = nullptr; |
637 | 458 | const node* leaf_left = static_cast<const node*>(cur_node->left); |
638 | 458 | const node* leaf_right = static_cast<const node*>(cur_node->right); |
639 | 458 | key_type key1 = leaf_left->value_leaf.key; |
640 | 458 | key_type key2 = leaf_right->value_leaf.key; |
641 | | |
642 | 458 | if (key1 <= key && key < key2) |
643 | 355 | { |
644 | 355 | dest_node = leaf_left; |
645 | 355 | } |
646 | 103 | else if (key2 <= key && key < cur_node->value_nonleaf.high) |
647 | 103 | { |
648 | 103 | dest_node = leaf_right; |
649 | 103 | } |
650 | | |
651 | 458 | if (!dest_node) |
652 | 0 | { |
653 | 0 | return ret_type(const_iterator(this, true), false); |
654 | 0 | } |
655 | | |
656 | 458 | value = dest_node->value_leaf.value; |
657 | 458 | if (start_key) |
658 | 0 | *start_key = dest_node->value_leaf.key; |
659 | | |
660 | 458 | if (end_key) |
661 | 0 | { |
662 | 0 | assert(dest_node->next); |
663 | 0 | if (dest_node->next) |
664 | 0 | *end_key = dest_node->next->value_leaf.key; |
665 | 0 | else |
666 | | // This should never happen, but just in case.... |
667 | 0 | *end_key = m_right_leaf->value_leaf.key; |
668 | 0 | } |
669 | | |
670 | 458 | return ret_type(const_iterator(this, dest_node), true); |
671 | 458 | } |
672 | | |
673 | | template<typename _Key, typename _Value> |
674 | | void flat_segment_tree<_Key, _Value>::build_tree() |
675 | 104 | { |
676 | 104 | if (!m_left_leaf) |
677 | 0 | return; |
678 | | |
679 | 104 | m_nonleaf_node_pool.clear(); |
680 | | |
681 | | // Count the number of leaf nodes. |
682 | 104 | size_t leaf_count = leaf_size(); |
683 | | |
684 | | // Determine the total number of non-leaf nodes needed to build the whole tree. |
685 | 104 | size_t nonleaf_count = __st::count_needed_nonleaf_nodes(leaf_count); |
686 | | |
687 | 104 | m_nonleaf_node_pool.resize(nonleaf_count); |
688 | 104 | mdds::__st::tree_builder<flat_segment_tree> builder(m_nonleaf_node_pool); |
689 | 104 | m_root_node = builder.build(m_left_leaf); |
690 | 104 | m_valid_tree = true; |
691 | 104 | } |
692 | | |
693 | | template<typename _Key, typename _Value> |
694 | | typename flat_segment_tree<_Key, _Value>::size_type |
695 | | flat_segment_tree<_Key, _Value>::leaf_size() const |
696 | 104 | { |
697 | 104 | return __st::count_leaf_nodes(m_left_leaf.get(), m_right_leaf.get()); |
698 | 104 | } |
699 | | |
700 | | template<typename _Key, typename _Value> |
701 | | bool flat_segment_tree<_Key, _Value>::operator==(const flat_segment_tree<key_type, value_type>& r) const |
702 | | { |
703 | | const node* n1 = m_left_leaf.get(); |
704 | | const node* n2 = r.m_left_leaf.get(); |
705 | | |
706 | | if ((!n1 && n2) || (n1 && !n2)) |
707 | | // Either one of them is nullptr; |
708 | | return false; |
709 | | |
710 | | while (n1) |
711 | | { |
712 | | if (!n2) |
713 | | return false; |
714 | | |
715 | | if (!n1->equals(*n2)) |
716 | | return false; |
717 | | |
718 | | n1 = n1->next.get(); |
719 | | n2 = n2->next.get(); |
720 | | } |
721 | | |
722 | | if (n2) |
723 | | // n1 is nullptr, but n2 is not. |
724 | | return false; |
725 | | |
726 | | // All leaf nodes are equal. |
727 | | return true; |
728 | | } |
729 | | |
730 | | template<typename _Key, typename _Value> |
731 | | const typename flat_segment_tree<_Key, _Value>::node* |
732 | | flat_segment_tree<_Key, _Value>::get_insertion_pos_leaf_reverse( |
733 | | key_type key, const node* start_pos) const |
734 | 1.34k | { |
735 | 1.34k | const node* cur_node = start_pos; |
736 | 3.46k | while (cur_node) |
737 | 3.15k | { |
738 | 3.15k | if (key > cur_node->value_leaf.key) |
739 | 1.03k | { |
740 | | // Found the insertion position. |
741 | 1.03k | return cur_node; |
742 | 1.03k | } |
743 | 2.12k | cur_node = cur_node->prev.get(); |
744 | 2.12k | } |
745 | 312 | return nullptr; |
746 | 1.34k | } mdds::flat_segment_tree<unsigned int, float>::get_insertion_pos_leaf_reverse(unsigned int, mdds::__st::node<mdds::flat_segment_tree<unsigned int, float> > const*) const Line | Count | Source | 734 | 621 | { | 735 | 621 | const node* cur_node = start_pos; | 736 | 1.86k | while (cur_node) | 737 | 1.70k | { | 738 | 1.70k | if (key > cur_node->value_leaf.key) | 739 | 464 | { | 740 | | // Found the insertion position. | 741 | 464 | return cur_node; | 742 | 464 | } | 743 | 1.24k | cur_node = cur_node->prev.get(); | 744 | 1.24k | } | 745 | 157 | return nullptr; | 746 | 621 | } |
mdds::flat_segment_tree<unsigned int, bool>::get_insertion_pos_leaf_reverse(unsigned int, mdds::__st::node<mdds::flat_segment_tree<unsigned int, bool> > const*) const Line | Count | Source | 734 | 616 | { | 735 | 616 | const node* cur_node = start_pos; | 736 | 1.38k | while (cur_node) | 737 | 1.23k | { | 738 | 1.23k | if (key > cur_node->value_leaf.key) | 739 | 461 | { | 740 | | // Found the insertion position. | 741 | 461 | return cur_node; | 742 | 461 | } | 743 | 771 | cur_node = cur_node->prev.get(); | 744 | 771 | } | 745 | 155 | return nullptr; | 746 | 616 | } |
mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >::get_insertion_pos_leaf_reverse(unsigned int, mdds::__st::node<mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> > > const*) const Line | Count | Source | 734 | 108 | { | 735 | 108 | const node* cur_node = start_pos; | 736 | 216 | while (cur_node) | 737 | 216 | { | 738 | 216 | if (key > cur_node->value_leaf.key) | 739 | 108 | { | 740 | | // Found the insertion position. | 741 | 108 | return cur_node; | 742 | 108 | } | 743 | 108 | cur_node = cur_node->prev.get(); | 744 | 108 | } | 745 | 0 | return nullptr; | 746 | 108 | } |
|
747 | | |
748 | | template<typename _Key, typename _Value> |
749 | | const typename flat_segment_tree<_Key, _Value>::node* |
750 | | flat_segment_tree<_Key, _Value>::get_insertion_pos_leaf(key_type key, const node* start_pos) const |
751 | 1.34k | { |
752 | 1.34k | const node* cur_node = start_pos; |
753 | 2.12k | while (cur_node) |
754 | 2.12k | { |
755 | 2.12k | if (key <= cur_node->value_leaf.key) |
756 | 1.34k | { |
757 | | // Found the insertion position. |
758 | 1.34k | return cur_node; |
759 | 1.34k | } |
760 | 775 | cur_node = cur_node->next.get(); |
761 | 775 | } |
762 | 0 | return nullptr; |
763 | 1.34k | } mdds::flat_segment_tree<unsigned int, float>::get_insertion_pos_leaf(unsigned int, mdds::__st::node<mdds::flat_segment_tree<unsigned int, float> > const*) const Line | Count | Source | 751 | 621 | { | 752 | 621 | const node* cur_node = start_pos; | 753 | 1.24k | while (cur_node) | 754 | 1.24k | { | 755 | 1.24k | if (key <= cur_node->value_leaf.key) | 756 | 621 | { | 757 | | // Found the insertion position. | 758 | 621 | return cur_node; | 759 | 621 | } | 760 | 620 | cur_node = cur_node->next.get(); | 761 | 620 | } | 762 | 0 | return nullptr; | 763 | 621 | } |
mdds::flat_segment_tree<unsigned int, bool>::get_insertion_pos_leaf(unsigned int, mdds::__st::node<mdds::flat_segment_tree<unsigned int, bool> > const*) const Line | Count | Source | 751 | 616 | { | 752 | 616 | const node* cur_node = start_pos; | 753 | 771 | while (cur_node) | 754 | 771 | { | 755 | 771 | if (key <= cur_node->value_leaf.key) | 756 | 616 | { | 757 | | // Found the insertion position. | 758 | 616 | return cur_node; | 759 | 616 | } | 760 | 155 | cur_node = cur_node->next.get(); | 761 | 155 | } | 762 | 0 | return nullptr; | 763 | 616 | } |
mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >::get_insertion_pos_leaf(unsigned int, mdds::__st::node<mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> > > const*) const Line | Count | Source | 751 | 108 | { | 752 | 108 | const node* cur_node = start_pos; | 753 | 108 | while (cur_node) | 754 | 108 | { | 755 | 108 | if (key <= cur_node->value_leaf.key) | 756 | 108 | { | 757 | | // Found the insertion position. | 758 | 108 | return cur_node; | 759 | 108 | } | 760 | 0 | cur_node = cur_node->next.get(); | 761 | 0 | } | 762 | 0 | return nullptr; | 763 | 108 | } |
|
764 | | |
765 | | template<typename _Key, typename _Value> |
766 | | void |
767 | | flat_segment_tree<_Key, _Value>::destroy() |
768 | 828 | { |
769 | 828 | disconnect_leaf_nodes(m_left_leaf.get(), m_right_leaf.get()); |
770 | 828 | m_nonleaf_node_pool.clear(); |
771 | 828 | m_root_node = nullptr; |
772 | 828 | } mdds::flat_segment_tree<unsigned int, bool>::destroy() Line | Count | Source | 768 | 196 | { | 769 | 196 | disconnect_leaf_nodes(m_left_leaf.get(), m_right_leaf.get()); | 770 | 196 | m_nonleaf_node_pool.clear(); | 771 | 196 | m_root_node = nullptr; | 772 | 196 | } |
mdds::flat_segment_tree<unsigned int, float>::destroy() Line | Count | Source | 768 | 196 | { | 769 | 196 | disconnect_leaf_nodes(m_left_leaf.get(), m_right_leaf.get()); | 770 | 196 | m_nonleaf_node_pool.clear(); | 771 | 196 | m_root_node = nullptr; | 772 | 196 | } |
mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >::destroy() Line | Count | Source | 768 | 436 | { | 769 | 436 | disconnect_leaf_nodes(m_left_leaf.get(), m_right_leaf.get()); | 770 | 436 | m_nonleaf_node_pool.clear(); | 771 | 436 | m_root_node = nullptr; | 772 | 436 | } |
|
773 | | |
774 | | template<typename _Key, typename _Value> |
775 | | bool flat_segment_tree<_Key, _Value>::adjust_segment_range(key_type& start_key, key_type& end_key) const |
776 | 1.34k | { |
777 | 1.34k | if (start_key >= end_key) |
778 | | // Invalid order of segment range. |
779 | 0 | return false; |
780 | | |
781 | 1.34k | if (end_key < m_left_leaf->value_leaf.key || start_key >= m_right_leaf->value_leaf.key) |
782 | | // The new segment does not overlap the current interval. |
783 | 0 | return false; |
784 | | |
785 | 1.34k | if (start_key < m_left_leaf->value_leaf.key) |
786 | | // The start value should not be smaller than the current minimum. |
787 | 0 | start_key = m_left_leaf->value_leaf.key; |
788 | | |
789 | 1.34k | if (end_key > m_right_leaf->value_leaf.key) |
790 | | // The end value should not be larger than the current maximum. |
791 | 0 | end_key = m_right_leaf->value_leaf.key; |
792 | | |
793 | 1.34k | return true; |
794 | 1.34k | } mdds::flat_segment_tree<unsigned int, float>::adjust_segment_range(unsigned int&, unsigned int&) const Line | Count | Source | 776 | 621 | { | 777 | 621 | if (start_key >= end_key) | 778 | | // Invalid order of segment range. | 779 | 0 | return false; | 780 | | | 781 | 621 | if (end_key < m_left_leaf->value_leaf.key || start_key >= m_right_leaf->value_leaf.key) | 782 | | // The new segment does not overlap the current interval. | 783 | 0 | return false; | 784 | | | 785 | 621 | if (start_key < m_left_leaf->value_leaf.key) | 786 | | // The start value should not be smaller than the current minimum. | 787 | 0 | start_key = m_left_leaf->value_leaf.key; | 788 | | | 789 | 621 | if (end_key > m_right_leaf->value_leaf.key) | 790 | | // The end value should not be larger than the current maximum. | 791 | 0 | end_key = m_right_leaf->value_leaf.key; | 792 | | | 793 | 621 | return true; | 794 | 621 | } |
mdds::flat_segment_tree<unsigned int, bool>::adjust_segment_range(unsigned int&, unsigned int&) const Line | Count | Source | 776 | 616 | { | 777 | 616 | if (start_key >= end_key) | 778 | | // Invalid order of segment range. | 779 | 0 | return false; | 780 | | | 781 | 616 | if (end_key < m_left_leaf->value_leaf.key || start_key >= m_right_leaf->value_leaf.key) | 782 | | // The new segment does not overlap the current interval. | 783 | 0 | return false; | 784 | | | 785 | 616 | if (start_key < m_left_leaf->value_leaf.key) | 786 | | // The start value should not be smaller than the current minimum. | 787 | 0 | start_key = m_left_leaf->value_leaf.key; | 788 | | | 789 | 616 | if (end_key > m_right_leaf->value_leaf.key) | 790 | | // The end value should not be larger than the current maximum. | 791 | 0 | end_key = m_right_leaf->value_leaf.key; | 792 | | | 793 | 616 | return true; | 794 | 616 | } |
mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >::adjust_segment_range(unsigned int&, unsigned int&) const Line | Count | Source | 776 | 108 | { | 777 | 108 | if (start_key >= end_key) | 778 | | // Invalid order of segment range. | 779 | 0 | return false; | 780 | | | 781 | 108 | if (end_key < m_left_leaf->value_leaf.key || start_key >= m_right_leaf->value_leaf.key) | 782 | | // The new segment does not overlap the current interval. | 783 | 0 | return false; | 784 | | | 785 | 108 | if (start_key < m_left_leaf->value_leaf.key) | 786 | | // The start value should not be smaller than the current minimum. | 787 | 0 | start_key = m_left_leaf->value_leaf.key; | 788 | | | 789 | 108 | if (end_key > m_right_leaf->value_leaf.key) | 790 | | // The end value should not be larger than the current maximum. | 791 | 0 | end_key = m_right_leaf->value_leaf.key; | 792 | | | 793 | 108 | return true; | 794 | 108 | } |
|
795 | | |
796 | | } |