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();
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
163 {
164 return this->tree.psum(i);
165 }
166
171 {
172 return this->tree.psum();
173 }
174
179 {
180 return this->tree.search(x);
181 }
182
183 int64_t predecessor_index(uint64_t value) const
184 {
185 int64_t size = this->size();
186
187 if (size > 0)
188 {
189 uint64_t fst_value = this->at(0);
190 if (value >= fst_value)
191 {
192 if (value > this->psum())
193 {
194 return size - 1;
195 }
196 else
197 {
198 int64_t idx = this->search(value);
199 if (idx >= size)
200 {
201 return size - 1;
202 }
203 else
204 {
205 uint64_t v = this->psum(idx);
206
207 assert(v >= value);
208 if (v > value)
209 {
210 assert(idx - 1 < size);
211 return idx - 1;
212 }
213 else
214 {
215 assert(idx < size);
216 return idx;
217 }
218 }
219 }
220 }
221 else
222 {
223 return -1;
224 }
225 }
226 else
227 {
228 return -1;
229 }
230 }
231 int64_t successor_index(uint64_t value) const
232 {
233 int64_t size = this->size();
234 if (size > 0)
235 {
236 uint64_t lst_value = this->psum();
237 if (value <= lst_value)
238 {
239 int64_t idx = this->search(value);
240 if (idx >= size)
241 {
242 return -1;
243 }
244 else
245 {
246 [[maybe_unused]] uint64_t v = this->psum(idx);
247 assert(v >= value);
248 return idx;
249 }
250 }
251 else
252 {
253 return -1;
254 }
255 }
256 else
257 {
258 return -1;
259 }
260 }
261 uint64_t operator[](uint64_t n) const
262 {
263 return this->tree.at(n);
264 }
265
267
272
273
274 void swap(DynamicPrefixSum &item)
275 {
276 this->tree.swap(item.tree);
277 }
278
282 void clear()
283 {
284 this->tree.clear();
285 }
286
290 void verify() const
291 {
292 this->tree.verify();
293 }
294 void push_back(uint64_t value)
295 {
296 this->tree.push_back(value);
297 }
298 void push_front(uint64_t value)
299 {
300 this->tree.push_front(value);
301 }
302 void pop_back()
303 {
304 this->tree.remove(this->size() - 1);
305 }
306 void pop_front()
307 {
308 this->tree.remove(0);
309 }
310
311 void insert(uint64_t pos, uint64_t value)
312 {
313 this->tree.insert(pos, value, value);
314 }
315 void remove(uint64_t pos)
316 {
317 this->tree.remove(pos);
318 }
319
320 void increment(uint64_t i, int64_t delta)
321 {
322 this->tree.increment(i, delta);
323 }
324 void decrement(uint64_t i, int64_t delta)
325 {
326 this->tree.increment(i, -delta);
327 }
328 void push_many(const std::vector<uint64_t> &items)
329 {
330 this->tree.push_many(items);
331 }
332 void set_value(uint64_t i, uint64_t value){
333 uint64_t old_value = this->at(i);
334 if(old_value > value){
335 this->decrement(i, old_value - value);
336 }
337 else if(old_value < value){
338 this->increment(i, value - old_value);
339 }
340 }
341
342 /*
343 void set_degree(uint64_t degree)
344 {
345 this->tree.initialize(degree);
346 }
347 */
348 double density() const{
349 return this->tree.get_value_density();
350 }
351
353
358
359
360 std::vector<std::string> get_memory_usage_info(int message_paragraph = stool::Message::SHOW_MESSAGE) const
361 {
362 std::vector<std::string> log1 = this->tree.get_memory_usage_info(message_paragraph + 1);
363
364 std::vector<std::string> r;
365 uint64_t size_in_bytes = this->size_in_bytes();
366 uint64_t size = this->size();
367 double bits_per_element = size > 0 ? ((double)size_in_bytes / (double)size) : 0;
368
369 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "=DynamicPrefixSum: " + std::to_string(this->size_in_bytes())
370 + " bytes, " + std::to_string(size) + " elements, " + std::to_string(bits_per_element) + " bytes per element =");
371
372 for (std::string &s : log1)
373 {
374 r.push_back(s);
375 }
376
377 uint64_t total_bits_if_sequence_is_plain = 0;
378 for(uint64_t i = 0; i < size; ++i){
379 total_bits_if_sequence_is_plain += stool::LSBByte::get_code_length(this->at(i));
380 }
381
382
383 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));
384 if(total_bits_if_sequence_is_plain > 0){
385 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");
386 }
387
388
389 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "==");
390
391
392 return r;
393 }
394 void print_memory_usage(int message_paragraph = stool::Message::SHOW_MESSAGE) const
395 {
396 std::vector<std::string> log = this->get_memory_usage_info(message_paragraph);
397 for (std::string &s : log)
398 {
399 std::cout << s << std::endl;
400 }
401 }
402 void print_statistics(int message_paragraph = stool::Message::SHOW_MESSAGE) const
403 {
404 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Statistics(DynamicPrefixSum):" << std::endl;
405 this->tree.print_statistics(message_paragraph + 1);
406 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "[END]" << std::endl;
407 }
408 void print_information_about_performance(int message_paragraph = stool::Message::SHOW_MESSAGE) const{
409 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Performance Information (DynamicPrefixSum)[" << std::endl;
410 this->tree.print_information_about_performance(message_paragraph + 1);
411 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "]" << std::endl;
412 }
413
414 void print_tree(int message_paragraph = stool::Message::SHOW_MESSAGE) const{
415
416 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Tree(DynamicPrefixSum)[" << std::endl;
417 this->tree.print_tree();
418 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "]" << std::endl;
419
420 }
421
423
428
429 static DynamicPrefixSum build(const std::vector<uint64_t> &items)
430 {
431 DynamicPrefixSum r;
432 r.tree.initialize();
433 r.tree.build(items);
434 assert(r.size() == items.size());
435 return r;
436 }
437 static DynamicPrefixSum build_from_data(const std::vector<uint8_t> &data, uint64_t &pos)
438 {
439 DynamicPrefixSum r;
440 r.tree.build_from_data(data, pos);
441 return r;
442 }
443
444 static DynamicPrefixSum build_from_data(std::ifstream &ifs)
445 {
446 DynamicPrefixSum r;
447 r.tree.build_from_data(ifs);
448 return r;
449 }
450 static void save(DynamicPrefixSum &item, std::vector<uint8_t> &output, uint64_t &pos)
451 {
452 item.tree.save(output, pos);
453 }
454 static void save(DynamicPrefixSum &item, std::ofstream &os)
455 {
456 item.tree.save(os);
457 }
459
464
465 static std::string name()
466 {
467 std::string s;
468 s += "DynamicPrefixSum(";
469 s += LEAF_CONTAINER::name();
470 s += ")";
471 return s;
472 }
474 };
475
476 using SimpleDynamicPrefixSum = DynamicPrefixSum<stool::NaiveFLCVector<>, 62, 256>;
477 using PlainDynamicPrefixSum = DynamicPrefixSum<PlainSPSIContainer>;
478 using VLCDequeDynamicPrefixSum = DynamicPrefixSum<VLCDeque>;
479 //using DynamicSuccinctPrefixSum = DynamicPrefixSum<stool::NaiveVLCArray<4096>, 62, 128>;
480 //using EFDynamicPrefixSum = DynamicPrefixSum<stool::NaiveFLCVector<>, 62, 256>;
481
482 // using GapEncodedSPSI = SPSI<GapEncodedContainer>;
483
484 }
485
486}
An implementation of B+-tree.
Definition bp_tree.hpp:24
void swap(BPTree &_tree, bool swap_linked_tree)
Swaps the contents of this B+ tree with another B+ tree.
Definition bp_tree.hpp:178
VALUE at(uint64_t pos) const
Returns the value at position pos in the B+ tree.
Definition bp_tree.hpp:574
void initialize()
Initializes the B+ tree with specified maximum degrees for internal nodes and leaf nodes.
Definition bp_tree.hpp:150
void push_many(std::vector< LEAF_CONTAINER > &containers)
Pushes multiple leaf containers into the B+ tree.
Definition bp_tree.hpp:1976
void print_statistics(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Prints statistical information about the B+ tree.
Definition bp_tree.hpp:3037
void increment(uint64_t i, int64_t delta)
Increments a value at a given position in the B+ tree.
Definition bp_tree.hpp:2410
std::vector< VALUE > to_value_vector() const
Converts the B+ tree to a vector of values.
Definition bp_tree.hpp:685
void resize(uint64_t _size, VALUE default_value)
Resizes the B+ tree to contain a specified number of elements.
Definition bp_tree.hpp:2190
uint64_t size() const
Return the number of values stored in this tree.
Definition bp_tree.hpp:316
int64_t search(uint64_t sum) const
Returns the position of the sum in the B+ tree.
Definition bp_tree.hpp:549
void build(const std::vector< VALUE > &_values)
Builds a complete B+ tree from a vector of values.
Definition bp_tree.hpp:2857
ValueForwardIterator get_value_forward_iterator_begin() const
Returns an iterator pointing to the first value in forward traversal.
Definition bp_tree.hpp:404
uint64_t psum() const
Returns the prefix sum of the B+ tree.
Definition bp_tree.hpp:472
ValueForwardIterator get_value_forward_iterator_end() const
Returns an iterator pointing to the end of forward value traversal.
Definition bp_tree.hpp:423
void push_back(VALUE value)
Pushes a single value to the B+ tree.
Definition bp_tree.hpp:1849
void remove(uint64_t pos)
Removes a value at a specific position in the B+ tree.
Definition bp_tree.hpp:2086
void push_front(VALUE value)
Inserts a value at the front of the B+ tree.
Definition bp_tree.hpp:1866
void print_tree() const
Prints the B+ tree in a tree-like format.
Definition bp_tree.hpp:806
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
void clear()
Clears all contents of the B+ tree and resets it to an empty state.
Definition bp_tree.hpp:219
uint64_t size_in_bytes() const
Returns the total memory size of the B+ tree.
Definition bp_tree.hpp:931
bool verify() const
Verifies the integrity of the B+ tree.
Definition bp_tree.hpp:788
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:2120
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:1068
The forward iterator of the values stored in BPTree.
Definition bp_value_forward_iterator.hpp:17
A dynamic data structure supporting prefix-sum query.
Definition dynamic_prefix_sum.hpp:17
uint64_t psum() const
Return the sum of the stored values.
Definition dynamic_prefix_sum.hpp:170
uint64_t at(uint64_t pos) const
Return the element at the given position.
Definition dynamic_prefix_sum.hpp:98
uint64_t size_in_bytes() const
Return the size of this data structure in bytes.
Definition dynamic_prefix_sum.hpp:107
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:290
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:178
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 values stored in this data structure.
Definition dynamic_prefix_sum.hpp:162
void clear()
Clear the elements stored in this data structure.
Definition dynamic_prefix_sum.hpp:282