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