b-tree-plus-alpha
Loading...
Searching...
No Matches
dynamic_prefix_sum.hpp
1#pragma once
2#include "./plain_spsi_container.hpp"
3#include "stool/include/light_stool.hpp"
4#include "stool/include/develop/short_integer_vector.hpp"
5
6namespace stool
7{
8 namespace bptree
9 {
10
15 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>
17 {
18 public:
21 //static inline constexpr int DEFAULT_MAX_COUNT_OF_VALUES_IN_LEAF = 126;
22
23 //static inline constexpr int DEFAULT_MAX_COUNT_OF_VALUES_IN_LEAF = 126;
24 //static inline constexpr int DEFAULT_MAX_COUNT_OF_VALUES_IN_LEAF = 1024;
25
26 private:
27 Tree tree;
28
29 public:
31 {
32 this->tree.initialize();
33 }
34 DynamicPrefixSum(const std::vector<uint64_t> &items){
35 this->tree.initialize();
36 this->tree.build(items);
37 assert(this->size() == items.size());
38 }
39 DynamicPrefixSum &operator=(const DynamicPrefixSum &) = delete;
40 DynamicPrefixSum(DynamicPrefixSum &&) noexcept = default;
41 DynamicPrefixSum &operator=(DynamicPrefixSum &&) noexcept = default;
42
43 public:
48
49 typename Tree::ValueForwardIterator begin() const
50 {
51 return this->tree.get_value_forward_iterator_begin();
52 }
53 typename Tree::ValueForwardIterator end() const
54 {
55 return this->tree.get_value_forward_iterator_end();
56 }
57
59
64
65
71 {
72 return this->tree;
73 }
74
80 {
81 return this->tree.get_max_degree_of_internal_node();
82 }
83
88 uint64_t size() const
89 {
90 return this->tree.size();
91 }
92
99 {
100 return this->tree.at(pos);
101 }
102
108 {
109 return this->tree.size_in_bytes(only_extra_bytes);
110 }
111
113
118
119
123 std::vector<uint64_t> to_vector() const
124 {
125 return this->tree.to_value_vector();
126 }
127
132 std::vector<uint8_t> to_u8_vector() const
133 {
134 std::vector<uint8_t> r;
135 r.resize(this->size(), 0);
136 uint64_t x = 0;
137 for (uint8_t c : *this)
138 {
139 r[x++] = c;
140 }
141 return r;
142 }
143
144 std::string to_string() const
145 {
146 std::stringstream ss;
147 auto vec = this->to_vector();
148 ss << stool::DebugPrinter::to_integer_string(vec);
149 return ss.str();
150 }
152
157
158
159 uint64_t reverse_psum([[maybe_unused]] uint64_t i) const
160 {
161 throw std::runtime_error("No implementation");
162 }
163
168 {
169 return this->tree.psum(i);
170 }
171
176 {
177 return this->tree.psum();
178 }
179
184 {
185 return this->tree.search(x);
186 }
187
188 int64_t predecessor_index(uint64_t value) const
189 {
190 int64_t size = this->size();
191
192 if (size > 0)
193 {
194 uint64_t fst_value = this->at(0);
195 if (value >= fst_value)
196 {
197 if (value > this->psum())
198 {
199 return size - 1;
200 }
201 else
202 {
203 int64_t idx = this->search(value);
204 if (idx >= size)
205 {
206 return size - 1;
207 }
208 else
209 {
210 uint64_t v = this->psum(idx);
211
212 assert(v >= value);
213 if (v > value)
214 {
215 assert(idx - 1 < size);
216 return idx - 1;
217 }
218 else
219 {
220 assert(idx < size);
221 return idx;
222 }
223 }
224 }
225 }
226 else
227 {
228 return -1;
229 }
230 }
231 else
232 {
233 return -1;
234 }
235 }
236 int64_t successor_index(uint64_t value) const
237 {
238 int64_t size = this->size();
239 if (size > 0)
240 {
241 uint64_t lst_value = this->psum();
242 if (value <= lst_value)
243 {
244 int64_t idx = this->search(value);
245 if (idx >= size)
246 {
247 return -1;
248 }
249 else
250 {
251 [[maybe_unused]] uint64_t v = this->psum(idx);
252 assert(v >= value);
253 return idx;
254 }
255 }
256 else
257 {
258 return -1;
259 }
260 }
261 else
262 {
263 return -1;
264 }
265 }
266 uint64_t operator[](uint64_t n) const
267 {
268 return this->tree.at(n);
269 }
270
272
277
278
279 void swap(DynamicPrefixSum &item)
280 {
281 this->tree.swap(item.tree);
282 }
283
287 void clear()
288 {
289 this->tree.clear();
290 }
291
295 void verify() const
296 {
297 this->tree.verify();
298 }
299 void push_back(uint64_t value)
300 {
301 this->tree.push_back(value);
302 }
303 void push_front(uint64_t value)
304 {
305 this->tree.push_front(value);
306 }
307 void pop_back()
308 {
309 this->tree.remove(this->size() - 1);
310 }
311 void pop_front()
312 {
313 this->tree.remove(0);
314 }
315
316 void insert(uint64_t pos, uint64_t value)
317 {
318 this->tree.insert(pos, value, value);
319 }
320 void remove(uint64_t pos)
321 {
322 this->tree.remove(pos);
323 }
324
325 void increment(uint64_t i, int64_t delta)
326 {
327 this->tree.increment(i, delta);
328 }
329 void decrement(uint64_t i, int64_t delta)
330 {
331 this->tree.increment(i, -delta);
332 }
333 void push_many(const std::vector<uint64_t> &items)
334 {
335 this->tree.push_many(items);
336 }
337 void set_value(uint64_t i, uint64_t value){
338 uint64_t old_value = this->at(i);
339 if(old_value > value){
340 this->decrement(i, old_value - value);
341 }
342 else if(old_value < value){
343 this->increment(i, value - old_value);
344 }
345 }
346 void set_values(uint64_t i, const std::vector<uint64_t> &values){
347 assert(i < this->size());
348 assert(i + values.size() <= this->size());
349
350 for(uint64_t j = 0; j < values.size(); j++){
351 this->set_value(i + j, values[j]);
352 }
353 }
354
355 /*
356 void set_degree(uint64_t degree)
357 {
358 this->tree.initialize(degree);
359 }
360 */
361 double density() const{
362 return this->tree.get_value_density();
363 }
364
366
371
372
373 std::vector<std::string> get_memory_usage_info(int message_paragraph = stool::Message::SHOW_MESSAGE) const
374 {
375 std::vector<std::string> log1 = this->tree.get_memory_usage_info(message_paragraph + 1);
376
377 std::vector<std::string> r;
378 uint64_t size_in_bytes = this->size_in_bytes();
379 uint64_t size = this->size();
380 double bits_per_element = size > 0 ? ((double)size_in_bytes / (double)size) : 0;
381
382 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "=DynamicPrefixSum: " + std::to_string(this->size_in_bytes())
383 + " bytes, " + std::to_string(size) + " elements, " + std::to_string(bits_per_element) + " bytes per element =");
384
385 for (std::string &s : log1)
386 {
387 r.push_back(s);
388 }
389
390 uint64_t total_bits_if_sequence_is_plain = 0;
391 for(uint64_t i = 0; i < size; ++i){
392 total_bits_if_sequence_is_plain += stool::LSBByte::get_code_length(this->at(i));
393 }
394
395
396 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));
397 if(total_bits_if_sequence_is_plain > 0){
398 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");
399 }
400
401
402 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "==");
403
404
405 return r;
406 }
407 void print_memory_usage(int message_paragraph = stool::Message::SHOW_MESSAGE) const
408 {
409 std::vector<std::string> log = this->get_memory_usage_info(message_paragraph);
410 for (std::string &s : log)
411 {
412 std::cout << s << std::endl;
413 }
414 }
415 void print_statistics(int message_paragraph = stool::Message::SHOW_MESSAGE) const
416 {
417 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Statistics(DynamicPrefixSum):" << std::endl;
418 this->tree.print_statistics(message_paragraph + 1);
419 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "[END]" << std::endl;
420 }
421 void print_information_about_performance(int message_paragraph = stool::Message::SHOW_MESSAGE) const{
422 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Performance Information (DynamicPrefixSum)[" << std::endl;
423 this->tree.print_information_about_performance(message_paragraph + 1);
424 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "]" << std::endl;
425 }
426
427 void print_tree(int message_paragraph = stool::Message::SHOW_MESSAGE) const{
428
429 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Tree(DynamicPrefixSum)[" << std::endl;
430 this->tree.print_tree();
431 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "]" << std::endl;
432
433 }
434 void print_info() const {
435 this->print_statistics();
436 }
437
439
444
445 static DynamicPrefixSum build(const std::vector<uint64_t> &items)
446 {
447 DynamicPrefixSum r;
448 r.tree.initialize();
449 r.tree.build(items);
450 assert(r.size() == items.size());
451 return r;
452 }
453 /*
454 static DynamicPrefixSum load_from_bytes(const std::vector<uint8_t> &data, uint64_t &pos)
455 {
456 DynamicPrefixSum r;
457 r.tree.load_from_bytes(data, pos);
458 return r;
459 }
460 */
461 static DynamicPrefixSum load_from_bytes(const std::vector<uint8_t> &data, uint64_t &pos)
462 {
463 DynamicPrefixSum r;
464 r.tree.load_from_bytes(data, pos);
465 return r;
466 }
467
468 static DynamicPrefixSum load_from_file(std::ifstream &ifs)
469 {
470 DynamicPrefixSum r;
471 r.tree.load_from_file(ifs);
472 return r;
473 }
474 static DynamicPrefixSum load(std::ifstream &ifs)
475 {
476 return DynamicPrefixSum::load_from_file(ifs);
477 }
478
479 static void store_to_bytes(DynamicPrefixSum &item, std::vector<uint8_t> &output, uint64_t &pos)
480 {
481 Tree::store_to_bytes(item.tree, output, pos);
482 }
483 static void store_to_file(DynamicPrefixSum &item, std::ofstream &os)
484 {
485 Tree::store_to_file(item.tree, os);
486 }
488
493
494 static std::string name()
495 {
496 std::string s;
497 s += "DynamicPrefixSum(";
498 s += LEAF_CONTAINER::name();
499 s += ")";
500 return s;
501 }
503 };
504
505 using SimpleDynamicPrefixSum = DynamicPrefixSum<stool::NaiveFLCVector<>, 62, 256>;
506 using PlainDynamicPrefixSum = DynamicPrefixSum<PlainSPSIContainer>;
507 using VLCDequeDynamicPrefixSum = DynamicPrefixSum<VLCDeque>;
508 //using DynamicSuccinctPrefixSum = DynamicPrefixSum<stool::NaiveVLCArray<4096>, 62, 128>;
509 //using EFDynamicPrefixSum = DynamicPrefixSum<stool::NaiveFLCVector<>, 62, 256>;
510
511 // using GapEncodedSPSI = SPSI<GapEncodedContainer>;
512
513 }
514
515}
An implementation of B+-tree [Unchecked AI's Comment].
Definition bp_tree.hpp:24
std::vector< VALUE > to_value_vector() const
Converts the B+ tree to a vector of values.
Definition bp_tree.hpp:684
void build(const std::vector< VALUE > &_values)
Builds a complete B+ tree from a vector of values.
Definition bp_tree.hpp:2858
ValueForwardIterator get_value_forward_iterator_end() const
Returns an iterator pointing to the end of forward value traversal.
Definition bp_tree.hpp:423
void print_statistics(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Prints statistical information about the B+ tree.
Definition bp_tree.hpp:3038
void increment(uint64_t i, int64_t delta)
Increments a value at a given position in the B+ tree.
Definition bp_tree.hpp:2411
ValueForwardIterator get_value_forward_iterator_begin() const
Returns an iterator pointing to the first value in forward traversal.
Definition bp_tree.hpp:404
int64_t search(uint64_t sum) const
Returns the position of the sum in the B+ tree.
Definition bp_tree.hpp:549
uint64_t size_in_bytes(bool only_extra_bytes=false) const
Returns the total memory size of the B+ tree.
Definition bp_tree.hpp:930
void push_back(VALUE value)
Pushes a single value to the B+ tree.
Definition bp_tree.hpp:1851
void insert(uint64_t pos, VALUE value, uint64_t sum_delta)
Inserts a value at a specific position in the B+ tree.
Definition bp_tree.hpp:2122
void initialize()
Initializes the B+ tree with specified maximum degrees for internal nodes and leaf nodes.
Definition bp_tree.hpp:150
std::vector< std::string > get_memory_usage_info(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Returns a vector of strings containing memory usage information about the B+ tree.
Definition bp_tree.hpp:1070
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
bool verify() const
Verifies the integrity of the B+ tree.
Definition bp_tree.hpp:787
void print_tree() const
Prints the B+ tree in a tree-like format.
Definition bp_tree.hpp:805
VALUE at(uint64_t pos) const
Returns the value at position pos in the B+ tree.
Definition bp_tree.hpp:574
void push_front(VALUE value)
Inserts a value at the front of the B+ tree.
Definition bp_tree.hpp:1868
void remove(uint64_t pos)
Removes a value at a specific position in the B+ tree.
Definition bp_tree.hpp:2088
void swap(BPTree &_tree, bool swap_linked_tree)
Swaps the contents of this B+ tree with another B+ tree.
Definition bp_tree.hpp:178
void push_many(std::vector< LEAF_CONTAINER > &containers)
Pushes multiple leaf containers into the B+ tree.
Definition bp_tree.hpp:1978
void clear()
Clears all contents of the B+ tree and resets it to an empty state.
Definition bp_tree.hpp:219
void resize(uint64_t _size, VALUE default_value)
Resizes the B+ tree to contain a specified number of elements.
Definition bp_tree.hpp:2194
uint64_t psum() const
Returns the prefix sum of the B+ tree.
Definition bp_tree.hpp:472
static void store_to_file(BPTree &bp, std::ofstream &os)
Saves the B+ tree structure to a file stream.
Definition bp_tree.hpp:2945
uint64_t get_max_degree_of_internal_node() const
Return the max degree of this tree. The number of children of every internal node does not exceed the...
Definition bp_tree.hpp:278
The forward iterator of the values stored in BPTree [Unchecked AI's Comment].
Definition bp_value_forward_iterator.hpp:17
A dynamic data structure supporting prefix-sum query [Unchecked AI's Comment].
Definition dynamic_prefix_sum.hpp:17
uint64_t psum() const
Return the sum of the stored values.
Definition dynamic_prefix_sum.hpp:175
uint64_t at(uint64_t pos) const
Return the element at the given position.
Definition dynamic_prefix_sum.hpp:98
Tree & __get_tree()
Get the internal tree of this data structure.
Definition dynamic_prefix_sum.hpp:70
std::vector< uint64_t > to_vector() const
Return the elements stored in this data structure as a vector.
Definition dynamic_prefix_sum.hpp:123
std::vector< uint8_t > to_u8_vector() const
Return the elements stored in this data structure as a vector of uint8_t.
Definition dynamic_prefix_sum.hpp:132
void verify() const
Verify the internal consistency of this data structure.
Definition dynamic_prefix_sum.hpp:295
uint64_t get_degree() const
Get the maximum degree of internal nodes of the internal tree of this data structure.
Definition dynamic_prefix_sum.hpp:79
int64_t search(uint64_t x) const
Return the smallest i such that psum(i) >= x.
Definition dynamic_prefix_sum.hpp:183
uint64_t size_in_bytes(bool only_extra_bytes=false) const
Return the size of this data structure in bytes.
Definition dynamic_prefix_sum.hpp:107
uint64_t size() const
Return the number of elements stored in this data structure.
Definition dynamic_prefix_sum.hpp:88
uint64_t psum(uint64_t i) const
Return the sum of the first (i+1) values stored in this data structure.
Definition dynamic_prefix_sum.hpp:167
void clear()
Clear the elements stored in this data structure.
Definition dynamic_prefix_sum.hpp:287