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