b-tree-plus-alpha
Loading...
Searching...
No Matches
dynamic_wavelet_tree_for_range_search.hpp
1#pragma once
2#include "../sequence/dynamic_bit_sequence.hpp"
3#include "../prefix_sum/dynamic_prefix_sum.hpp"
4
5namespace stool
6{
7 namespace bptree
8 {
9
15 {
18
19 std::vector<BIT_SEQUENCE> bits_seq;
20 std::vector<PREFIX_SUM> length_seq;
21
22
23 //std::vector<stool::NaiveFLCVector<false>> leaves;
24
25 //inline static uint64_t LEAF_MAX_SIZE = 8;
26
27 public:
29 {
30 public:
31 using iterator_category = std::random_access_iterator_tag; // C++17
32 using value_type = uint64_t;
33 using difference_type = std::ptrdiff_t;
34
35 const DynamicWaveletTreeForRangeSearch *container = nullptr;
36 uint64_t x_rank = 0;
37 uint64_t y_rank = 0;
38 YRankIterator() : container(nullptr), x_rank(0), y_rank(0) {}
39 YRankIterator(const DynamicWaveletTreeForRangeSearch *container, uint64_t x_rank, uint64_t y_rank) : container(container), x_rank(x_rank), y_rank(y_rank) {}
40
41 uint64_t operator*() const noexcept { return this->x_rank; }
42
43 // 前後インクリメント
44 YRankIterator &operator++() noexcept
45 {
46 ++this->y_rank;
47 if (this->y_rank < this->container->size())
48 {
49 this->x_rank = this->container->access_x_rank(this->y_rank);
50 }
51 else
52 {
53 this->x_rank = this->container->size();
54 }
55 return *this;
56 }
57 YRankIterator operator++(int) noexcept
58 {
59 YRankIterator t = *this;
60 ++*this;
61 return t;
62 }
63 YRankIterator &operator--() noexcept
64 {
65 if (this->y_rank > 0)
66 {
67 this->y_rank--;
68 this->x_rank = this->container->access_x_rank(this->y_rank);
69 }
70 else
71 {
72 this->x_rank = this->container->size();
73 }
74 return *this;
75 }
76 YRankIterator operator--(int) noexcept
77 {
78 YRankIterator t = *this;
79 --*this;
80 return t;
81 }
82
83 // 加減算
84 YRankIterator &operator+=(difference_type n) noexcept
85 {
86 this->y_rank += n;
87 if (this->y_rank < this->container->size())
88 {
89 this->x_rank = this->container->access_x_rank(this->y_rank);
90 }
91 else
92 {
93 this->x_rank = this->container->size();
94 }
95 return *this;
96 }
97 YRankIterator &operator-=(difference_type n) noexcept
98 {
99 this->y_rank -= n;
100 if (this->y_rank < this->container->size())
101 {
102 this->x_rank = this->container->access_x_rank(this->y_rank);
103 }
104 else
105 {
106 this->x_rank = this->container->size();
107 }
108 return *this;
109 }
110 friend YRankIterator operator+(YRankIterator it, difference_type n) noexcept { return YRankIterator(it.container, it.y_rank + n, it.x_rank); }
111 friend YRankIterator operator+(difference_type n, YRankIterator it) noexcept { return it + n; }
112 friend YRankIterator operator-(YRankIterator it, difference_type n) noexcept { return YRankIterator(it.container, it.y_rank - n, it.x_rank); }
113 friend difference_type operator-(YRankIterator a, YRankIterator b) noexcept { return a.y_rank - b.y_rank; }
114
115 // 比較
116 friend bool operator==(YRankIterator a, YRankIterator b) noexcept { return a.y_rank == b.y_rank; }
117 friend bool operator!=(YRankIterator a, YRankIterator b) noexcept { return !(a == b); }
118 friend bool operator<(YRankIterator a, YRankIterator b) noexcept { return a.y_rank < b.y_rank; }
119 friend bool operator>(YRankIterator a, YRankIterator b) noexcept { return b < a; }
120 friend bool operator<=(YRankIterator a, YRankIterator b) noexcept { return !(b < a); }
121 friend bool operator>=(YRankIterator a, YRankIterator b) noexcept { return !(a < b); }
122 };
123
125 {
126 public:
127 using iterator_category = std::random_access_iterator_tag; // C++17
128 using value_type = uint64_t;
129 using difference_type = std::ptrdiff_t;
130
131 const DynamicWaveletTreeForRangeSearch *container = nullptr;
132 uint64_t x_rank = 0;
133 uint64_t y_rank = 0;
134 XRankIterator() : container(nullptr), x_rank(0), y_rank(0) {}
135 XRankIterator(const DynamicWaveletTreeForRangeSearch *container, uint64_t x_rank, uint64_t y_rank) : container(container), x_rank(x_rank), y_rank(y_rank) {}
136
137 uint64_t operator*() const noexcept { return this->y_rank; }
138
139 // 前後インクリメント
140 XRankIterator &operator++() noexcept
141 {
142 ++this->x_rank;
143 if (this->x_rank < this->container->size())
144 {
145 this->y_rank = this->container->access_y_rank(this->x_rank);
146 }
147 else
148 {
149 this->y_rank = this->container->size();
150 }
151 return *this;
152 }
153 XRankIterator operator++(int) noexcept
154 {
155 XRankIterator t = *this;
156 ++*this;
157 return t;
158 }
159 XRankIterator &operator--() noexcept
160 {
161 if (this->x_rank > 0)
162 {
163 this->x_rank--;
164 this->y_rank = this->container->access_y_rank(this->x_rank);
165 }
166 else
167 {
168 this->y_rank = this->container->size();
169 }
170 return *this;
171 }
172 XRankIterator operator--(int) noexcept
173 {
174 XRankIterator t = *this;
175 --*this;
176 return t;
177 }
178
179 // 加減算
180 XRankIterator &operator+=(difference_type n) noexcept
181 {
182 this->x_rank += n;
183 if (this->x_rank < this->container->size())
184 {
185 this->y_rank = this->container->access_y_rank(this->x_rank);
186 }
187 else
188 {
189 this->y_rank = this->container->size();
190 }
191 return *this;
192 }
193 XRankIterator &operator-=(difference_type n) noexcept
194 {
195 this->x_rank -= n;
196 if (this->x_rank < this->container->size())
197 {
198 this->y_rank = this->container->access_y_rank(this->x_rank);
199 }
200 else
201 {
202 this->y_rank = this->container->size();
203 }
204 return *this;
205 }
206 friend XRankIterator operator+(XRankIterator it, difference_type n) noexcept { return XRankIterator(it.container, it.y_rank + n, it.x_rank); }
207 friend XRankIterator operator+(difference_type n, XRankIterator it) noexcept { return it + n; }
208 friend XRankIterator operator-(XRankIterator it, difference_type n) noexcept { return XRankIterator(it.container, it.y_rank - n, it.x_rank); }
209 friend difference_type operator-(XRankIterator a, XRankIterator b) noexcept { return a.y_rank - b.y_rank; }
210
211 // 比較
212 friend bool operator==(XRankIterator a, XRankIterator b) noexcept { return a.y_rank == b.y_rank; }
213 friend bool operator!=(XRankIterator a, XRankIterator b) noexcept { return !(a == b); }
214 friend bool operator<(XRankIterator a, XRankIterator b) noexcept { return a.y_rank < b.y_rank; }
215 friend bool operator>(XRankIterator a, XRankIterator b) noexcept { return b < a; }
216 friend bool operator<=(XRankIterator a, XRankIterator b) noexcept { return !(b < a); }
217 friend bool operator>=(XRankIterator a, XRankIterator b) noexcept { return !(a < b); }
218 };
219
221 {
222 this->clear();
223 }
224
225 void clear()
226 {
227 for (uint64_t i = 0; i < this->bits_seq.size(); i++)
228 {
229 this->bits_seq[i].clear();
230 this->length_seq[i].clear();
231 }
232 this->bits_seq.clear();
233 this->length_seq.clear();
234 //this->leaves.clear();
235
236 /*
237 for (uint64_t i = 0; i < this->leaves.size(); i++)
238 {
239 this->leaves[i].clear();
240 }
241 this->leaves.push_back(stool::NaiveFLCVector<false>());
242 */
243 }
244
245 uint64_t get_node_x_pos_in_bit_sequence(int64_t h, uint64_t h_node_id) const{
246 if(h_node_id == 0){
247 return 0;
248 }
249 else{
250 return this->length_seq[h].psum(h_node_id-1);
251 }
252 }
253 /*
254 return the number of 0 in S[0..i];
255 */
256 uint64_t rank0_in_bit_sequence_of_node(uint64_t h, [[maybe_unused]] uint64_t h_node_id, uint64_t node_x_pos_in_bit_sequence, uint64_t i) const {
257 assert(i <= this->length_seq[h].at(h_node_id));
258 assert(node_x_pos_in_bit_sequence == this->get_node_x_pos_in_bit_sequence(h, h_node_id));
259 return this->bits_seq[h].rank0(node_x_pos_in_bit_sequence + i + 1) - this->bits_seq[h].rank0(node_x_pos_in_bit_sequence);
260
261 }
262 /*
263 return the number of 1 in S[0..i];
264 */
265 uint64_t rank1_in_bit_sequence_of_node(uint64_t h, [[maybe_unused]] uint64_t h_node_id, uint64_t node_x_pos_in_bit_sequence, uint64_t i) const {
266 assert(i <= this->length_seq[h].at(h_node_id));
267 assert(node_x_pos_in_bit_sequence == this->get_node_x_pos_in_bit_sequence(h, h_node_id));
268 return this->bits_seq[h].rank1(node_x_pos_in_bit_sequence + i + 1) - this->bits_seq[h].rank1(node_x_pos_in_bit_sequence);
269
270 }
271
272
273 void recursive_add(int64_t h, uint64_t h_node_id, uint64_t x_rank, uint64_t y_rank, std::vector<uint64_t> &output_path)
274 {
275 output_path[h] = h_node_id;
276 uint64_t node_size = this->length_seq[h].at(h_node_id);
277 uint64_t node_x_pos_in_bit_sequence = this->get_node_x_pos_in_bit_sequence(h, h_node_id);
278
279 if (h + 1 < this->height())
280 {
281 uint64_t left_node_id = 2 * h_node_id;
282 uint64_t right_node_id = 2 * h_node_id + 1;
283 uint64_t left_tree_size = this->length_seq[h + 1].at(left_node_id);
284
285 if (x_rank <= left_tree_size)
286 {
287 uint64_t new_y_rank = y_rank > 0 ? this->rank0_in_bit_sequence_of_node(h, h_node_id, node_x_pos_in_bit_sequence, y_rank-1) : 0;
288 this->recursive_add(h + 1, left_node_id, x_rank, new_y_rank, output_path);
289 this->bits_seq[h].insert(node_x_pos_in_bit_sequence + y_rank, false);
290 this->length_seq[h].increment(h_node_id, 1);
291 }
292 else
293 {
294 uint64_t new_y_rank = y_rank > 0 ? this->rank1_in_bit_sequence_of_node(h, h_node_id, node_x_pos_in_bit_sequence, y_rank - 1) : 0;
295 uint64_t new_x_rank = x_rank - left_tree_size;
296
297 this->recursive_add(h + 1, right_node_id, new_x_rank, new_y_rank, output_path);
298 this->bits_seq[h].insert(node_x_pos_in_bit_sequence + y_rank, true);
299 this->length_seq[h].increment(h_node_id, 1);
300 }
301
302 //uint64_t upper_size = this->get_upper_size_of_internal_node(h);
303 /*
304 if (this->is_unbalanced_node(h, h_node_id))
305 {
306 if(h + 5 < this->height()){
307 std::cout << "Rebuild internal node: h = " << h << ", h_node_id = " << h_node_id << ", H = " << this->height() << "/len = " << this->length_seq[h].at(h_node_id) << "/ s: " << this->get_upper_size_of_internal_node(h) << std::endl;
308 }
309 std::cout << "Rebuild internal node: h = " << h << ", h_node_id = " << h_node_id << ", H = " << this->height() << "/len = " << this->length_seq[h].at(h_node_id) << "/ s: " << this->get_upper_size_of_internal_node(h) << std::endl;
310 this->print_tree();
311
312 this->rebuild_internal_node(h, h_node_id);
313 }
314 */
315
316 }
317 else
318 {
319 assert(this->get_bit_count_in_node(h, h_node_id) <= 1);
320 if(node_size == 0){
321 this->bits_seq[h].insert(node_x_pos_in_bit_sequence + y_rank, false);
322 this->length_seq[h].increment(h_node_id, 1);
323 }else if(node_size == 1){
324 assert(x_rank <= 1);
325 if(x_rank == 0){
326 this->bits_seq[h].set_bit(node_x_pos_in_bit_sequence, true);
327 this->bits_seq[h].insert(node_x_pos_in_bit_sequence + y_rank, false);
328
329 }else{
330
331 this->bits_seq[h].insert(node_x_pos_in_bit_sequence + y_rank, true);
332 }
333 this->length_seq[h].increment(h_node_id, 1);
334 }else{
335 throw std::runtime_error("node_size > 1");
336 }
337 }
338
339
340 }
341
342 void add(uint64_t x_rank, uint64_t y_rank)
343 {
344
345
346 if(this->size() > 0){
347 //std::cout << "Add: x_rank = " << x_rank << ", y_rank = " << y_rank << std::endl;
348
349 std::vector<uint64_t> output_path(this->height(), UINT64_MAX);
350 this->recursive_add(0, 0, x_rank, y_rank, output_path);
351 uint64_t upper_size = this->get_upper_size_of_internal_node(0);
352 if (this->size() >= upper_size)
353 {
354 /*
355 std::cout << "Rebuilding range reporting data structure ...: ";
356 std::chrono::system_clock::time_point st1, st2;
357 st1 = std::chrono::system_clock::now();
358 */
359
360 std::vector<uint64_t> rank_elements = this->to_rank_elements_in_y_order();
361 this->build(rank_elements);
362
363 /*
364
365 st2 = std::chrono::system_clock::now();
366 uint64_t sec_time = std::chrono::duration_cast<std::chrono::seconds>(st2 - st1).count();
367 std::cout << "[DONE] Elapsed Time: " << sec_time << " sec, the number of elements: " << rank_elements.size() << std::endl;
368 */
369 }else{
370 uint64_t height = this->height();
371 for(uint64_t h = 0; h < height; h++){
372 uint64_t h_node_id = output_path[h];
373 if (this->is_unbalanced_node(h, h_node_id))
374 {
375 /*
376 if(h + 5 < this->height()){
377 std::cout << "Rebuild internal node: h = " << h << ", h_node_id = " << h_node_id << ", H = " << this->height() << "/len = " << this->length_seq[h].at(h_node_id) << "/ s: " << this->get_upper_size_of_internal_node(h) << std::endl;
378 }
379 */
380
381 this->rebuild_internal_node(h, h_node_id);
382 break;
383 }
384
385 }
386 }
387 assert(this->verify());
388
389 }else{
390 this->clear();
391 std::vector<uint64_t> rank_elements;
392 rank_elements.push_back(0);
393 this->build(rank_elements);
394
395 }
396
397
398
399 }
400
401 void remove(uint64_t y_rank)
402 {
403 int64_t height = this->height();
404 if(height == 0){
405 throw std::runtime_error("Error: DynamicWaveletTreeForRangeSearch::remove(y_rank)");
406 }else{
407 uint64_t h_y_rank = y_rank;
408 uint64_t h_node_id = 0;
409
410 for (int64_t h = 0; h < height; h++)
411 {
412 uint64_t node_x_pos = this->get_node_x_pos_in_bit_sequence(h, h_node_id);
413 bool b = this->bits_seq[h].at(node_x_pos + h_y_rank);
414 uint64_t next_node_id = (2 * h_node_id) + (uint64_t)b;
415 if (b)
416 {
417 uint64_t rmv_y_rank = this->rank0_in_bit_sequence_of_node(h, h_node_id, node_x_pos, h_y_rank);
418 this->bits_seq[h].remove(node_x_pos + h_y_rank);
419 this->length_seq[h].decrement(h_node_id, 1);
420 h_y_rank -= rmv_y_rank;
421 }
422 else
423 {
424 uint64_t rmv_y_rank = this->rank1_in_bit_sequence_of_node(h, h_node_id, node_x_pos, h_y_rank);
425 this->bits_seq[h].remove(node_x_pos + h_y_rank);
426 this->length_seq[h].decrement(h_node_id, 1);
427 h_y_rank -= rmv_y_rank;
428 }
429 h_node_id = next_node_id;
430 }
431
432 uint64_t upper_size = this->get_upper_size_of_internal_node(0);
433 uint64_t size = this->size();
434 if (size < upper_size / 2)
435 {
436 auto rank_elements = this->to_rank_elements_in_y_order();
437 this->build(rank_elements);
438 }
439
440 assert(this->verify());
441 }
442
443
444 }
445
446
447 /*
448 static uint64_t get_full_size_of_tree(uint64_t height)
449 {
450 if(height == 0){
451 return 0;
452 }else{
453 return 1 << (height - 1);
454 }
455 }
456 */
457
458 /*
459 static uint64_t get_upper_size_of_tree(uint64_t height)
460 {
461 return _get_upper_size_of_internal_node(0, height);
462 }
463 */
464
465 /*
466 uint64_t get_full_size_of_internal_node(uint64_t h) const
467 {
468 uint64_t H = this->bits_seq.size();
469 return 1 << (H - 1 - h);
470 }
471 */
472
473
474 /*
475 uint64_t get_upper_size_of_leaf() const
476 {
477 return LEAF_MAX_SIZE;
478 }
479 */
480
481 static uint64_t _get_upper_size_of_root(uint64_t H)
482 {
483 return _get_upper_size_of_internal_node(0, H);
484 }
485
486
487 static uint64_t _get_upper_size_of_internal_node(uint64_t h, uint64_t H)
488 {
489
490 uint64_t u1 = 1;
491 for (uint64_t p = h + 1; p < H; p++)
492 {
493 u1 *= 2;
494 }
495
496 if(u1 > 4){
497 return u1 / 2;
498 }else{
499 return u1;
500 }
501 }
502
503 uint64_t get_upper_size_of_internal_node(uint64_t h) const
504 {
505 return _get_upper_size_of_internal_node(h, this->height());
506 }
507 uint64_t get_lower_size_of_internal_node(uint64_t h) const
508 {
509 uint64_t fsize = _get_upper_size_of_internal_node(h, this->height());
510 return (fsize / 4);
511 }
512
513 /*
514 void insert_element_into_internal_node(uint8_t h, uint64_t hnode_id, uint64_t pos, uint64_t rank){
515
516
517 }
518 */
519
520 void build_h_bit_sequence(uint64_t h, const std::vector<uint64_t> &rank_elements, std::vector<uint64_t> &output_next_rank_elements, std::vector<uint64_t> &output_next_length_seq)
521 {
522
523 uint64_t h_node_count = 1ULL << h;
524 uint64_t counter = 0;
525 uint64_t node_x_pos = 0;
526 std::vector<bool> tmp_bit_sequence(rank_elements.size(), false);
527
528 if((int64_t)(h + 1) < this->height()){
529 output_next_rank_elements.resize(rank_elements.size(), UINT64_MAX);
530 output_next_length_seq.resize(h_node_count * 2, UINT64_MAX);
531 }
532
533
534
535 for(uint64_t i = 0; i < h_node_count; i++){
536 uint64_t bit_size = this->get_bit_count_in_node(h, i);
537 uint64_t half_size = bit_size / 2;
538
539
540 // Processing left elements
541 if((int64_t)(h + 1) < this->height())
542 {
543 uint64_t left_counter = 0;
544 for (uint64_t j = 0; j < bit_size; j++)
545 {
546 if (rank_elements[node_x_pos + j] < half_size)
547 {
548
549 output_next_rank_elements[counter++] = rank_elements[node_x_pos + j];
550 left_counter++;
551 }
552 }
553 output_next_length_seq[i * 2] = left_counter;
554 }
555
556 // Processing right elements
557 {
558 uint64_t right_counter = 0;
559
560 if((int64_t)(h + 1) < this->height()){
561 for (uint64_t j = 0; j < bit_size; j++)
562 {
563 if (rank_elements[node_x_pos + j] >= half_size)
564 {
565
566 tmp_bit_sequence[node_x_pos + j] = true;
567 output_next_rank_elements[counter++] = rank_elements[node_x_pos + j] - half_size;
568 right_counter++;
569 }
570 }
571 output_next_length_seq[(i * 2) + 1] = right_counter;
572 }else{
573 if(bit_size > 1){
574 throw std::runtime_error("Error in build_h_bit_sequence, bit_size > 1");
575 }
576 }
577
578 }
579
580 node_x_pos += bit_size;
581 }
582 this->bits_seq[h].clear();
583 this->bits_seq[h].push_many(tmp_bit_sequence);
584 }
585
586 void rebuild_h_bit_sequence(uint64_t h, uint64_t first_node_id, uint64_t local_h_node_count, const std::vector<uint64_t> &rank_elements, std::vector<uint64_t> &output_next_rank_elements, std::vector<uint64_t> &output_next_length_seq)
587 {
588 assert(first_node_id + local_h_node_count - 1 < this->length_seq[h].size());
589
590
591 uint64_t counter = 0;
592 uint64_t node_x_pos = this->get_node_x_pos_in_bit_sequence(h, first_node_id);
593 const uint64_t first_node_x_pos = node_x_pos;
594 std::vector<bool> tmp_bit_sequence(rank_elements.size(), false);
595
596 if((int64_t)(h + 1) < this->height()){
597 output_next_rank_elements.resize(rank_elements.size(), UINT64_MAX);
598 output_next_length_seq.resize(local_h_node_count * 2, UINT64_MAX);
599 }
600
601
602
603 for(uint64_t node_id = first_node_id; node_id <= first_node_id + local_h_node_count - 1; node_id++){
604 uint64_t bit_size = this->get_bit_count_in_node(h, node_id);
605 uint64_t half_size = bit_size / 2;
606
607
608 // Processing left elements
609 if((int64_t)(h + 1) < this->height())
610 {
611 uint64_t left_counter = 0;
612 for (uint64_t j = 0; j < bit_size; j++)
613 {
614 if (rank_elements[(node_x_pos - first_node_x_pos) + j] < half_size)
615 {
616 output_next_rank_elements[counter++] = rank_elements[(node_x_pos - first_node_x_pos) + j];
617 left_counter++;
618 }
619 }
620 output_next_length_seq[(node_id - first_node_id) * 2] = left_counter;
621 }
622
623 // Processing right elements
624 {
625 uint64_t right_counter = 0;
626
627 if((int64_t)(h + 1) < this->height()){
628 for (uint64_t j = 0; j < bit_size; j++)
629 {
630 if (rank_elements[(node_x_pos - first_node_x_pos) + j] >= half_size)
631 {
632
633 tmp_bit_sequence[(node_x_pos - first_node_x_pos) + j] = true;
634 output_next_rank_elements[counter++] = rank_elements[(node_x_pos - first_node_x_pos) + j] - half_size;
635 right_counter++;
636 }
637 }
638 output_next_length_seq[(node_id - first_node_id) * 2 + 1] = right_counter;
639 }else{
640 if(bit_size > 1){
641 throw std::runtime_error("Error in rebuild_h_bit_sequence, bit_size > 1");
642 }
643 }
644
645 }
646
647 node_x_pos += bit_size;
648 }
649 this->bits_seq[h].set_bits(first_node_x_pos, tmp_bit_sequence);
650 }
651
652
653 void build(const std::vector<uint64_t> &rank_elements, int message_paragraph = stool::Message::NO_MESSAGE)
654 {
655
656
657 this->clear();
658
659 uint64_t height = 0;
660 while (true)
661 {
662 uint64_t fsize = _get_upper_size_of_root(height);
663 if (rank_elements.size() < fsize)
664 {
665 break;
666 }
667 else
668 {
669 height++;
670 }
671 }
672
673 if(message_paragraph != stool::Message::NO_MESSAGE){
674 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Building wavelet tree for range search... " << "(input size = " << rank_elements.size() << ", tree height = " << height << ")" << std::endl;
675 }
676 std::chrono::system_clock::time_point st1, st2;
677 st1 = std::chrono::system_clock::now();
678
679
680 this->bits_seq.resize(height);
681 this->length_seq.resize(height);
682 for(uint64_t h = 0; h < height; h++){
683 this->bits_seq[h].clear();
684 this->length_seq[h].clear();
685 }
686
687 if(height > 0){
688 this->length_seq[0].push_back(rank_elements.size());
689 std::vector<uint64_t> tmp_rank_elements = rank_elements;
690
691 for(uint64_t h = 0; h < height; h++){
692
693 if(message_paragraph != stool::Message::NO_MESSAGE){
694 std::cout << stool::Message::get_paragraph_string(message_paragraph+1) << "Building the " << h << "-th bit sequence in the wavelet tree... " << std::endl;
695 }
696 std::vector<uint64_t> next_rank_elements;
697 std::vector<uint64_t> next_length_seq;
698
699 this->build_h_bit_sequence(h, tmp_rank_elements, next_rank_elements, next_length_seq);
700
701
702 tmp_rank_elements.swap(next_rank_elements);
703 if(h + 1 < height){
704 this->length_seq[h+1].push_many(next_length_seq);
705 }
706 }
707 }
708
709 assert(this->verify());
710
711 st2 = std::chrono::system_clock::now();
712 uint64_t sec_time = std::chrono::duration_cast<std::chrono::seconds>(st2 - st1).count();
713
714 if(message_paragraph != stool::Message::NO_MESSAGE){
715 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "[DONE] Elapsed Time: " << sec_time << " sec" << std::endl;
716 }
717 }
718
719 uint64_t get_bit_count_in_node(uint64_t h, uint64_t h_node_id) const {
720 assert(h < this->length_seq.size());
721 assert(h_node_id < this->length_seq[h].size());
722 return this->length_seq[h].at(h_node_id);
723 }
724
725
726 bool is_unbalanced_node(uint8_t h, uint64_t h_node_id) const
727 {
728 if (h + 1 < this->height())
729 {
730 uint64_t left_node_id = 2 * h_node_id;
731 uint64_t right_node_id = 2 * h_node_id + 1;
732 uint64_t left_tree_size = this->get_bit_count_in_node(h + 1, left_node_id);
733 uint64_t right_tree_size = this->get_bit_count_in_node(h + 1, right_node_id);
734 bool unbalance_flag_LR = left_tree_size > (right_tree_size * 2) || right_tree_size > (left_tree_size * 2);
735 uint64_t child_upper_size = this->get_upper_size_of_internal_node(h + 1);
736 bool full_flag_L = left_tree_size >= child_upper_size;
737 bool full_flag_R = right_tree_size >= child_upper_size;
738 return unbalance_flag_LR || full_flag_L || full_flag_R;
739 }
740 else
741 {
742 return this->length_seq[h].at(h_node_id) >= 2;
743 /*
744 uint64_t left_node_id = 2 * h_node_id;
745 uint64_t right_node_id = 2 * h_node_id + 1;
746 uint64_t left_tree_size = this->leaves[left_node_id].size();
747 uint64_t right_tree_size = this->leaves[right_node_id].size();
748
749 bool unbalance_flag_LR = left_tree_size > (right_tree_size * 2) || right_tree_size > (left_tree_size * 2);
750 uint64_t child_upper_size = this->get_upper_size_of_leaf();
751 bool full_flag_L = left_tree_size >= child_upper_size;
752 bool full_flag_R = right_tree_size >= child_upper_size;
753
754 return unbalance_flag_LR || full_flag_L || full_flag_R;
755 */
756 }
757 }
758
759
760
761 void rebuild_internal_node(uint8_t h, uint64_t h_node_id)
762 {
763
764 std::vector<uint64_t> rank_elements = this->to_local_rank_elements_in_y_order(h, h_node_id);
765
766
767 uint64_t height = this->height();
768 uint64_t current_node_id = h_node_id;
769 uint64_t current_node_count = 1;
770 for(uint64_t q = h; q < height; q++){
771 std::vector<uint64_t> next_rank_elements;
772 std::vector<uint64_t> next_length_seq;
773
774 this->rebuild_h_bit_sequence(q, current_node_id, current_node_count, rank_elements, next_rank_elements, next_length_seq);
775
776 rank_elements.swap(next_rank_elements);
777
778 current_node_count *= 2;
779 current_node_id *= 2;
780
781 if(q+1 < height){
782 this->length_seq[q+1].set_values(current_node_id, next_length_seq);
783 }
784
785 }
786
787
788 /*
789 assert(h < this->bits_seq.size());
790 uint64_t upper_size = this->get_upper_size_of_internal_node(h);
791
792 if (rank_elements.size() > upper_size)
793 {
794 std::cout << "Rebuild: h = " << (int)h << "/ H = " << (int)this->height() << ", h_node_id = " << h_node_id << ", rank_elements.size() = " << rank_elements.size() << ", upper_size = " << upper_size << std::endl;
795 this->print_tree();
796 }
797
798 assert(rank_elements.size() <= upper_size);
799 uint64_t left_counter = 0;
800
801 uint64_t half_size = rank_elements.size() / 2;
802 {
803 std::vector<uint64_t> left_elements(half_size, 0);
804 for (uint64_t i = 0; i < rank_elements.size(); i++)
805 {
806 if (rank_elements[i] < half_size)
807 {
808 left_elements[left_counter++] = rank_elements[i];
809 }
810 }
811 uint64_t next_id = 2 * h_node_id;
812 if ((int64_t)(h + 1) < (int64_t)this->bits_seq.size())
813 {
814 this->rebuild_internal_node(h + 1, next_id, left_elements);
815 assert(left_elements.size() == this->get_bit_count_in_node(h + 1, next_id));
816 }
817 else
818 {
819 this->rebuild_leaf(next_id, left_elements);
820 assert(left_elements.size() == this->leaves[next_id].size());
821 }
822 }
823 {
824 std::vector<uint64_t> right_elements(rank_elements.size() - half_size, 0);
825 std::vector<bool> tmp_bit_sequence(rank_elements.size(), false);
826 uint64_t right_counter = 0;
827
828 for (uint64_t i = 0; i < rank_elements.size(); i++)
829 {
830 assert(i < rank_elements.size());
831 if (rank_elements[i] >= half_size)
832 {
833 assert(right_counter < right_elements.size());
834 tmp_bit_sequence[i] = true;
835 right_elements[right_counter++] = rank_elements[i] - half_size;
836 }
837 }
838 uint64_t next_id = (2 * h_node_id) + 1;
839 if ((int64_t)(h + 1) < (int64_t)this->bits_seq.size())
840 {
841 this->rebuild_internal_node(h + 1, next_id, right_elements);
842 assert(right_elements.size() == this->bits_seq[h + 1][next_id].size());
843 }
844 else
845 {
846 this->rebuild_leaf(next_id, right_elements);
847 assert(right_elements.size() == this->leaves[next_id].size());
848 }
849 assert(h < this->bits_seq.size());
850 assert(h_node_id < this->bits_seq[h].size());
851
852 this->bits_seq[h][h_node_id].clear();
853 this->bits_seq[h][h_node_id].push_many(tmp_bit_sequence);
854
855 }
856 */
857 }
858
859
860 void swap(DynamicWaveletTreeForRangeSearch &item)
861 {
862 this->length_seq.swap(item.length_seq);
863 this->bits_seq.swap(item.bits_seq);
864 }
865
866 /*
867 void rebuild_leaf(uint64_t leaf_id, const std::vector<uint64_t> &rank_elements)
868 {
869 stool::NaiveFLCVector<false> tmp(rank_elements);
870 this->leaves[leaf_id].swap(tmp);
871 }
872 */
873
874 /*
875 void insert_element_into_leaf(uint64_t leaf_id, uint64_t pos, uint64_t rank)
876 {
877 uint64_t size = this->leaves[leaf_id].size();
878 for (uint64_t i = 0; i < size; i++)
879 {
880 uint64_t v = this->leaves[leaf_id][i];
881 if (v >= rank)
882 {
883 this->leaves[leaf_id].increment(i, 1);
884 }
885 }
886 this->leaves[leaf_id].insert(pos, rank);
887 }
888 */
889
890 /*
891 void remove_element_from_leaf(uint64_t leaf_id, uint64_t pos)
892 {
893 uint64_t size = this->leaves[leaf_id].size();
894 uint64_t rank = this->leaves[leaf_id][pos];
895 for (uint64_t i = 0; i < size; i++)
896 {
897 uint64_t v = this->leaves[leaf_id][i];
898 if (v > rank)
899 {
900 this->leaves[leaf_id].increment(i, -1);
901 }
902 }
903 this->leaves[leaf_id].remove(pos);
904 }
905 */
906 int64_t height() const
907 {
908 return this->bits_seq.size();
909 }
910 uint64_t size() const
911 {
912 if (this->height() > 0)
913 {
914 return this->bits_seq[0].size();
915 }
916 else
917 {
918 return 0;
919 }
920 }
921
922 uint64_t access_x_rank(uint64_t y_rank) const
923 {
924 assert(y_rank < this->size());
925 uint64_t x_rank = this->compute_local_x_rank(0, 0, y_rank);
926 return x_rank;
927 }
928 uint64_t find_leaf_index(uint64_t x_rank) const
929 {
930
931 if (x_rank >= this->size())
932 {
933 throw std::runtime_error("ERROR in find_leaf_index: x_rank is out of range");
934 }
935
936 uint64_t current_x_rank = x_rank;
937 uint64_t current_node_id = 0;
938 uint64_t height = this->height();
939
940 for (uint64_t h = 0; h + 1 < height; h++)
941 {
942 uint64_t left_tree_size = this->get_bit_count_in_node(h+1, 2 * current_node_id);
943
944 if (current_x_rank < left_tree_size)
945 {
946 current_node_id = 2 * current_node_id;
947 }
948 else
949 {
950 current_x_rank = current_x_rank - left_tree_size;
951 current_node_id = 2 * current_node_id + 1;
952 }
953 }
954 return current_node_id;
955
956 }
957 uint64_t access_y_rank(uint64_t x_rank) const
958 {
959 uint64_t leaf_index = this->find_leaf_index(x_rank);
960 uint64_t current_y_rank = 0;
961 uint64_t prev_node_id = leaf_index;
962 int64_t height = this->height();
963 for (int64_t h = height - 2; h >= 0; h--)
964 {
965 uint64_t next_node_id = prev_node_id / 2;
966 uint64_t next_x_pos = this->get_node_x_pos_in_bit_sequence(h, next_node_id);
967
968 if (prev_node_id % 2 == 0)
969 {
970 uint64_t count_zero_offset = this->bits_seq[h].rank0(next_x_pos);
971 uint64_t next_y_rank = this->bits_seq[h].select0(current_y_rank + count_zero_offset) - next_x_pos;
972 current_y_rank = next_y_rank;
973 prev_node_id = next_node_id;
974
975 }
976 else
977 {
978
979 uint64_t count_one_offset = this->bits_seq[h].rank1(next_x_pos);
980 int64_t select_result = this->bits_seq[h].select1(current_y_rank + count_one_offset);
981 assert(select_result >= 0);
982 uint64_t next_y_rank = select_result - next_x_pos;
983
984
985
986 current_y_rank = next_y_rank;
987 prev_node_id = next_node_id;
988
989
990 }
991 }
992 return current_y_rank;
993 }
994 std::vector<bool> get_bit_sequence(uint64_t h, uint64_t node_id) const{
995 uint64_t x_pos = this->get_node_x_pos_in_bit_sequence(h, node_id);
996 uint64_t node_size = this->get_bit_count_in_node(h, node_id);
997 std::vector<bool> r;
998 r.resize(node_size, false);
999 for(uint64_t i = 0; i < node_size; i++){
1000 r[i] = this->bits_seq[h].at(x_pos + i);
1001 }
1002 return r;
1003 }
1004
1005 bool verify() const
1006 {
1007
1008 for (uint64_t h = 0; h < this->bits_seq.size(); h++)
1009 {
1010 uint64_t node_count = 1 << h;
1011
1012 if(h + 1 < this->bits_seq.size()){
1013 for (uint64_t i = 0; i < node_count; i++)
1014 {
1015 std::vector<bool> bit_sequence = this->get_bit_sequence(h, i);
1016 uint64_t countL = 0;
1017 uint64_t countR = 0;
1018 for(uint64_t j = 0; j < bit_sequence.size(); j++){
1019 if(bit_sequence[j]){
1020 countR++;
1021 }else{
1022 countL++;
1023 }
1024 }
1025
1026 uint64_t left_tree_size = this->get_bit_count_in_node(h+1, 2 * i);
1027 uint64_t right_tree_size = this->get_bit_count_in_node(h+1, 2 * i + 1);
1028
1029 if(countL != left_tree_size){
1030 this->print_tree();
1031 throw std::runtime_error("Error: verify, countL != left_tree_size");
1032 }
1033
1034 if(countR != right_tree_size){
1035 this->print_tree();
1036 throw std::runtime_error("Error: verify, countR != right_tree_size");
1037 }
1038 }
1039
1040 }else{
1041 for (uint64_t i = 0; i < node_count; i++)
1042 {
1043 uint64_t bit_size = this->get_bit_count_in_node(h, i);
1044 if(bit_size > 1){
1045 this->print_tree();
1046 throw std::runtime_error("Error: verify function, bit_size > 1");
1047 }
1048 }
1049 }
1050
1051 }
1052 return true;
1053
1054 }
1055
1056 std::vector<uint64_t> to_local_rank_elements_in_y_order(uint64_t h, uint64_t node_id) const
1057 {
1058 uint64_t height = this->height();
1059 uint64_t node_size = this->get_bit_count_in_node(h, node_id);
1060 std::vector<uint64_t> r;
1061 r.resize(node_size, UINT64_MAX);
1062 uint64_t x_pos = this->get_node_x_pos_in_bit_sequence(h, node_id);
1063
1064 if (h + 1 < height)
1065 {
1066 uint64_t counterL = 0;
1067 uint64_t counterR = 0;
1068 uint64_t leaf_id_L = 2 * node_id;
1069 uint64_t leaf_id_R = 2 * node_id + 1;
1070 uint64_t left_tree_size = this->get_bit_count_in_node(h + 1, leaf_id_L);
1071
1072 std::vector<uint64_t> left_elements = this->to_local_rank_elements_in_y_order(h + 1, leaf_id_L);
1073 std::vector<uint64_t> right_elements = this->to_local_rank_elements_in_y_order(h + 1, leaf_id_R);
1074
1075 assert(left_elements.size() + right_elements.size() == node_size);
1076
1077
1078
1079
1080 for (uint64_t i = 0; i < node_size; i++)
1081 {
1082 bool b = this->bits_seq[h].at(x_pos + i);
1083 if (b)
1084 {
1085 assert(counterR < right_elements.size());
1086
1087 r[i] = right_elements[counterR++] + left_tree_size;
1088 }
1089 else
1090 {
1091 assert(counterL < left_elements.size());
1092 r[i] = left_elements[counterL++];
1093 }
1094 }
1095 }
1096 else
1097 {
1098 if(node_size == 1){
1099 r[0] = 0;
1100 }else if(node_size > 1){
1101 for (uint64_t i = 0; i < node_size; i++)
1102 {
1103 r[i] = this->bits_seq[h].at(x_pos + i);
1104 }
1105 }
1106 }
1107
1108 return r;
1109
1110 }
1111
1112 std::vector<uint64_t> to_rank_elements_in_y_order() const
1113 {
1114
1115 if (this->height() > 0)
1116 {
1117 return this->to_local_rank_elements_in_y_order(0, 0);
1118 }
1119 else
1120 {
1121 std::vector<uint64_t> r;
1122 return r;
1123 }
1124 }
1125 std::vector<uint64_t> to_rank_elements_in_x_order() const
1126 {
1127 std::vector<uint64_t> r;
1128 r.resize(this->size(), UINT64_MAX);
1129 uint64_t size = this->size();
1130 for(uint64_t i = 0; i < size; i++){
1131 r[i] = this->access_y_rank(i);
1132 }
1133
1134 return r;
1135 }
1136
1137 /*
1138 std::vector<uint64_t> compute_local_rank_array_in_y_order(uint64_t node_y, uint64_t node_id) const
1139 {
1140 std::vector<uint64_t> r;
1141 uint64_t node_size = this->get_bit_count_in_node(node_y, node_id);
1142 r.resize(node_size, UINT64_MAX);
1143 for(uint64_t i = 0; i < node_size; i++){
1144 r[i] = this->compute_local_x_rank(node_y, node_id, i);
1145 }
1146 return r;
1147 }
1148 */
1149
1150
1151 uint64_t compute_local_x_rank(uint64_t node_y, uint64_t node_id, uint64_t local_y_rank) const
1152 {
1153 assert(local_y_rank < this->length_seq[node_y].at(node_id));
1154
1155 uint64_t x_rank = 0;
1156 uint64_t h_node_id = node_id;
1157 int64_t height = this->height();
1158 for (int64_t h = node_y; h + 1 < height; h++)
1159 {
1160 uint64_t node_x_pos = this->get_node_x_pos_in_bit_sequence(h, h_node_id);
1161
1162 assert(node_x_pos + local_y_rank < this->bits_seq[h].size());
1163
1164 bool b = this->bits_seq[h].at(node_x_pos + local_y_rank);
1165 uint64_t next_node_id = (2 * h_node_id) + (uint64_t)b;
1166 if (b)
1167 {
1168 uint64_t left_tree_size = this->get_bit_count_in_node(h+1, 2 * h_node_id);
1169 x_rank += left_tree_size;
1170 local_y_rank -= this->rank0_in_bit_sequence_of_node(h, h_node_id, node_x_pos, local_y_rank);
1171 }
1172 else
1173 {
1174 local_y_rank -= this->rank1_in_bit_sequence_of_node(h, h_node_id, node_x_pos, local_y_rank);
1175 }
1176 h_node_id = next_node_id;
1177 }
1178 //x_rank += this->leaves[h_node_id][h_y_rank];
1179 return x_rank;
1180 }
1181
1182 template <typename APPENDABLE_VECTOR>
1183 uint64_t local_range_report_on_internal_node(uint64_t h, uint64_t node_id, uint64_t x_rank_gap, uint64_t hy_min, uint64_t hy_max, APPENDABLE_VECTOR &out) const
1184 {
1185
1186 for (uint64_t i = hy_min; i <= hy_max; i++)
1187 {
1188 uint64_t x = this->compute_local_x_rank(h, node_id, i) + x_rank_gap;
1189 out.push_back(x);
1190 }
1191 return hy_max - hy_min + 1;
1192 }
1193 /*
1194 template <typename APPENDABLE_VECTOR>
1195 uint64_t local_range_report_on_leaf(uint64_t leaf_id, uint64_t x_rank_gap, uint64_t x_min, uint64_t x_max, uint64_t hy_min, uint64_t hy_max, APPENDABLE_VECTOR &out) const
1196 {
1197 //assert(hy_max < this->leaves[leaf_id].size());
1198
1199 for (uint64_t i = hy_min; i <= hy_max; i++)
1200 {
1201 uint64_t x = this->leaves[leaf_id][i] + x_rank_gap;
1202 if (x >= x_min && x <= x_max)
1203 {
1204 out.push_back(x);
1205 }
1206 }
1207 return hy_max - hy_min + 1;
1208 }
1209 */
1210
1211 template <typename APPENDABLE_VECTOR>
1212 uint64_t recursive_range_report_on_internal_nodes(uint64_t h, uint64_t node_id, uint64_t node_x_pos, int64_t x_min, int64_t x_max, uint64_t hy_min, uint64_t hy_max, APPENDABLE_VECTOR &out) const
1213 {
1214
1215 uint64_t found_elements_count = 0;
1216 int64_t node_size = this->get_bit_count_in_node(h, node_id);
1217 if (x_min <= (int64_t)node_x_pos && (int64_t)(node_x_pos + node_size - 1) <= x_max)
1218 {
1219 uint64_t limitR = std::min((int64_t)hy_max, node_size-1);
1220
1221 if(hy_min <= limitR){
1222 uint64_t _tmp = local_range_report_on_internal_node(h, node_id, node_x_pos, hy_min, limitR, out);
1223 found_elements_count += _tmp;
1224 }
1225
1226 }
1227 else if((int64_t)(h+1) < this->height())
1228 {
1229 uint64_t node_x_pos_L = node_x_pos;
1230 uint64_t node_x_pos_R = node_x_pos + this->get_bit_count_in_node(h+1, 2 * node_id);
1231
1232
1233
1234 /*
1235 int64_t hy_max_0 = ((int64_t)this->bits_seq[h][node_id].rank0(hy_max + 1)) - 1;
1236 int64_t hy_max_1 = ((int64_t)this->bits_seq[h][node_id].rank1(hy_max + 1)) - 1;
1237 */
1238 int64_t hy_max_0 = rank0_in_bit_sequence_of_node(h, node_id, node_x_pos_L, hy_max) - 1;
1239 int64_t hy_max_1 = rank1_in_bit_sequence_of_node(h, node_id, node_x_pos_L, hy_max) - 1;
1240
1241 /*
1242 int64_t hy_min_0 = hy_min > 0 ? ((int64_t)this->bits_seq[h][node_id].rank0(hy_min)) : 0;
1243 int64_t hy_min_1 = hy_min > 0 ? ((int64_t)this->bits_seq[h][node_id].rank1(hy_min)) : 0;
1244 */
1245 int64_t hy_min_0 = hy_min > 0 ? rank0_in_bit_sequence_of_node(h, node_id, node_x_pos_L, hy_min - 1) : 0;
1246 int64_t hy_min_1 = hy_min > 0 ? rank1_in_bit_sequence_of_node(h, node_id, node_x_pos_L, hy_min - 1) : 0;
1247
1248
1249 uint64_t next_node_id_L = 2 * node_id;
1250 uint64_t next_node_id_R = next_node_id_L + 1;
1251
1252 if (x_min < (int64_t)node_x_pos_R && hy_min_0 <= hy_max_0)
1253 {
1254 found_elements_count += this->recursive_range_report_on_internal_nodes(h + 1, next_node_id_L, node_x_pos_L, x_min, x_max, hy_min_0, hy_max_0, out);
1255 }
1256
1257 if (x_max >= (int64_t)node_x_pos_R && hy_min_1 <= hy_max_1)
1258 {
1259 found_elements_count += this->recursive_range_report_on_internal_nodes(h + 1, next_node_id_R, node_x_pos_R, x_min, x_max, hy_min_1, hy_max_1, out);
1260 }
1261
1262 }
1263 return found_elements_count;
1264
1265 }
1266
1267 template <typename APPENDABLE_VECTOR>
1268 uint64_t range_report(uint64_t x_min, uint64_t x_max, uint64_t y_min, uint64_t y_max, APPENDABLE_VECTOR &out) const
1269 {
1270 uint64_t found_elements_count = 0;
1271 if (this->height() > 0)
1272 {
1273 found_elements_count = this->recursive_range_report_on_internal_nodes(0, 0, 0, x_min, x_max, y_min, y_max, out);
1274 }
1275 return found_elements_count;
1276 }
1277
1278 XRankIterator x_rank_begin() const
1279 {
1280 if (this->size() == 0)
1281 {
1282 return XRankIterator(this, this->size(), this->size());
1283 }
1284 else
1285 {
1286 return XRankIterator(this, 0, this->access_y_rank(0));
1287 }
1288 }
1289 XRankIterator x_rank_end() const
1290 {
1291 return XRankIterator(this, this->size(), this->size());
1292 }
1293 YRankIterator y_rank_begin() const
1294 {
1295 if (this->size() == 0)
1296 {
1297 return YRankIterator(this, this->size(), this->size());
1298 }
1299 else
1300 {
1301 return YRankIterator(this, this->access_x_rank(0), 0);
1302 }
1303 }
1304 YRankIterator y_rank_end() const
1305 {
1306 return YRankIterator(this, this->size(), this->size());
1307 }
1308
1309 void print_tree() const
1310 {
1311 std::vector<std::string> r;
1312 for (uint64_t h = 0; h < this->bits_seq.size(); h++)
1313 {
1314 std::vector<uint64_t> tmp_len_veq;
1315 uint64_t counter = 0;
1316 tmp_len_veq.push_back(0);
1317 for(uint64_t i = 0; i < this->length_seq[h].size(); i++){
1318 counter += this->length_seq[h].at(i);
1319 tmp_len_veq.push_back(counter);
1320 }
1321
1322 std::string s = "";
1323 uint64_t tmp_p = 0;
1324 for(uint64_t i = 0; i < this->bits_seq[h].size(); i++){
1325 while(tmp_len_veq[tmp_p] <= i){
1326 s.append("|");
1327 tmp_p++;
1328 }
1329
1330 bool b = this->bits_seq[h].at(i);
1331
1332 s.append(b ? "1" : "0");
1333 }
1334 s.append("|");
1335
1336 r.push_back(s);
1337 }
1338 /*
1339 std::string s = "";
1340 std::vector<char> char_vec{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
1341
1342 for (uint64_t i = 0; i < this->leaves.size(); i++)
1343 {
1344 s.append("[");
1345
1346 for (uint64_t j = 0; j < this->leaves[i].size(); j++)
1347 {
1348 uint64_t v = this->leaves[i][j];
1349 if (v < char_vec.size())
1350 {
1351 s.push_back(char_vec[v]);
1352 }
1353 else
1354 {
1355 s.push_back('?');
1356 }
1357 }
1358 s.append("]");
1359 }
1360 r.push_back(s);
1361 */
1362
1363 std::cout << "===== TREE =====" << std::endl;
1364
1365 for (uint64_t i = 0; i < r.size(); i++)
1366 {
1367 std::cout << r[i] << std::endl;
1368 }
1369 std::cout << "===== [END] =====" << std::endl;
1370 }
1371
1372 static void store_to_file(DynamicWaveletTreeForRangeSearch &item, std::ofstream &os)
1373 {
1374 uint64_t height = item.height();
1375 os.write(reinterpret_cast<const char *>(&height), sizeof(uint64_t));
1376
1377 for (uint64_t h = 0; h < height; h++)
1378 {
1379 BIT_SEQUENCE::store_to_file(item.bits_seq[h], os);
1380 PREFIX_SUM::store_to_file(item.length_seq[h], os);
1381 }
1382 }
1383 static void store_to_bytes(DynamicWaveletTreeForRangeSearch &item, std::vector<uint8_t> &output, uint64_t &pos)
1384 {
1385 uint64_t bytes = item.size_in_bytes();
1386 if(output.size() < pos + bytes){
1387 output.resize(pos + bytes);
1388 }
1389 uint64_t height = item.height();
1390
1391 std::memcpy(output.data() + pos, &height, sizeof(height));
1392 pos += sizeof(height);
1393
1394 for (int64_t h = 0; h < (int64_t)height; h++)
1395 {
1396 BIT_SEQUENCE::store_to_bytes(item.bits_seq[h], output, pos);
1397 PREFIX_SUM::store_to_bytes(item.length_seq[h], output, pos);
1398 }
1399 }
1400 uint64_t size_in_bytes(bool only_extra_bytes = false) const
1401 {
1402 uint64_t sum = 0;
1403 sum += sizeof(uint64_t);
1404 for(int64_t h = 0; h < (int64_t)this->height(); h++){
1405 sum += this->bits_seq[h].size_in_bytes(only_extra_bytes);
1406 sum += this->length_seq[h].size_in_bytes(only_extra_bytes);
1407 }
1408 return sum;
1409 }
1410
1411 static DynamicWaveletTreeForRangeSearch load_from_file(std::ifstream &ifs)
1412 {
1413 DynamicWaveletTreeForRangeSearch r;
1414 uint64_t _height = 0;
1415 ifs.read(reinterpret_cast<char *>(&_height), sizeof(uint64_t));
1416
1417 r.bits_seq.resize(_height);
1418 r.length_seq.resize(_height);
1419 for (uint64_t h = 0; h < _height; h++)
1420 {
1421 SimpleDynamicBitSequence bits = BIT_SEQUENCE::load_from_file(ifs);
1422 r.bits_seq[h].swap(bits);
1423
1424 SimpleDynamicPrefixSum length_seq = PREFIX_SUM::load_from_file(ifs);
1425 r.length_seq[h].swap(length_seq);
1426 }
1427 return r;
1428
1429 }
1430 static DynamicWaveletTreeForRangeSearch load_from_bytes(const std::vector<uint8_t> &data, uint64_t &pos)
1431 {
1432 DynamicWaveletTreeForRangeSearch r;
1433 uint64_t _height;
1434 std::memcpy(&_height, data.data() + pos, sizeof(_height));
1435 pos += sizeof(_height);
1436
1437 r.bits_seq.resize(_height);
1438 r.length_seq.resize(_height);
1439 for (uint64_t h = 0; h < _height; h++)
1440 {
1441 SimpleDynamicBitSequence bits = BIT_SEQUENCE::load_from_bytes(data, pos);
1442 r.bits_seq[h].swap(bits);
1443
1444 SimpleDynamicPrefixSum length_seq = PREFIX_SUM::load_from_bytes(data, pos);
1445 r.length_seq[h].swap(length_seq);
1446
1447 }
1448 return r;
1449 }
1450
1451 std::vector<std::string> get_memory_usage_info(int message_paragraph = stool::Message::SHOW_MESSAGE) const
1452 {
1453
1454 std::vector<std::string> r;
1455 uint64_t size_in_bytes = this->size_in_bytes();
1456 uint64_t element_count = this->size();
1457
1458 double bits_per_element = element_count > 0 ? ((double)size_in_bytes / (double)element_count) : 0;
1459
1460 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "=DynamicWaveletTreeForRangeSearch: " + std::to_string(this->size_in_bytes())
1461 + " bytes, " + std::to_string(element_count) + " elements, " + std::to_string(bits_per_element) + " bytes per element =");
1462
1463 for(uint64_t h = 0; h < this->bits_seq.size(); h++){
1464 uint64_t _sub_size = 0;
1465 _sub_size += this->bits_seq[h].size_in_bytes();
1466 _sub_size += this->length_seq[h].size_in_bytes();
1467
1468 uint64_t _bits_per_element = element_count > 0 ? ((double)_sub_size / (double)element_count) : 0;
1469 r.push_back(stool::Message::get_paragraph_string(message_paragraph+1) + "Level " + std::to_string(h) + " in range tree: " + std::to_string(_sub_size) + " bytes" + " (" + std::to_string(_bits_per_element) + " bytes per element)");
1470 }
1471 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "==");
1472
1473 return r;
1474 }
1475
1476 };
1477 }
1478}
An implementation of B+-tree [Unchecked AI's Comment].
Definition bp_tree.hpp:24
void push_back(VALUE value)
Pushes a single value to the B+ tree.
Definition bp_tree.hpp:1851
static void store_to_bytes(BPTree &bp, std::vector< uint8_t > &output, uint64_t &pos)
Saves the B+ tree structure to a byte vector.
Definition bp_tree.hpp:2913
uint64_t size() const
Return the number of values stored in this tree.
Definition bp_tree.hpp:316
void load_from_file(std::ifstream &ifs)
Builds a B+ tree from serialized data in a file stream.
Definition bp_tree.hpp:2993
void load_from_bytes(const std::vector< uint8_t > &data, uint64_t &pos)
Builds a B+ tree from serialized data in a byte vector.
Definition bp_tree.hpp:2969
static void store_to_file(BPTree &bp, std::ofstream &os)
Saves the B+ tree structure to a file stream.
Definition bp_tree.hpp:2945
Definition dynamic_wavelet_tree_for_range_search.hpp:125
Definition dynamic_wavelet_tree_for_range_search.hpp:29
DynamicWaveletTreeForRangeSearch. [Unchecked AI's Comment].
Definition dynamic_wavelet_tree_for_range_search.hpp:15