b-tree-plus-alpha
Loading...
Searching...
No Matches
dynamic_prefix_sum.hpp
1#pragma once
2#include "./prefix_sum/plain_spsi_container.hpp"
3#include "stool/include/all.hpp"
4
5namespace stool
6{
7 namespace bptree
8 {
9
10
16 template <typename LEAF_CONTAINER = VLCDeque, uint64_t TREE_DEGREE = bptree::DEFAULT_MAX_DEGREE_OF_INTERNAL_NODE, uint64_t LEAF_CONTAINER_MAX_SIZE = bptree::DEFAULT_MAX_COUNT_OF_VALUES_IN_LEAF>
18 {
19 public:
22 // static inline constexpr int DEFAULT_MAX_COUNT_OF_VALUES_IN_LEAF = 126;
23
24 // static inline constexpr int DEFAULT_MAX_COUNT_OF_VALUES_IN_LEAF = 126;
25 // static inline constexpr int DEFAULT_MAX_COUNT_OF_VALUES_IN_LEAF = 1024;
26
27 private:
28 Tree tree;
29
30 public:
34
35
36
41 {
42 this->tree.initialize();
43 }
44
48 DynamicPrefixSum(const std::vector<uint64_t> &S_)
49 {
50 this->tree.initialize();
51 this->tree.build(S_);
52 assert(this->size() == S_.size());
53 }
57 DynamicPrefixSum(DynamicPrefixSum &&) noexcept = default;
58
59 //}@
60
64
65
69 typename Tree::ValueForwardIterator begin() const
70 {
71 return this->tree.get_value_forward_iterator_begin();
72 }
73
78 {
79 return this->tree.get_value_forward_iterator_end();
80 }
81
83
87
88
99 uint64_t operator[](uint64_t i) const
100 {
101 return this->tree.at(i);
102 }
104
108
109
114 {
115 return this->tree;
116 }
117
121 uint64_t get_degree() const
122 {
123 return this->tree.get_max_degree_of_internal_node();
124 }
125
129 uint64_t size() const
130 {
131 return this->tree.size();
132 }
133
138 uint64_t size_in_bytes(bool only_dynamic_memory = false) const
139 {
140 return this->tree.size_in_bytes(only_dynamic_memory);
141 }
142
146 double density() const
147 {
148 return this->tree.get_value_density();
149 }
150
152
156
157
160 std::vector<uint64_t> to_vector() const
161 {
162 return this->tree.to_value_vector();
163 }
164
168 std::vector<uint8_t> to_u8_vector() const
169 {
170 std::vector<uint8_t> r;
171 r.resize(this->size(), 0);
172 uint64_t x = 0;
173 for (uint8_t c : *this)
174 {
175 r[x++] = c;
176 }
177 return r;
178 }
179
183 std::string to_string() const
184 {
185 std::stringstream ss;
186 auto vec = this->to_vector();
187 ss << stool::ConverterToString::to_integer_string(vec);
188 return ss.str();
189 }
191
195
196
201 uint64_t at(uint64_t i) const
202 {
203 return this->tree.at(i);
204 }
205
210 uint64_t psum() const
211 {
212 return this->tree.psum();
213 }
214
219 uint64_t psum(uint64_t i) const
220 {
221 return this->tree.psum(i);
222 }
223
228 uint64_t psum(uint64_t i, uint64_t j) const
229 {
230 if(i > 0){
231 return this->tree.psum(j) - this->tree.psum(i-1);
232 }else{
233 return this->tree.psum(j);
234 }
235 }
236
241 uint64_t reverse_psum([[maybe_unused]] uint64_t i) const
242 {
243 uint64_t size = this->size();
244 if (size == 0)
245 {
246 return 0;
247 }
248 else if (i + 1 == size)
249 {
250 return this->psum(size - i - 1, size - 1);
251 }
252 else
253 {
254 return this->psum(size - i - 1, size - 1);
255 }
256 }
257
261 int64_t search(uint64_t x) const
262 {
263 return this->tree.search(x);
264 }
265
270 int64_t predecessor_index(uint64_t x) const
271 {
272 int64_t size = this->size();
273
274 if (size > 0)
275 {
276 uint64_t fst_value = this->at(0);
277 if (x >= fst_value)
278 {
279 if (x > this->psum())
280 {
281 return size - 1;
282 }
283 else
284 {
285 int64_t idx = this->search(x);
286 if (idx >= size)
287 {
288 return size - 1;
289 }
290 else
291 {
292 uint64_t v = this->psum(idx);
293
294 assert(v >= x);
295 if (v > x)
296 {
297 assert(idx - 1 < size);
298 return idx - 1;
299 }
300 else
301 {
302 assert(idx < size);
303 return idx;
304 }
305 }
306 }
307 }
308 else
309 {
310 return -1;
311 }
312 }
313 else
314 {
315 return -1;
316 }
317 }
318
323 int64_t successor_index(uint64_t x) const
324 {
325 int64_t size = this->size();
326 if (size > 0)
327 {
328 uint64_t lst_value = this->psum();
329 if (x <= lst_value)
330 {
331 int64_t idx = this->search(x);
332 if (idx >= size)
333 {
334 return -1;
335 }
336 else
337 {
338 assert(this->psum(idx) >= x);
339 return idx;
340 }
341 }
342 else
343 {
344 return -1;
345 }
346 }
347 else
348 {
349 return -1;
350 }
351 }
352
354
358
359
363 void set_value(uint64_t i, uint64_t value)
364 {
365 uint64_t old_value = this->at(i);
366 if (old_value > value)
367 {
368 this->decrement(i, old_value - value);
369 }
370 else if (old_value < value)
371 {
372 this->increment(i, value - old_value);
373 }
374 }
375
380 void set_values(uint64_t i, const std::vector<uint64_t> &values_Q)
381 {
382 assert(i < this->size());
383 assert(i + values_Q.size() <= this->size());
384
385 for (uint64_t j = 0; j < values_Q.size(); j++)
386 {
387 this->set_value(i + j, values_Q[j]);
388 }
389 }
390
395 void increment(uint64_t i, int64_t delta)
396 {
397 this->tree.increment(i, delta);
398 }
399
404 void decrement(uint64_t i, int64_t delta)
405 {
406 this->tree.increment(i, -delta);
407 }
408
413 {
414 this->tree.swap(item.tree);
415 }
416
420 void clear()
421 {
422 this->tree.clear();
423 }
424
429 void push_back(uint64_t value)
430 {
431 this->tree.push_back(value);
432 }
433
438 void push_back_many(const std::vector<uint64_t> &items_Q)
439 {
440 this->tree.push_many(items_Q);
441 }
442
446 void push_many(const std::vector<uint64_t> &items)
447 {
448 this->tree.push_many(items);
449 }
450
455 void push_front(uint64_t value)
456 {
457 this->tree.push_front(value);
458 }
459
464 void pop_back()
465 {
466 this->tree.remove(this->size() - 1);
467 }
468
474 {
475 this->tree.remove(0);
476 }
477
482 void insert(uint64_t pos, uint64_t value)
483 {
484 this->tree.insert(pos, value, value);
485 }
486
491 void remove(uint64_t pos)
492 {
493 this->tree.remove(pos);
494 }
495
497
501
502
507 std::vector<std::string> get_memory_usage_info(int message_paragraph = stool::Message::SHOW_MESSAGE) const
508 {
509 std::vector<std::string> log1 = this->tree.get_memory_usage_info(message_paragraph + 1);
510
511 std::vector<std::string> r;
512 uint64_t size_in_bytes = this->size_in_bytes();
513 uint64_t size = this->size();
514 double bits_per_element = size > 0 ? ((double)size_in_bytes / (double)size) : 0;
515
516 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "=DynamicPrefixSum: " + std::to_string(this->size_in_bytes()) + " bytes, " + std::to_string(size) + " elements, " + std::to_string(bits_per_element) + " bytes per element =");
517
518 for (std::string &s : log1)
519 {
520 r.push_back(s);
521 }
522
523 uint64_t total_bits_if_sequence_is_plain = 0;
524 for (uint64_t i = 0; i < size; ++i)
525 {
526 total_bits_if_sequence_is_plain += stool::LSBByte::get_code_length(this->at(i));
527 }
528
529 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "The number of bits in input sequence: " + std::to_string(total_bits_if_sequence_is_plain));
530 if (total_bits_if_sequence_is_plain > 0)
531 {
532 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "Memory per input bit: " + std::to_string((double)size_in_bytes / (double)total_bits_if_sequence_is_plain) + " bytes");
533 }
534
535 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "==");
536
537 return r;
538 }
539
544 void print_memory_usage(int message_paragraph = stool::Message::SHOW_MESSAGE) const
545 {
546 std::vector<std::string> log = this->get_memory_usage_info(message_paragraph);
547 for (std::string &s : log)
548 {
549 std::cout << s << std::endl;
550 }
551 }
552
557 void print_statistics(int message_paragraph = stool::Message::SHOW_MESSAGE) const
558 {
559 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Statistics(DynamicPrefixSum):" << std::endl;
560 this->tree.print_statistics(message_paragraph + 1);
561 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "[END]" << std::endl;
562 }
563
568 void print_information_about_performance(int message_paragraph = stool::Message::SHOW_MESSAGE) const
569 {
570 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Performance Information (DynamicPrefixSum)[" << std::endl;
571 this->tree.print_information_about_performance(message_paragraph + 1);
572 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "]" << std::endl;
573 }
574
579 void print_tree(int message_paragraph = stool::Message::SHOW_MESSAGE) const
580 {
581
582 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Tree(DynamicPrefixSum)[" << std::endl;
583 this->tree.print_tree();
584 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "]" << std::endl;
585 }
586
590 void print_info() const
591 {
592 this->print_statistics();
593 }
594
598 void verify() const
599 {
600 this->tree.verify();
601 }
602
604
608
609
613 static DynamicPrefixSum build(const std::vector<uint64_t> &items)
614 {
616 r.tree.initialize();
617 r.tree.build(items);
618 assert(r.size() == items.size());
619 return r;
620 }
621
625 static DynamicPrefixSum load_from_bytes(const std::vector<uint8_t> &data, uint64_t &pos)
626 {
628 Tree tree = Tree::load_from_bytes(data, pos);
629 r.tree.swap(tree, false);
630 return r;
631 }
632
636 static DynamicPrefixSum load_from_file(std::ifstream &ifs)
637 {
639 Tree tree = Tree::load_from_file(ifs);
640 r.tree.swap(tree, false);
641 return r;
642 }
643
647 static void store_to_bytes(DynamicPrefixSum &item, std::vector<uint8_t> &output, uint64_t &pos)
648 {
649 Tree::store_to_bytes(item.tree, output, pos);
650 }
651
655 static void store_to_file(DynamicPrefixSum &item, std::ofstream &os)
656 {
657 Tree::store_to_file(item.tree, os);
658 }
660
664
665
668 static std::string name()
669 {
670 std::string s;
671 s += "DynamicPrefixSum(";
672 s += LEAF_CONTAINER::name();
673 s += ")";
674 return s;
675 }
677 };
678
679 using SimpleDynamicPrefixSum = DynamicPrefixSum<stool::NaiveFLCVector<>, 62, 256>;
680 using PlainDynamicPrefixSum = DynamicPrefixSum<PlainSPSIContainer>;
681 using VLCDequeDynamicPrefixSum = DynamicPrefixSum<VLCDeque>;
682 // using DynamicSuccinctPrefixSum = DynamicPrefixSum<stool::NaiveVLCArray<4096>, 62, 128>;
683 // using EFDynamicPrefixSum = DynamicPrefixSum<stool::NaiveFLCVector<>, 62, 256>;
684
685 // using GapEncodedSPSI = SPSI<GapEncodedContainer>;
686
687 }
688
689}
A pointer to a node of BPTree [Unchecked AI's Comment].
Definition bp_node_pointer.hpp:14
An implementation of a B+-tree for storing n values S[0..n-1] of type VALUE in leaves.
Definition bp_tree.hpp:29
std::vector< VALUE > to_value_vector() const
Return the values S[0..n-1] as a vector of VALUE.
Definition bp_tree.hpp:403
void build(const std::vector< VALUE > &_values)
Builds the B+ tree so that S[0..n-1] = _values[0..n-1].
Definition bp_tree.hpp:1491
ValueForwardIterator get_value_forward_iterator_end() const
Return an iterator pointing to the end of the values S[0..n-1].
Definition bp_tree.hpp:223
void insert(uint64_t i, VALUE v, uint64_t weight_w)
Insert a given value v with weight w at position i in the sequence S.
Definition bp_tree.hpp:1275
static void store_to_bytes(BPTree &item, std::vector< uint8_t > &output, uint64_t &pos)
Save the given instance item to a byte vector output at the position pos.
Definition bp_tree.hpp:1554
static void store_to_file(BPTree &item, std::ofstream &os)
Save the given instance item to a file stream os.
Definition bp_tree.hpp:1581
void print_statistics(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Print the statistics of this data structure.
Definition bp_tree.hpp:971
void increment(uint64_t i, int64_t delta)
Update S[i] and its weight using a given value delta and the increment function supported by the LEAF...
Definition bp_tree.hpp:1332
ValueForwardIterator get_value_forward_iterator_begin() const
Return an iterator pointing to the first value in the values S[0..n-1].
Definition bp_tree.hpp:207
void swap(BPTree &_tree, bool swap_linked_tree=true)
Swap operation.
Definition bp_tree.hpp:1087
static BPTree load_from_file(std::ifstream &ifs)
Returns the BPTree instance loaded from a file stream ifs.
Definition bp_tree.hpp:1536
VALUE at(uint64_t i) const
Return B[i].
Definition bp_tree.hpp:440
void push_back(VALUE value)
Push a given value to the end of the sequence S.
Definition bp_tree.hpp:1154
uint64_t size_in_bytes(bool only_dynamic_memory=false) const
Returns the total memory size of this B+-tree.
Definition bp_tree.hpp:377
void initialize()
Initializes this instance.
Definition bp_tree.hpp:1063
std::vector< std::string > get_memory_usage_info(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Return the memory usage information of this data structure as a vector of strings.
Definition bp_tree.hpp:789
int64_t search(uint64_t u) const
Return the smallest index i such that psum(i) >= u if it exists, otherwise return -1.
Definition bp_tree.hpp:572
uint64_t size() const
Return the number of values stored in this tree (i.e., n).
Definition bp_tree.hpp:282
bool verify() const
Verify the internal consistency of this data structure.
Definition bp_tree.hpp:1040
void print_tree() const
Prints the B+ tree in a tree-like format.
Definition bp_tree.hpp:836
void push_front(VALUE value)
Push a given value to the beginning of the sequence S.
Definition bp_tree.hpp:1189
static BPTree load_from_bytes(const std::vector< uint8_t > &data, uint64_t &pos)
Returns the BPTree instance loaded from a byte vector data at the position pos.
Definition bp_tree.hpp:1515
void remove(uint64_t i)
Remove S[i] from the sequence S.
Definition bp_tree.hpp:1255
void push_many(const std::vector< VALUE > &values_Q)
Add a given sequence Q[0..k-1] to the end of S[0..n-1] (i.e., S = S[0..n-1]Q[0..k-1])
Definition bp_tree.hpp:1164
void clear()
Clear the B+-tree and reset it to an empty state (i.e., n = 0, x = 0, y = 0).
Definition bp_tree.hpp:1110
uint64_t psum() const
Return the sum of the weights of S[0..n-1].
Definition bp_tree.hpp:521
void print_information_about_performance(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Print the performance information of this data structure.
Definition bp_tree.hpp:947
uint64_t get_max_degree_of_internal_node() const
Return MAX_DEGREE.
Definition bp_tree.hpp:267
double get_value_density() const
Return the density of this tree (i.e., n / capacity()).
Definition bp_tree.hpp:313
The forward iterator of the values stored in BPTree [Unchecked AI's Comment].
Definition bp_value_forward_iterator.hpp:16
A dynamic data structure supporting prefix-sum query on a unsigned 64-bit integer sequence S[0....
Definition dynamic_prefix_sum.hpp:18
DynamicPrefixSum & operator=(DynamicPrefixSum &&) noexcept=default
Default move assignment operator.
void print_tree(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Print the form of the internal tree of this data structure.
Definition dynamic_prefix_sum.hpp:579
uint64_t psum() const
Return the sum of S[0..n-1].
Definition dynamic_prefix_sum.hpp:210
void push_front(uint64_t value)
Add a given value to the beginning of S.
Definition dynamic_prefix_sum.hpp:455
int64_t successor_index(uint64_t x) const
Return the smallest i such that psum(i) >= x if such a position exists, otherwise returns -1.
Definition dynamic_prefix_sum.hpp:323
void decrement(uint64_t i, int64_t delta)
Set the value S[i-delta] at a given position i in S.
Definition dynamic_prefix_sum.hpp:404
std::string to_string() const
Return S as a string.
Definition dynamic_prefix_sum.hpp:183
Tree & __get_tree()
Get the internal tree storing the sequence S.
Definition dynamic_prefix_sum.hpp:113
void push_back(uint64_t value)
Add a given integer to the end of S.
Definition dynamic_prefix_sum.hpp:429
void insert(uint64_t pos, uint64_t value)
Insert a given integer value into S as the (pos+1)-th element.
Definition dynamic_prefix_sum.hpp:482
std::vector< uint64_t > to_vector() const
Return S as a vector.
Definition dynamic_prefix_sum.hpp:160
uint64_t at(uint64_t i) const
Return the (i+1)-th element of S[i].
Definition dynamic_prefix_sum.hpp:201
std::vector< uint8_t > to_u8_vector() const
Return S as a vector of uint8_t.
Definition dynamic_prefix_sum.hpp:168
static DynamicPrefixSum build(const std::vector< uint64_t > &items)
Build a new DynamicPrefixSum from a given sequence items.
Definition dynamic_prefix_sum.hpp:613
void verify() const
Verify the internal consistency of this data structure.
Definition dynamic_prefix_sum.hpp:598
uint64_t get_degree() const
Return the maximum degree of internal nodes of the internal tree storing the sequence S.
Definition dynamic_prefix_sum.hpp:121
DynamicPrefixSum & operator=(const DynamicPrefixSum &)=delete
Deleted copy assignment operator.
int64_t search(uint64_t x) const
Return the smallest i such that psum(i) >= x if such a position exists, otherwise returns -1.
Definition dynamic_prefix_sum.hpp:261
double density() const
Return the density of the internal tree.
Definition dynamic_prefix_sum.hpp:146
DynamicPrefixSum(DynamicPrefixSum &&) noexcept=default
Default move constructor.
static void store_to_bytes(DynamicPrefixSum &item, std::vector< uint8_t > &output, uint64_t &pos)
Save the given instance item to a byte vector output at the position pos.
Definition dynamic_prefix_sum.hpp:647
uint64_t reverse_psum(uint64_t i) const
Returns the sum of integers in S[(n-1)-i..n-1].
Definition dynamic_prefix_sum.hpp:241
std::vector< std::string > get_memory_usage_info(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Return the memory usage information of this data structure as a vector of strings.
Definition dynamic_prefix_sum.hpp:507
void print_memory_usage(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Print the memory usage information of this data structure.
Definition dynamic_prefix_sum.hpp:544
uint64_t psum(uint64_t i, uint64_t j) const
Return the sum of S[i..j].
Definition dynamic_prefix_sum.hpp:228
static DynamicPrefixSum load_from_bytes(const std::vector< uint8_t > &data, uint64_t &pos)
Returns the DynamicPrefixSum instance loaded from a byte vector data at the position pos.
Definition dynamic_prefix_sum.hpp:625
void swap(DynamicPrefixSum &item)
Swap operation.
Definition dynamic_prefix_sum.hpp:412
uint64_t size_in_bytes(bool only_dynamic_memory=false) const
Returns the total memory usage in bytes.
Definition dynamic_prefix_sum.hpp:138
void remove(uint64_t pos)
Remove the element at the position pos from S and return it.
Definition dynamic_prefix_sum.hpp:491
void increment(uint64_t i, int64_t delta)
Set the value S[i+delta] at a given position i in S.
Definition dynamic_prefix_sum.hpp:395
void print_statistics(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Print the statistics of this data structure.
Definition dynamic_prefix_sum.hpp:557
void push_back_many(const std::vector< uint64_t > &items_Q)
Add a given sequence Q[0..k-1] to the end of S[0..n-1] (i.e., S = S[0..n-1]Q[0..k-1])
Definition dynamic_prefix_sum.hpp:438
uint64_t size() const
Return |S|.
Definition dynamic_prefix_sum.hpp:129
void set_value(uint64_t i, uint64_t value)
Set a given value v at a given position i in S.
Definition dynamic_prefix_sum.hpp:363
void pop_back()
Remove the last element from S.
Definition dynamic_prefix_sum.hpp:464
DynamicPrefixSum(const std::vector< uint64_t > &S_)
Default constructor with S = S_.
Definition dynamic_prefix_sum.hpp:48
int64_t predecessor_index(uint64_t x) const
Return the largest i such that psum(i) <= x if such a position exists, otherwise returns -1.
Definition dynamic_prefix_sum.hpp:270
void print_information_about_performance(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Print the performance information of this data structure.
Definition dynamic_prefix_sum.hpp:568
void set_values(uint64_t i, const std::vector< uint64_t > &values_Q)
Replaces the |Q| values S[i..i+|Q|-1] with the given values Q[0..|Q|-1].
Definition dynamic_prefix_sum.hpp:380
static void store_to_file(DynamicPrefixSum &item, std::ofstream &os)
Save the given instance item to a file stream os.
Definition dynamic_prefix_sum.hpp:655
void push_many(const std::vector< uint64_t > &items)
Alias for push_back_many.
Definition dynamic_prefix_sum.hpp:446
uint64_t psum(uint64_t i) const
Return the sum of the first (i+1) values of S[0..n-1].
Definition dynamic_prefix_sum.hpp:219
Tree::ValueForwardIterator end() const
Returns an iterator to the end of the sequence S.
Definition dynamic_prefix_sum.hpp:77
Tree::ValueForwardIterator begin() const
Returns an iterator to the beginning of the sequence S.
Definition dynamic_prefix_sum.hpp:69
static DynamicPrefixSum load_from_file(std::ifstream &ifs)
Returns the DynamicPrefixSum instance loaded from a file stream ifs.
Definition dynamic_prefix_sum.hpp:636
void print_info() const
Print the statistics of this data structure.
Definition dynamic_prefix_sum.hpp:590
DynamicPrefixSum()
Default constructor with |S| = 0.
Definition dynamic_prefix_sum.hpp:40
static std::string name()
Return the name of the DynamicPrefixSum for debugging.
Definition dynamic_prefix_sum.hpp:668
void pop_front()
Remove the first element from S.
Definition dynamic_prefix_sum.hpp:473
void clear()
Clear the elements in S.
Definition dynamic_prefix_sum.hpp:420