Coverage Report

Created: 2026-04-29 07:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
518
    m_root_node(nullptr),
47
518
    m_left_leaf(new node),
48
518
    m_right_leaf(new node),
49
396
    m_init_val(init_val),
50
518
    m_valid_tree(false)
51
518
{
52
    // we need to create two end nodes during initialization.
53
518
    m_left_leaf->value_leaf.key = min_val;
54
518
    m_left_leaf->value_leaf.value = init_val;
55
518
    m_left_leaf->next = m_right_leaf;
56
57
518
    m_right_leaf->value_leaf.key = max_val;
58
518
    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
518
    m_right_leaf->value_leaf.value = init_val;
64
518
}
mdds::flat_segment_tree<unsigned int, float>::flat_segment_tree(unsigned int, unsigned int, float)
Line
Count
Source
46
198
    m_root_node(nullptr),
47
198
    m_left_leaf(new node),
48
198
    m_right_leaf(new node),
49
198
    m_init_val(init_val),
50
198
    m_valid_tree(false)
51
198
{
52
    // we need to create two end nodes during initialization.
53
198
    m_left_leaf->value_leaf.key = min_val;
54
198
    m_left_leaf->value_leaf.value = init_val;
55
198
    m_left_leaf->next = m_right_leaf;
56
57
198
    m_right_leaf->value_leaf.key = max_val;
58
198
    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
198
    m_right_leaf->value_leaf.value = init_val;
64
198
}
mdds::flat_segment_tree<unsigned int, bool>::flat_segment_tree(unsigned int, unsigned int, bool)
Line
Count
Source
46
198
    m_root_node(nullptr),
47
198
    m_left_leaf(new node),
48
198
    m_right_leaf(new node),
49
198
    m_init_val(init_val),
50
198
    m_valid_tree(false)
51
198
{
52
    // we need to create two end nodes during initialization.
53
198
    m_left_leaf->value_leaf.key = min_val;
54
198
    m_left_leaf->value_leaf.value = init_val;
55
198
    m_left_leaf->next = m_right_leaf;
56
57
198
    m_right_leaf->value_leaf.key = max_val;
58
198
    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
198
    m_right_leaf->value_leaf.value = init_val;
64
198
}
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
122
    m_root_node(nullptr),
47
122
    m_left_leaf(new node),
48
122
    m_right_leaf(new node),
49
122
    m_init_val(init_val),
50
122
    m_valid_tree(false)
51
122
{
52
    // we need to create two end nodes during initialization.
53
122
    m_left_leaf->value_leaf.key = min_val;
54
122
    m_left_leaf->value_leaf.value = init_val;
55
122
    m_left_leaf->next = m_right_leaf;
56
57
122
    m_right_leaf->value_leaf.key = max_val;
58
122
    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
122
    m_right_leaf->value_leaf.value = init_val;
64
122
}
65
66
template<typename _Key, typename _Value>
67
flat_segment_tree<_Key, _Value>::flat_segment_tree(const flat_segment_tree<_Key, _Value>& r) :
68
365
    m_root_node(nullptr),
69
365
    m_left_leaf(new node(static_cast<const node&>(*r.m_left_leaf))),
70
365
    m_right_leaf(static_cast<node*>(nullptr)),
71
365
    m_init_val(r.m_init_val),
72
365
    m_valid_tree(false) // tree is invalid because we only copy the leaf nodes.
73
365
{
74
    // Copy all the leaf nodes from the original instance.
75
365
    node* src_node = r.m_left_leaf.get();
76
365
    node_ptr dest_node = m_left_leaf;
77
605
    while (true)
78
605
    {
79
605
        dest_node->next.reset(new node(*src_node->next));
80
81
        // Move on to the next source node.
82
605
        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
605
        node_ptr old_node = dest_node;
87
605
        dest_node = dest_node->next;
88
605
        dest_node->prev = old_node;
89
90
605
        if (src_node == r.m_right_leaf.get())
91
365
        {
92
            // Reached the right most leaf node.  We can stop here.
93
365
            m_right_leaf = dest_node;
94
365
            break;
95
365
        }
96
605
    }
97
365
}
98
99
template<typename _Key, typename _Value>
100
flat_segment_tree<_Key, _Value>::~flat_segment_tree()
101
883
{
102
883
    destroy();
103
883
}
mdds::flat_segment_tree<unsigned int, bool>::~flat_segment_tree()
Line
Count
Source
101
198
{
102
198
    destroy();
103
198
}
mdds::flat_segment_tree<unsigned int, float>::~flat_segment_tree()
Line
Count
Source
101
198
{
102
198
    destroy();
103
198
}
mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >::~flat_segment_tree()
Line
Count
Source
101
487
{
102
487
    destroy();
103
487
}
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
308
        else
167
308
            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
615
{
147
615
    typedef std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> ret_type;
148
149
615
    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
615
    node_ptr start_pos;
156
615
    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
615
    else
162
615
    {
163
615
        const node* p = get_insertion_pos_leaf_reverse(start_key, m_right_leaf.get());
164
615
        if (p)
165
460
            start_pos = p->next;
166
155
        else
167
155
            start_pos = m_left_leaf;
168
615
    }
169
615
    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
615
    return insert_to_pos(start_pos, start_key, end_key, val);
177
615
}
mdds::flat_segment_tree<unsigned int, bool>::insert_segment_impl(unsigned int, unsigned int, bool, bool)
Line
Count
Source
146
610
{
147
610
    typedef std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> ret_type;
148
149
610
    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
610
    node_ptr start_pos;
156
610
    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
610
    else
162
610
    {
163
610
        const node* p = get_insertion_pos_leaf_reverse(start_key, m_right_leaf.get());
164
610
        if (p)
165
457
            start_pos = p->next;
166
153
        else
167
153
            start_pos = m_left_leaf;
168
610
    }
169
610
    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
610
    return insert_to_pos(start_pos, start_key, end_key, val);
177
610
}
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
120
{
147
120
    typedef std::pair<typename flat_segment_tree<_Key, _Value>::const_iterator, bool> ret_type;
148
149
120
    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
120
    node_ptr start_pos;
156
120
    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
120
    else
162
120
    {
163
120
        const node* p = get_insertion_pos_leaf_reverse(start_key, m_right_leaf.get());
164
120
        if (p)
165
120
            start_pos = p->next;
166
0
        else
167
0
            start_pos = m_left_leaf;
168
120
    }
169
120
    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
120
    return insert_to_pos(start_pos, start_key, end_key, val);
177
120
}
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
767
    {
201
        // Re-use the existing node, but save the old value for later.
202
203
767
        if (start_pos->prev && start_pos->prev->value_leaf.value == val)
204
458
        {
205
            // Extend the existing segment.
206
458
            old_value = start_pos->value_leaf.value;
207
458
            new_start_node = start_pos->prev;
208
458
        }
209
309
        else
210
309
        {
211
            // Update the value of the existing node.
212
309
            old_value = start_pos->value_leaf.value;
213
309
            start_pos->value_leaf.value = val;
214
309
            new_start_node = start_pos;
215
216
309
            changed = (old_value != val);
217
309
        }
218
767
    }
219
578
    else if (start_pos->prev->value_leaf.value == val)
220
457
    {
221
        // Extend the existing segment.
222
457
        old_value = start_pos->prev->value_leaf.value;
223
457
        new_start_node = start_pos->prev;
224
457
    }
225
121
    else
226
121
    {
227
        // Insert a new node before the insertion position node.
228
121
        node_ptr new_node(new node);
229
121
        new_node->value_leaf.key = start_key;
230
121
        new_node->value_leaf.value = val;
231
121
        new_start_node = new_node;
232
233
121
        node_ptr left_node = start_pos->prev;
234
121
        old_value = left_node->value_leaf.value;
235
236
        // Link to the left node.
237
121
        __st::link_nodes<flat_segment_tree>(left_node, new_node);
238
239
        // Link to the right node.
240
121
        __st::link_nodes<flat_segment_tree>(new_node, start_pos);
241
121
        changed = true;
242
121
    }
243
244
1.34k
    node_ptr cur_node = new_start_node->next;
245
1.80k
    while (cur_node != end_pos)
246
458
    {
247
        // Disconnect the link between the current node and the previous node.
248
458
        cur_node->prev->next.reset();
249
458
        cur_node->prev.reset();
250
458
        old_value = cur_node->value_leaf.value;
251
252
458
        cur_node = cur_node->next;
253
458
        changed = true;
254
458
    }
255
256
    // Set the end node.
257
258
1.34k
    if (end_pos->value_leaf.key == end_key)
259
168
    {
260
        // The new segment ends exactly at the end node position.
261
262
168
        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
168
        else if (new_start_node->next != end_pos)
273
82
        {
274
            // Just link the new segment to this node.
275
82
            new_start_node->next = end_pos;
276
82
            end_pos->prev = new_start_node;
277
82
            changed = true;
278
82
        }
279
168
    }
280
1.17k
    else if (old_value == val)
281
527
    {
282
527
        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
527
    }
288
650
    else
289
650
    {
290
        // Insert a new node before the insertion position node.
291
650
        node_ptr new_node(new node);
292
650
        new_node->value_leaf.key = end_key;
293
650
        new_node->value_leaf.value = old_value;
294
295
        // Link to the left node.
296
650
        __st::link_nodes<flat_segment_tree>(new_start_node, new_node);
297
298
        // Link to the right node.
299
650
        __st::link_nodes<flat_segment_tree>(new_node, end_pos);
300
650
        changed = true;
301
650
    }
302
303
1.34k
    if (changed)
304
734
        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
615
{
184
615
    node_ptr end_pos;
185
615
    {
186
615
        const node* p = get_insertion_pos_leaf(end_key, start_pos.get());
187
615
        end_pos.reset(const_cast<node*>(p));
188
615
    }
189
615
    if (!end_pos)
190
0
        end_pos = m_right_leaf;
191
192
615
    node_ptr new_start_node;
193
615
    value_type old_value;
194
195
    // Set the start node.
196
197
615
    bool changed = false;
198
199
615
    if (start_pos->value_leaf.key == start_key)
200
614
    {
201
        // Re-use the existing node, but save the old value for later.
202
203
614
        if (start_pos->prev && start_pos->prev->value_leaf.value == val)
204
458
        {
205
            // Extend the existing segment.
206
458
            old_value = start_pos->value_leaf.value;
207
458
            new_start_node = start_pos->prev;
208
458
        }
209
156
        else
210
156
        {
211
            // Update the value of the existing node.
212
156
            old_value = start_pos->value_leaf.value;
213
156
            start_pos->value_leaf.value = val;
214
156
            new_start_node = start_pos;
215
216
156
            changed = (old_value != val);
217
156
        }
218
614
    }
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
615
    node_ptr cur_node = new_start_node->next;
245
1.07k
    while (cur_node != end_pos)
246
458
    {
247
        // Disconnect the link between the current node and the previous node.
248
458
        cur_node->prev->next.reset();
249
458
        cur_node->prev.reset();
250
458
        old_value = cur_node->value_leaf.value;
251
252
458
        cur_node = cur_node->next;
253
458
        changed = true;
254
458
    }
255
256
    // Set the end node.
257
258
615
    if (end_pos->value_leaf.key == end_key)
259
84
    {
260
        // The new segment ends exactly at the end node position.
261
262
84
        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
84
        else if (new_start_node->next != end_pos)
273
82
        {
274
            // Just link the new segment to this node.
275
82
            new_start_node->next = end_pos;
276
82
            end_pos->prev = new_start_node;
277
82
            changed = true;
278
82
        }
279
84
    }
280
531
    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
530
    else
289
530
    {
290
        // Insert a new node before the insertion position node.
291
530
        node_ptr new_node(new node);
292
530
        new_node->value_leaf.key = end_key;
293
530
        new_node->value_leaf.value = old_value;
294
295
        // Link to the left node.
296
530
        __st::link_nodes<flat_segment_tree>(new_start_node, new_node);
297
298
        // Link to the right node.
299
530
        __st::link_nodes<flat_segment_tree>(new_node, end_pos);
300
530
        changed = true;
301
530
    }
302
303
615
    if (changed)
304
614
        m_valid_tree = false;
305
306
615
    return ::std::pair<const_iterator, bool>(
307
615
        const_iterator(this, new_start_node.get()), changed);
308
615
}
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
610
{
184
610
    node_ptr end_pos;
185
610
    {
186
610
        const node* p = get_insertion_pos_leaf(end_key, start_pos.get());
187
610
        end_pos.reset(const_cast<node*>(p));
188
610
    }
189
610
    if (!end_pos)
190
0
        end_pos = m_right_leaf;
191
192
610
    node_ptr new_start_node;
193
610
    value_type old_value;
194
195
    // Set the start node.
196
197
610
    bool changed = false;
198
199
610
    if (start_pos->value_leaf.key == start_key)
200
153
    {
201
        // Re-use the existing node, but save the old value for later.
202
203
153
        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
153
        else
210
153
        {
211
            // Update the value of the existing node.
212
153
            old_value = start_pos->value_leaf.value;
213
153
            start_pos->value_leaf.value = val;
214
153
            new_start_node = start_pos;
215
216
153
            changed = (old_value != val);
217
153
        }
218
153
    }
219
457
    else if (start_pos->prev->value_leaf.value == val)
220
457
    {
221
        // Extend the existing segment.
222
457
        old_value = start_pos->prev->value_leaf.value;
223
457
        new_start_node = start_pos->prev;
224
457
    }
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
610
    node_ptr cur_node = new_start_node->next;
245
610
    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
610
    if (end_pos->value_leaf.key == end_key)
259
84
    {
260
        // The new segment ends exactly at the end node position.
261
262
84
        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
84
        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
84
    }
280
526
    else if (old_value == val)
281
526
    {
282
526
        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
526
    }
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
610
    if (changed)
304
0
        m_valid_tree = false;
305
306
610
    return ::std::pair<const_iterator, bool>(
307
610
        const_iterator(this, new_start_node.get()), changed);
308
610
}
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
120
{
184
120
    node_ptr end_pos;
185
120
    {
186
120
        const node* p = get_insertion_pos_leaf(end_key, start_pos.get());
187
120
        end_pos.reset(const_cast<node*>(p));
188
120
    }
189
120
    if (!end_pos)
190
0
        end_pos = m_right_leaf;
191
192
120
    node_ptr new_start_node;
193
120
    value_type old_value;
194
195
    // Set the start node.
196
197
120
    bool changed = false;
198
199
120
    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
120
    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
120
    else
226
120
    {
227
        // Insert a new node before the insertion position node.
228
120
        node_ptr new_node(new node);
229
120
        new_node->value_leaf.key = start_key;
230
120
        new_node->value_leaf.value = val;
231
120
        new_start_node = new_node;
232
233
120
        node_ptr left_node = start_pos->prev;
234
120
        old_value = left_node->value_leaf.value;
235
236
        // Link to the left node.
237
120
        __st::link_nodes<flat_segment_tree>(left_node, new_node);
238
239
        // Link to the right node.
240
120
        __st::link_nodes<flat_segment_tree>(new_node, start_pos);
241
120
        changed = true;
242
120
    }
243
244
120
    node_ptr cur_node = new_start_node->next;
245
120
    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
120
    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
120
    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
120
    else
289
120
    {
290
        // Insert a new node before the insertion position node.
291
120
        node_ptr new_node(new node);
292
120
        new_node->value_leaf.key = end_key;
293
120
        new_node->value_leaf.value = old_value;
294
295
        // Link to the left node.
296
120
        __st::link_nodes<flat_segment_tree>(new_start_node, new_node);
297
298
        // Link to the right node.
299
120
        __st::link_nodes<flat_segment_tree>(new_node, end_pos);
300
120
        changed = true;
301
120
    }
302
303
120
    if (changed)
304
120
        m_valid_tree = false;
305
306
120
    return ::std::pair<const_iterator, bool>(
307
120
        const_iterator(this, new_start_node.get()), changed);
308
120
}
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
502
{
580
502
    typedef std::pair<const_iterator, bool> ret_type;
581
502
    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
502
    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
502
    const nonleaf_node* cur_node = m_root_node;
596
1.00k
    while (true)
597
1.00k
    {
598
1.00k
        if (cur_node->left)
599
1.00k
        {
600
1.00k
            if (cur_node->left->is_leaf)
601
502
                break;
602
603
498
            const nonleaf_node* left_nonleaf = static_cast<const nonleaf_node*>(cur_node->left);
604
498
            const nonleaf_value_type& v = left_nonleaf->value_nonleaf;
605
498
            if (v.low <= key && key < v.high)
606
339
            {
607
                // Descend one level through the left child node.
608
339
                cur_node = left_nonleaf;
609
339
                continue;
610
339
            }
611
498
        }
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
159
        if (cur_node->right)
619
159
        {
620
159
            assert(!cur_node->right->is_leaf);
621
159
            const nonleaf_node* right_nonleaf = static_cast<const nonleaf_node*>(cur_node->right);
622
159
            const nonleaf_value_type& v = right_nonleaf->value_nonleaf;
623
159
            if (v.low <= key && key < v.high)
624
159
            {
625
                // Descend one level through the right child node.
626
159
                cur_node = right_nonleaf;
627
159
                continue;
628
159
            }
629
159
        }
630
0
        return ret_type(const_iterator(this, true), false);
631
159
    }
632
633
    // Current node must be a non-leaf whose child nodes are leaf nodes.
634
502
    assert(cur_node->left->is_leaf && cur_node->right->is_leaf);
635
636
502
    const node* dest_node = nullptr;
637
502
    const node* leaf_left = static_cast<const node*>(cur_node->left);
638
502
    const node* leaf_right = static_cast<const node*>(cur_node->right);
639
502
    key_type key1 = leaf_left->value_leaf.key;
640
502
    key_type key2 = leaf_right->value_leaf.key;
641
642
502
    if (key1 <= key && key < key2)
643
389
    {
644
389
        dest_node = leaf_left;
645
389
    }
646
113
    else if (key2 <= key && key < cur_node->value_nonleaf.high)
647
113
    {
648
113
        dest_node = leaf_right;
649
113
    }
650
651
502
    if (!dest_node)
652
0
    {
653
0
        return ret_type(const_iterator(this, true), false);
654
0
    }
655
656
502
    value = dest_node->value_leaf.value;
657
502
    if (start_key)
658
0
        *start_key = dest_node->value_leaf.key;
659
660
502
    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
502
    return ret_type(const_iterator(this, dest_node), true);
671
502
}
672
673
template<typename _Key, typename _Value>
674
void flat_segment_tree<_Key, _Value>::build_tree()
675
114
{
676
114
    if (!m_left_leaf)
677
0
        return;
678
679
114
    m_nonleaf_node_pool.clear();
680
681
    // Count the number of leaf nodes.
682
114
    size_t leaf_count = leaf_size();
683
684
    // Determine the total number of non-leaf nodes needed to build the whole tree.
685
114
    size_t nonleaf_count = __st::count_needed_nonleaf_nodes(leaf_count);
686
687
114
    m_nonleaf_node_pool.resize(nonleaf_count);
688
114
    mdds::__st::tree_builder<flat_segment_tree> builder(m_nonleaf_node_pool);
689
114
    m_root_node = builder.build(m_left_leaf);
690
114
    m_valid_tree = true;
691
114
}
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
114
{
697
114
    return __st::count_leaf_nodes(m_left_leaf.get(), m_right_leaf.get());
698
114
}
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.45k
    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.11k
        cur_node = cur_node->prev.get();
744
2.11k
    }
745
308
    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
615
{
735
615
    const node* cur_node = start_pos;
736
1.84k
    while (cur_node)
737
1.69k
    {
738
1.69k
        if (key > cur_node->value_leaf.key)
739
460
        {
740
            // Found the insertion position.
741
460
            return cur_node;
742
460
        }
743
1.23k
        cur_node = cur_node->prev.get();
744
1.23k
    }
745
155
    return nullptr;
746
615
}
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
610
{
735
610
    const node* cur_node = start_pos;
736
1.37k
    while (cur_node)
737
1.22k
    {
738
1.22k
        if (key > cur_node->value_leaf.key)
739
457
        {
740
            // Found the insertion position.
741
457
            return cur_node;
742
457
        }
743
763
        cur_node = cur_node->prev.get();
744
763
    }
745
153
    return nullptr;
746
610
}
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
120
{
735
120
    const node* cur_node = start_pos;
736
240
    while (cur_node)
737
240
    {
738
240
        if (key > cur_node->value_leaf.key)
739
120
        {
740
            // Found the insertion position.
741
120
            return cur_node;
742
120
        }
743
120
        cur_node = cur_node->prev.get();
744
120
    }
745
0
    return nullptr;
746
120
}
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.11k
    while (cur_node)
754
2.11k
    {
755
2.11k
        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
767
        cur_node = cur_node->next.get();
761
767
    }
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
615
{
752
615
    const node* cur_node = start_pos;
753
1.22k
    while (cur_node)
754
1.22k
    {
755
1.22k
        if (key <= cur_node->value_leaf.key)
756
615
        {
757
            // Found the insertion position.
758
615
            return cur_node;
759
615
        }
760
614
        cur_node = cur_node->next.get();
761
614
    }
762
0
    return nullptr;
763
615
}
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
610
{
752
610
    const node* cur_node = start_pos;
753
763
    while (cur_node)
754
763
    {
755
763
        if (key <= cur_node->value_leaf.key)
756
610
        {
757
            // Found the insertion position.
758
610
            return cur_node;
759
610
        }
760
153
        cur_node = cur_node->next.get();
761
153
    }
762
0
    return nullptr;
763
610
}
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
120
{
752
120
    const node* cur_node = start_pos;
753
120
    while (cur_node)
754
120
    {
755
120
        if (key <= cur_node->value_leaf.key)
756
120
        {
757
            // Found the insertion position.
758
120
            return cur_node;
759
120
        }
760
0
        cur_node = cur_node->next.get();
761
0
    }
762
0
    return nullptr;
763
120
}
764
765
template<typename _Key, typename _Value>
766
void
767
flat_segment_tree<_Key, _Value>::destroy()
768
883
{
769
883
    disconnect_leaf_nodes(m_left_leaf.get(), m_right_leaf.get());
770
883
    m_nonleaf_node_pool.clear();
771
883
    m_root_node = nullptr;
772
883
}
mdds::flat_segment_tree<unsigned int, bool>::destroy()
Line
Count
Source
768
198
{
769
198
    disconnect_leaf_nodes(m_left_leaf.get(), m_right_leaf.get());
770
198
    m_nonleaf_node_pool.clear();
771
198
    m_root_node = nullptr;
772
198
}
mdds::flat_segment_tree<unsigned int, float>::destroy()
Line
Count
Source
768
198
{
769
198
    disconnect_leaf_nodes(m_left_leaf.get(), m_right_leaf.get());
770
198
    m_nonleaf_node_pool.clear();
771
198
    m_root_node = nullptr;
772
198
}
mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >::destroy()
Line
Count
Source
768
487
{
769
487
    disconnect_leaf_nodes(m_left_leaf.get(), m_right_leaf.get());
770
487
    m_nonleaf_node_pool.clear();
771
487
    m_root_node = nullptr;
772
487
}
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
615
{
777
615
    if (start_key >= end_key)
778
        // Invalid order of segment range.
779
0
        return false;
780
781
615
    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
615
    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
615
    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
615
    return true;
794
615
}
mdds::flat_segment_tree<unsigned int, bool>::adjust_segment_range(unsigned int&, unsigned int&) const
Line
Count
Source
776
610
{
777
610
    if (start_key >= end_key)
778
        // Invalid order of segment range.
779
0
        return false;
780
781
610
    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
610
    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
610
    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
610
    return true;
794
610
}
mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >::adjust_segment_range(unsigned int&, unsigned int&) const
Line
Count
Source
776
120
{
777
120
    if (start_key >= end_key)
778
        // Invalid order of segment range.
779
0
        return false;
780
781
120
    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
120
    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
120
    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
120
    return true;
794
120
}
795
796
}