b-tree-plus-alpha
Loading...
Searching...
No Matches
bp_internal_node_functions.hpp
1#pragma once
2#include "./bp_internal_node.hpp"
3
4namespace stool
5{
6 namespace bptree
7 {
8
13 template <typename LEAF_CONTAINER, typename VALUE, bool USE_PARENT_FIELD, uint64_t MAX_DEGREE, bool USE_PSUM>
15 {
17
18 public:
23
24
25 static uint64_t psum(const InternalNode &node)
26 {
27 if constexpr (USE_PSUM)
28 {
29 return node.psum_on_sum_deque();
30 }
31 else
32 {
33 throw std::runtime_error("BPInternalNodeFunctions::psum(): psum is not supported");
34 }
35 }
36
37 static uint64_t psum(const InternalNode &node, uint64_t i, const std::vector<LEAF_CONTAINER> &leaf_container_vec)
38 {
39
40 InternalNode *current_node = const_cast<InternalNode *>(&node);
41 uint64_t current_i = i;
42 bool _is_leaf = false;
43 uint64_t sum = 0;
44
45 while (!_is_leaf)
46 {
47 uint64_t tmp_i = 0;
48 int64_t search_result = current_node->search_query_on_count_deque(current_i + 1, tmp_i);
49
50 if (search_result != -1)
51 {
52 if (search_result != 0)
53 {
54 sum += current_node->psum_on_sum_deque(search_result - 1);
55 }
56
57 _is_leaf = current_node->is_parent_of_leaves();
58 current_node = current_node->get_child(search_result);
59
60 current_i -= tmp_i;
61 }
62 else
63 {
64 throw std::invalid_argument("BPInternalNodeFunctions::psum(), psum error");
65 }
66 }
67
68 uint64_t x = (uint64_t)current_node;
69 assert(x < leaf_container_vec.size());
70 assert(current_i < leaf_container_vec[x].size());
71
72 uint64_t leaf_psum = leaf_container_vec[x].psum(current_i);
73
74 return sum + leaf_psum;
75 }
76
77 static int64_t select0(const InternalNode &node, uint64_t i, const std::vector<LEAF_CONTAINER> &leaf_container_vec)
78 {
79 uint64_t nth = i + 1;
80 InternalNode *current_node = const_cast<InternalNode *>(&node);
81 uint64_t result = 0;
82 uint64_t current_psum = 0;
83 bool _is_leaf = false;
84
85 while (!_is_leaf)
86 {
87 bool b = false;
88 assert(current_psum <= nth);
89
90 for (uint64_t x = 0; x < current_node->children_count(); x++)
91 {
92 int64_t sub_count0 = current_node->access_count_deque(x) - current_node->access_sum_deque(x);
93 if (current_psum + sub_count0 >= nth)
94 {
95 _is_leaf = current_node->is_parent_of_leaves();
96 current_node = current_node->get_child(x);
97 b = true;
98 break;
99 }
100 else
101 {
102 current_psum += sub_count0;
103 result += current_node->access_count_deque(x);
104 }
105 }
106 if (!b)
107 {
108 throw std::invalid_argument("psum error");
109 }
110 }
111 uint64_t x = (uint64_t)current_node;
112 return result + leaf_container_vec[x].select0(i - current_psum);
113 }
114
115 static int64_t search(const InternalNode &node, uint64_t sum, const std::vector<LEAF_CONTAINER> &leaf_container_vec)
116 {
117 InternalNode *current_node = const_cast<InternalNode *>(&node);
118 uint64_t result = 0;
119 uint64_t current_psum = 0;
120 bool _is_leaf = false;
121
122 while (!_is_leaf)
123 {
124 // bool b = false;
125 assert(sum <= current_psum + current_node->psum_on_sum_deque());
126 assert(current_psum <= sum);
127 uint64_t tmp_psum = 0;
128 uint64_t search_sum = sum - current_psum;
129 int64_t search_result = current_node->search_query_on_sum_deque(search_sum, tmp_psum);
130 if (search_result != -1)
131 {
132 if (search_result != 0)
133 {
134 result += current_node->psum_on_count_deque(search_result - 1);
135 }
136
137 _is_leaf = current_node->is_parent_of_leaves();
138 current_node = current_node->get_child(search_result);
139 current_psum += tmp_psum;
140 }
141 else
142 {
143 std::cout << "sum: " << sum << " == True sum: " << current_psum << std::endl;
144 throw std::invalid_argument("BPInternalNodeFunctions::search(), psum error");
145 }
146 }
147
148 uint64_t x = (uint64_t)current_node;
149 return result + leaf_container_vec[x].search(sum - current_psum);
150 }
151
152 inline static uint64_t time_count = 0;
153 static std::pair<int64_t, uint64_t> access_child_index_by_value_index(const InternalNode &node, uint64_t value_index)
154 {
155 assert(value_index <= node.psum_on_count_deque());
156
157 uint64_t sum = 0;
158 int64_t search_result = node.search_query_on_count_deque(value_index + 1, sum);
159
160 auto pair = std::pair<int64_t, uint64_t>(search_result, value_index - sum);
161
162 return pair;
163 }
165
170
171
172 static void get_leaf_container_index_vector(const InternalNode &node, std::vector<uint64_t> &output)
173 {
174 if (!node.is_parent_of_leaves())
175 {
176 for (uint64_t i = 0; i < node.children_count(); i++)
177 {
178 InternalNode *child = node.get_child(i);
179 BPInternalNodeFunctions::get_leaf_container_index_vector(*child, output);
180 }
181 }
182 else
183 {
184 for (uint64_t i = 0; i < node.children_count(); i++)
185 {
186 InternalNode *child = node.get_child(i);
187 output.push_back((uint64_t)child);
188 }
189 }
190 }
191 static void to_value_vector(const InternalNode &node, std::vector<VALUE> &output, const std::vector<LEAF_CONTAINER> &leaf_container_vec)
192 {
193 std::vector<uint64_t> index_vector;
194 BPInternalNodeFunctions::get_leaf_container_index_vector(node, index_vector);
195
196 for (uint64_t i : index_vector)
197 {
198 std::vector<VALUE> tmp;
199 leaf_container_vec[i].to_values(tmp);
200
201 // std::vector<VALUE> tmp = leaf_container_vec[i].to_value_vector();
202 for (uint64_t j : tmp)
203 {
204 output.push_back(j);
205 }
206 }
207 }
208
209 static std::string to_string(const InternalNode &node, const std::vector<LEAF_CONTAINER> &leaf_container_vec)
210 {
211 std::vector<uint64_t> tmp;
212 BPInternalNodeFunctions::get_leaf_container_index_vector(node, tmp);
213
214 std::string s;
215 for (uint64_t idx : tmp)
216 {
217 s += leaf_container_vec[idx].to_string();
218 }
219 return s;
220 }
222
227
228
229 static uint64_t get_tree_string(const InternalNode &node, std::vector<std::string> &output, const std::vector<LEAF_CONTAINER> &leaf_container_vec)
230 {
231 uint64_t h = node.get_height();
232 while (output.size() <= h)
233 {
234 output.push_back("");
235 }
236
237 uint64_t width = 0;
238
239 if (node.is_parent_of_leaves())
240 {
241 std::string s1;
242 std::vector<uint64_t> tmp;
243 BPInternalNodeFunctions::get_leaf_container_index_vector(node, tmp);
244 for (uint64_t idx : tmp)
245 {
246 s1 += "([" + std::to_string(idx) + "]" + leaf_container_vec[idx].to_string() + "])";
247 }
248 output[0] += s1;
249 width = s1.size();
250 }
251 else
252 {
253 // uint64_t width = 0;
254
255 for (uint64_t i = 0; i < node.children_count(); i++)
256 {
257 InternalNode *child = node.get_child(i);
258 width += BPInternalNodeFunctions::get_tree_string(*child, output, leaf_container_vec);
259 }
260 }
261 std::string s = "";
262
263 std::string id_str;
264#if DEBUG
265 id_str = "[" + std::to_string(node.id) + "]";
266#endif
267
268 while (s.size() < width)
269 {
270 if (s.size() == 0)
271 {
272 s.push_back('[');
273 if (s.size() + id_str.size() < width)
274 {
275 s += id_str;
276 }
277 }
278 else if (s.size() + 1 == width)
279 {
280 s.push_back(']');
281 }
282 else
283 {
284
285 s.push_back('-');
286 }
287 }
288
289 output[h] += s;
290 return width;
291 }
292
293 static void print_tree(const InternalNode &node, const std::vector<LEAF_CONTAINER> &leaf_container_vec)
294 {
295 std::vector<std::string> tree;
296 BPInternalNodeFunctions::get_tree_string(node, tree, leaf_container_vec);
297 for (int64_t i = tree.size() - 1; i >= 0; i--)
298 {
299 std::cout << tree[i] << std::endl;
300 }
301 }
302 static bool verify(const InternalNode &node, const std::vector<LEAF_CONTAINER> &leaf_container_vec, uint64_t max_degree, bool is_root)
303 {
304#if DEBUG
305 if (node.id > (uint64_t)InternalNode::ID_COUNTER)
306 {
307 throw std::logic_error("Error(6): BPInternalNode::verify()");
308 }
309#endif
310
311 uint64_t value_count_sum = 0;
312 uint64_t value_sum_sum = 0;
313 bool b1 = true;
314
315 if (!is_root)
316 {
317 if (node.get_degree() > max_degree || node.get_degree() < (max_degree / 2))
318 {
319 throw std::logic_error("Error(3): BPInternalNode::verify()");
320 }
321 }
322 else
323 {
324 if (node.get_degree() > max_degree)
325 {
326 throw std::logic_error("Error(4): BPInternalNode::verify()");
327 }
328 }
329
330 if (node.is_parent_of_leaves())
331 {
332 for (uint64_t i = 0; i < node.children_count(); i++)
333 {
334 uint64_t x = (uint64_t)node.get_child(i);
335 value_count_sum += leaf_container_vec[x].size();
336 value_sum_sum += leaf_container_vec[x].psum();
337 }
338 }
339 else
340 {
341 bool p = node.get_child(0)->is_parent_of_leaves();
342 const stool::SimpleDeque16<InternalNode *> &children = node.get_children();
343
344 for (InternalNode *child : children)
345 {
346 value_count_sum += child->psum_on_count_deque();
347 value_sum_sum += child->psum_on_sum_deque();
348
349 if (p != child->is_parent_of_leaves())
350 {
351 b1 = false;
352 }
353 }
354 }
355
356 if constexpr (USE_PSUM)
357 {
358 if (node.is_parent_of_leaves())
359 {
360 for (uint64_t i = 0; i < node.children_count(); i++)
361 {
362 uint64_t x = (uint64_t)node.get_child(i);
363 uint64_t psum = leaf_container_vec[x].psum();
364 uint64_t psum2 = node.access_sum_deque(i);
365
366 if (psum != psum2)
367 {
368 std::cout << "Error: psum = " << psum << " == True psum: " << psum2 << std::endl;
369 throw std::logic_error("Error(5): BPInternalNode::verify()");
370 }
371 }
372 }
373 }
374
375 if (!(value_count_sum == node.psum_on_count_deque()))
376 {
377 std::cout << "Error: count = " << node.psum_on_count_deque() << " == True count: " << value_count_sum << std::endl;
378 // stool::Printer::print("Count VEC", node.children_value_count_deque_.to_deque());
379
380 // this->print_tree(leaf_container_vec);
381 throw std::logic_error("Error(1): BPInternalNode::verify()");
382 }
383
384 if constexpr (USE_PSUM)
385 {
386 if (!(value_sum_sum == node.psum_on_sum_deque()))
387 {
388 std::cout << "Error: sum = " << node.psum_on_sum_deque() << " == True sum: " << value_sum_sum << std::endl;
389 // this->print_tree(leaf_container_vec);
390 throw std::logic_error("Error(2): BPInternalNode::verify()");
391 }
392 }
393
394 if (node.get_degree() > max_degree)
395 {
396 throw std::logic_error("Error(3): BPInternalNode::verify()");
397 }
398 if (!b1)
399 {
400 throw std::logic_error("Error(4): BPInternalNode::verify()");
401 }
402
403 return true;
404 }
406
411
412 static void move_right(InternalNode &left_node, InternalNode &right_node, uint64_t len, InternalNode *parent, int64_t parent_edge_index, std::vector<InternalNode *> &parent_vec)
413 {
414
415 assert(left_node.is_parent_of_leaves() == right_node.is_parent_of_leaves());
416
417 if constexpr (USE_PSUM)
418 {
419
420 int64_t sum_delta = 0;
421 for (uint64_t i = 0; i < len; i++)
422 {
423 uint64_t _sum = left_node.access_last_item_on_sum_deque();
424 // uint64_t _sum = left_sum_deq[left_sum_deq.size() - 1];
425 left_node.pop_back_on_sum_deque();
426 right_node.push_front_on_sum_deque(_sum);
427 // left_sum_deq.pop_back();
428 // right_sum_deq.push_front(_sum);
429 sum_delta += _sum;
430 }
431
432 if (parent != nullptr)
433 {
434 parent->decrement_on_sum_deque(parent_edge_index, sum_delta);
435 parent->increment_on_sum_deque(parent_edge_index + 1, sum_delta);
436 }
437 }
438
439 {
440 int64_t count_delta = 0;
441
442 uint64_t left_children_size = left_node.children_count();
443
444 std::vector<uint64_t> tmp_count_array;
445 tmp_count_array.resize(len);
446
447 for (uint64_t i = 0; i < len; i++)
448 {
449 tmp_count_array[i] = left_node.access_count_deque(left_children_size - len + i);
450 }
451 count_delta += std::accumulate(tmp_count_array.begin(), tmp_count_array.end(), 0);
452 left_node.pop_back_many_on_count_deque(len);
453 right_node.push_front_many_on_count_deque(tmp_count_array);
454
455 /*
456 for (uint64_t i = 0; i < len; i++)
457 {
458 assert(left_node.children_count() > 0);
459 uint64_t _count = left_node.access_count_deque(left_children_size - 1);
460 left_children_size--;
461 left_node.pop_back_on_count_deque();
462 right_node.push_front_on_count_deque(_count);
463 count_delta += _count;
464 }
465 */
466
467 if (parent != nullptr)
468 {
469 parent->decrement_on_count_deque(parent_edge_index, count_delta);
470 parent->increment_on_count_deque(parent_edge_index + 1, count_delta);
471 }
472 }
473
474 stool::SimpleDeque16<InternalNode *> &left_children = left_node.get_children();
475 stool::SimpleDeque16<InternalNode *> &right_children = right_node.get_children();
476 for (uint64_t i = 0; i < len; i++)
477 {
478 assert(left_node.children_count() > 0);
479 InternalNode *top = left_children[left_children.size() - 1];
480 left_children.pop_back();
481 right_children.push_front(top);
482 if (USE_PARENT_FIELD)
483 {
484 if (left_node.is_parent_of_leaves())
485 {
486 parent_vec[(uint64_t)top] = &right_node;
487 }
488 else
489 {
490 top->set_parent(&right_node);
491 }
492 }
493 }
494 }
495
496 static void move_left(InternalNode &left_node, InternalNode &right_node, uint64_t len, InternalNode *parent, int64_t parent_edge_index, std::vector<InternalNode *> &parent_vec)
497 {
498
499 assert(right_node.is_parent_of_leaves() == left_node.is_parent_of_leaves());
500
501 if constexpr (USE_PSUM)
502 {
503
504 int64_t sum_delta = 0;
505 for (uint64_t i = 0; i < len; i++)
506 {
507 uint64_t _sum = right_node.access_sum_deque(0);
508 right_node.pop_front_on_sum_deque();
509 left_node.push_back_on_sum_deque(_sum);
510 sum_delta += _sum;
511 }
512
513 if (parent != nullptr)
514 {
515 parent->decrement_on_sum_deque(parent_edge_index, sum_delta);
516 parent->increment_on_sum_deque(parent_edge_index - 1, sum_delta);
517
518 // parent_sum_deq[parent_edge_index] -= sum_delta;
519 // parent_sum_deq[parent_edge_index - 1] += sum_delta;
520 }
521 }
522
523 {
524
525 int64_t count_delta = 0;
526 std::vector<uint64_t> tmp_count_array;
527 tmp_count_array.resize(len);
528 for (uint64_t i = 0; i < len; i++)
529 {
530 tmp_count_array[i] = right_node.access_count_deque(i);
531 }
532 count_delta += std::accumulate(tmp_count_array.begin(), tmp_count_array.end(), 0);
533 right_node.pop_front_many_on_count_deque(len);
534 left_node.push_back_many_on_count_deque(tmp_count_array);
535
536 /*
537 for (uint64_t i = 0; i < len; i++)
538 {
539 uint64_t _count = right_node.access_count_deque(0);
540 right_node.pop_front_on_count_deque();
541 left_node.push_back_on_count_deque(_count);
542 count_delta += _count;
543 }
544 */
545 if (parent != nullptr)
546 {
547 parent->decrement_on_count_deque(parent_edge_index, count_delta);
548 parent->increment_on_count_deque(parent_edge_index - 1, count_delta);
549 }
550 }
551
552 stool::SimpleDeque16<InternalNode *> &left_children = left_node.get_children();
553 stool::SimpleDeque16<InternalNode *> &right_children = right_node.get_children();
554
555 for (uint64_t i = 0; i < len; i++)
556 {
557 assert(right_node.children_count() > 0);
558 InternalNode *top = right_children[0];
559 right_children.pop_front();
560 left_children.push_back(top);
561 if (USE_PARENT_FIELD)
562 {
563 if (right_node.is_parent_of_leaves())
564 {
565 parent_vec[(uint64_t)top] = &left_node;
566 }
567 else
568 {
569 top->set_parent(&left_node);
570 }
571 }
572 }
573 }
574
576 };
577 }
578
579}
Helper functions of BPInternalNode [Unchecked AI's Comment].
Definition bp_internal_node_functions.hpp:15
The internal node of BPTree [Unchecked AI's Comment].
Definition bp_internal_node.hpp:15