b-tree-plus-alpha
Loading...
Searching...
No Matches
dynamic_bit_sequence.hpp
Go to the documentation of this file.
1
6#pragma once
7#include "../bp_tree/bp_tree.hpp"
8#include "./bit_container.hpp"
9
10#include "./bit_forward_iterator.hpp"
11#include "./bit_deque_container.hpp"
12#include "stool/include/light_stool.hpp"
13namespace stool
14{
15 namespace bptree
16 {
17
22 template <typename CONTAINER, typename CONTAINER_ITERATOR, uint64_t MAX_TREE_DEGREE, uint64_t MAX_BIT_CONTAINER_SIZE>
24 {
25
27 using T = uint64_t;
29
30 static inline constexpr int DEFAULT_CONTAINER_DEGREE = 62;
31 //static inline constexpr int DEFAULT_CONTAINER_DEGREE = 124;
32
33 public:
34 Tree tree;
35
40
45 {
46 }
47
52
57
62
63 public:
68
69
73 uint64_t size() const
74 {
75 return this->tree.size();
76 }
77
83 {
84 return this->tree.size_in_bytes();
85 }
86
88
93
94
98 bool empty() const
99 {
100 return this->tree.empty();
101 }
102
108 bool at(uint64_t pos) const
109 {
110 return this->tree.at(pos) & 1;
111 }
112
119 {
120 if (i == 0)
121 {
122 return 0;
123 }
124 else if (i <= this->size())
125 {
126 return this->tree.psum(i - 1);
127 }
128 else
129 {
130 assert(false);
131 throw std::range_error("Error: DynamicBitSequence::rank1()");
132 }
133 }
134
141 {
142 return i - this->rank1(i);
143 }
144
151 int64_t rank(uint64_t i, bool c) const
152 {
153 return c ? this->rank1(i) : this->rank0(i);
154 }
155
162 {
163 int64_t p = this->tree.search(i + 1);
164 if (p == -1)
165 {
166 return p;
167 }
168 else
169 {
170 if (p >= (int64_t)this->size())
171 {
172 return -1;
173 }
174 else
175 {
176 return p;
177 }
178 }
179 }
180
187 {
188 int64_t p = this->tree.select0(i);
189 if (p == -1)
190 {
191 return p;
192 }
193 else
194 {
195 if (p >= (int64_t)this->size())
196 {
197 return -1;
198 }
199 else
200 {
201 return p;
202 }
203 }
204 }
205
212 int64_t select(uint64_t i, bool c) const
213 {
214 return c ? this->select1(i) : this->select0(i);
215 }
216
222 int64_t count_c(bool c) const
223 {
224 uint64_t _size = this->size();
225 if (_size > 0)
226 {
227 return this->rank(_size, c);
228 }
229 else
230 {
231 return 0;
232 }
233 }
234
241 {
242 return this->at(n);
243 }
244
251 {
252 return this->tree.psum(x);
253 }
254
260 {
261 return this->tree.psum();
262 }
263
270 {
271 return this->tree.search(sum);
272 }
273
275
280
281
286 {
287 this->tree.initialize(degree, DynamicBitSequence::DEFAULT_CONTAINER_DEGREE);
288 }
289
295 {
296 this->tree.swap(item.tree);
297 }
298
302 void clear()
303 {
304 this->tree.clear();
305 }
306
311 void push_back(bool value)
312 {
313#if DEBUG
314 uint64_t p = this->size();
315#endif
316 this->tree.push_back(value);
317#if DEBUG
318 assert(p + 1 == this->size());
319#endif
320 }
321
326 void push_front(bool value)
327 {
328 this->tree.push_front(value);
329 }
330
337 {
338 this->tree.insert(pos, value, value);
339 }
340
346 {
348 this->tree.remove(pos);
349 }
350
356 void set_bit(uint64_t i, bool b)
357 {
358 bool b1 = this->at(i);
359 if (b != b1)
360 {
361 if (b)
362 {
363 this->tree.increment(i, 1);
364 }
365 else
366 {
367 this->tree.increment(i, -1);
368 }
369 }
370 }
371
376 {
377 bool b = this->tree.check_if_leaf_container_vec_is_sorted();
378 if (!b)
379 {
380 std::cout << "unsorted" << std::endl;
381 this->tree.sort_leaf_containers();
382 }
383 }
384
389 void push_many(const std::vector<bool> &items)
390 {
391 this->tree.push_many(items);
392 }
393
394 void print_debug_info() const{
395 std::cout << "DynamicBitSequence::print_debug_info()" << std::endl;
396 this->tree.print_debug_info();
397 }
398
400
405
406
411 std::vector<std::string> get_memory_usage_info(int message_paragraph = stool::Message::SHOW_MESSAGE) const
412 {
413 std::vector<std::string> log1 = this->tree.get_memory_usage_info(message_paragraph + 1);
414
415 std::vector<std::string> r;
417 uint64_t size = this->size();
418 double bits_per_element = size > 0 ? ((double)size_in_bytes / (double)size) : 0;
419
420 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "=DynamicBitSequence: " + std::to_string(this->size_in_bytes())
421 + " bytes, " + std::to_string(size) + " elements, " + std::to_string(bits_per_element) + " bytes per element =");
422 for (std::string &s : log1)
423 {
424 r.push_back(s);
425 }
426 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "==");
427 return r;
428 }
429
434 void print_memory_usage(int message_paragraph = stool::Message::SHOW_MESSAGE) const
435 {
436 std::vector<std::string> log = this->get_memory_usage_info(message_paragraph);
437 for (std::string &s : log)
438 {
439 std::cout << s << std::endl;
440 }
441 }
442
447 void print_statistics(int message_paragraph = stool::Message::SHOW_MESSAGE) const
448 {
449 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Statistics(DynamicBitSequence):" << std::endl;
450 this->tree.print_statistics(message_paragraph + 1);
451 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "[END]" << std::endl;
452 }
453
458 void print_content(int message_paragraph = stool::Message::SHOW_MESSAGE) const
459 {
460 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Content(DynamicBitSequence):" << std::endl;
461 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) << "Bits: " << this->to_string() << std::endl;
462 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "[END]" << std::endl;
463 }
464
470 void print(std::string name = "DynamicBitSequence", int message_paragraph = stool::Message::SHOW_MESSAGE) const
471 {
472 std::cout << stool::Message::get_paragraph_string(message_paragraph) << name << ": " << this->to_string() << std::endl;
473 }
475
480
481
485 std::vector<uint64_t> to_value_vector() const
486 {
487 auto vec = this->tree.to_value_vector();
488 std::vector<uint64_t> r;
489 r.resize(vec.size());
490 for (uint64_t i = 0; i < vec.size(); i++)
491 {
492 r[i] = vec[i];
493 }
494 return r;
495 }
496
501 std::string to_string() const
502 {
503 std::string s;
504 std::vector<uint64_t> bits = this->to_value_vector();
505 s.push_back('[');
506 for (uint64_t i = 0; i < bits.size(); i++)
507 {
508 s.push_back(bits[i] >= 1 ? '1' : '0');
509 //assert(bits[i] == this->at(i));
510 }
511 s.push_back(']');
512 return s;
513 }
514
519 std::vector<bool> to_vector() const
520 {
521 uint64_t _size = this->size();
522 std::vector<bool> r;
523 r.resize(_size, false);
524 uint64_t counter = 0;
525
526
527
528
529 auto _end = this->get_leaf_forward_iterator_end();
530
532 while(!it.is_end()){
533 uint64_t bits = *it;
534 uint64_t i = 0;
535
536 while (i < 64 && counter < _size)
537 {
538 bool b = stool::MSBByte::get_bit(bits, i);
539 r[counter] = b;
540
541
542 counter++;
543 i++;
544 }
545 ++it;
546
547 }
548
549 /*
550 for (BitForwardIterator<CONTAINER, CONTAINER_ITERATOR, MAX_TREE_DEGREE, MAX_BIT_CONTAINER_SIZE> it = this->get_bit_forward_iterator_begin(); it != _end; ++it)
551 {
552
553 uint64_t bits = *it;
554 uint64_t i = 0;
555
556
557 while (i < 64 && counter < _size)
558 {
559 bool b = stool::MSBByte::get_bit(bits, i);
560 r[counter] = b;
561
562
563 counter++;
564 i++;
565 }
566 }
567 */
568 assert(counter == _size);
569 return r;
570 }
572
577
578
584 static void save(DynamicBitSequence &item, std::vector<uint8_t> &output, uint64_t &pos)
585 {
586 item.tree.save(output, pos);
587 }
588
594 static void save(DynamicBitSequence &item, std::ofstream &os)
595 {
596 item.tree.save(os);
597 }
598
605 static DynamicBitSequence build(const std::vector<bool> &items)
606 {
608 r.tree.initialize();
609 r.tree.build(items);
610 return r;
611 }
612
613
620 static DynamicBitSequence build_from_data(const std::vector<uint8_t> &data, uint64_t &pos)
621 {
623 r.tree.build_from_data(data, pos);
624 return r;
625 }
626
633 {
635 r.tree.build_from_data(ifs);
636 return r;
637 }
639
644
645
654
664
669
670
674 static std::string name()
675 {
676 std::string s;
677 s += "DynamicSequence(";
678 s += CONTAINER::name();
679 s += ")";
680 return s;
681 }
682
683 void print_information_about_performance(int message_paragraph = stool::Message::SHOW_MESSAGE) const{
684 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Performance Information (DynamicSequence)[" << std::endl;
685 this->tree.print_information_about_performance(message_paragraph + 1);
686 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "]" << std::endl;
687 }
688
689 double density() const{
690 return this->tree.get_value_density();
691 }
692
693 void verify() const{
694 this->tree.verify();
695 }
696
697
699
700
701
702
703 };
704
706
707 using DynamicBitDequeSequence = DynamicBitSequence<BDC, BDC::BitDequeContainerIterator, bptree::DEFAULT_MAX_DEGREE_OF_INTERNAL_NODE, 1024>;
708 using DynamicBitDequeSequenceA = DynamicBitSequence<BDC, BDC::BitDequeContainerIterator, 62, 512>;
709 using DynamicBitDequeSequenceB = DynamicBitSequence<BDC, BDC::BitDequeContainerIterator, 62, 1024>;
710 using DynamicBitDequeSequenceC = DynamicBitSequence<BDC, BDC::BitDequeContainerIterator, 62, 2048>;
711 using DynamicBitDequeSequenceD = DynamicBitSequence<BDC, BDC::BitDequeContainerIterator, 62, 4096>;
712
713 using DynamicBitDequeSequence1 = DynamicBitSequence<BDC, BDC::BitDequeContainerIterator, 14, 8192>;
714 using DynamicBitDequeSequence2 = DynamicBitSequence<BDC, BDC::BitDequeContainerIterator, 30, 8192>;
715 using DynamicBitDequeSequence3 = DynamicBitSequence<BDC, BDC::BitDequeContainerIterator, 62, 8192>;
716 using DynamicBitDequeSequence4 = DynamicBitSequence<BDC, BDC::BitDequeContainerIterator, 126, 8192>;
717
718 using SimpleDynamicBitSequence = DynamicBitSequence<BDC, BDC::BitDequeContainerIterator, 62, 8192>;
719
720 //using DynamicBitDequeSequenceE = DynamicBitSequence<stool::bptree::BitDequeContainer, stool::bptree::BitDequeContainer::BitDequeContainerIterator, 8190, 2048>;
721
722 // template <typename T>
723 // using VLCDequeSeq = DynamicSequence<VLCDeque, T>;
724 }
725
726}
An implementation of B+-tree.
Definition bp_tree.hpp:24
LeafForwardIterator get_leaf_forward_iterator_begin() const
Returns an iterator pointing to the first leaf in forward traversal.
Definition bp_tree.hpp:436
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
int64_t select0(uint64_t i) const
Returns the position of the i-th 0 in the B+ tree.
Definition bp_tree.hpp:525
void build(const std::vector< VALUE > &_values)
Builds a complete B+ tree from a vector of values.
Definition bp_tree.hpp:2857
uint64_t psum() const
Returns the prefix sum of the B+ tree.
Definition bp_tree.hpp:472
void sort_leaf_containers()
Sorts the leaf containers in the B+ tree.
Definition bp_tree.hpp:2536
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
bool check_if_leaf_container_vec_is_sorted() const
Checks if the leaf containers in the B+ tree are sorted.
Definition bp_tree.hpp:2433
void save(std::vector< uint8_t > &output, uint64_t &pos)
Saves the B+ tree structure to a byte vector.
Definition bp_tree.hpp:2912
void push_front(VALUE value)
Inserts a value at the front of the B+ tree.
Definition bp_tree.hpp:1866
bool empty() const
Checks if the B+ tree is empty.
Definition bp_tree.hpp:463
void clear()
Clears all contents of the B+ tree and resets it to an empty state.
Definition bp_tree.hpp:219
void build_from_data(const std::vector< uint8_t > &data, uint64_t &pos)
Builds a B+ tree from serialized data in a byte vector.
Definition bp_tree.hpp:2968
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
A dynamic data structure supporting rank and select queries on a bit sequence.
Definition dynamic_bit_sequence.hpp:24
int64_t rank0(uint64_t i) const
Returns the number of 0s up to position i.
Definition dynamic_bit_sequence.hpp:140
uint64_t size_in_bytes() const
Returns the size of the bit sequence in bytes.
Definition dynamic_bit_sequence.hpp:82
int64_t rank(uint64_t i, bool c) const
Returns the number of bits with value c up to position i.
Definition dynamic_bit_sequence.hpp:151
DynamicBitSequence()
Default constructor initializes the tree with default degree.
Definition dynamic_bit_sequence.hpp:44
DynamicBitSequence(DynamicBitSequence &&) noexcept=default
Default move constructor.
uint64_t psum() const
Returns the total prefix sum.
Definition dynamic_bit_sequence.hpp:259
std::vector< bool > to_vector() const
Converts the bit sequence to a vector of bool.
Definition dynamic_bit_sequence.hpp:519
int64_t select1(uint64_t i) const
Returns the position of the i-th 1.
Definition dynamic_bit_sequence.hpp:161
int64_t select(uint64_t i, bool c) const
Returns the position of the i-th bit with value c.
Definition dynamic_bit_sequence.hpp:212
static DynamicBitSequence build_from_data(const std::vector< uint8_t > &data, uint64_t &pos)
Builds a bit sequence from a vector of uint8_t.
Definition dynamic_bit_sequence.hpp:620
uint64_t psum(uint64_t x) const
Returns the prefix sum up to position x.
Definition dynamic_bit_sequence.hpp:250
bool empty() const
Checks if the bit sequence is empty.
Definition dynamic_bit_sequence.hpp:98
static void save(DynamicBitSequence &item, std::ofstream &os)
Saves the bit sequence to a file.
Definition dynamic_bit_sequence.hpp:594
int64_t rank1(uint64_t i) const
Returns the number of 1s up to position i.
Definition dynamic_bit_sequence.hpp:118
void set_bit(uint64_t i, bool b)
Sets the bit at the specified position.
Definition dynamic_bit_sequence.hpp:356
void print(std::string name="DynamicBitSequence", int message_paragraph=stool::Message::SHOW_MESSAGE) const
Prints the bit sequence.
Definition dynamic_bit_sequence.hpp:470
static DynamicBitSequence build(const std::vector< bool > &items)
Builds a bit sequence from a vector of bool.
Definition dynamic_bit_sequence.hpp:605
void swap(DynamicBitSequence &item)
Swaps the contents of this sequence with another.
Definition dynamic_bit_sequence.hpp:294
std::vector< uint64_t > to_value_vector() const
Converts the bit sequence to a vector of uint64_t.
Definition dynamic_bit_sequence.hpp:485
int64_t count_c(bool c) const
Returns the number of bits with value c in the sequence.
Definition dynamic_bit_sequence.hpp:222
std::string to_string() const
Converts the bit sequence to a string.
Definition dynamic_bit_sequence.hpp:501
void push_many(const std::vector< bool > &items)
Adds multiple bits to the end of the sequence.
Definition dynamic_bit_sequence.hpp:389
DynamicBitSequence(const DynamicBitSequence &)=delete
Deleted copy constructor.
void push_back(bool value)
Adds a bit to the end of the sequence.
Definition dynamic_bit_sequence.hpp:311
static void save(DynamicBitSequence &item, std::vector< uint8_t > &output, uint64_t &pos)
Saves the bit sequence to a vector.
Definition dynamic_bit_sequence.hpp:584
int64_t search(uint64_t sum) const
Searches for the position where the prefix sum equals sum.
Definition dynamic_bit_sequence.hpp:269
DynamicBitSequence & operator=(const DynamicBitSequence &)=delete
Deleted copy assignment operator.
void print_memory_usage(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Prints memory usage information.
Definition dynamic_bit_sequence.hpp:434
uint64_t size() const
Returns the size of the bit sequence.
Definition dynamic_bit_sequence.hpp:73
void print_statistics(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Prints statistics about the bit sequence.
Definition dynamic_bit_sequence.hpp:447
int64_t select0(uint64_t i) const
Returns the position of the i-th 0.
Definition dynamic_bit_sequence.hpp:186
void clear()
Clears the bit sequence.
Definition dynamic_bit_sequence.hpp:302
void remove(uint64_t pos)
Removes the bit at the specified position.
Definition dynamic_bit_sequence.hpp:345
void push_front(bool value)
Adds a bit to the beginning of the sequence.
Definition dynamic_bit_sequence.hpp:326
bool at(uint64_t pos) const
Returns the bit at the specified position.
Definition dynamic_bit_sequence.hpp:108
static DynamicBitSequence build_from_data(std::ifstream &ifs)
Builds a bit sequence from a file.
Definition dynamic_bit_sequence.hpp:632
void set_degree(uint64_t degree)
Sets the degree of the tree.
Definition dynamic_bit_sequence.hpp:285
static std::string name()
Returns the name of the bit sequence.
Definition dynamic_bit_sequence.hpp:674
void print_content(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Prints the content of the bit sequence.
Definition dynamic_bit_sequence.hpp:458
void insert(uint64_t pos, bool value)
Inserts a bit at the specified position.
Definition dynamic_bit_sequence.hpp:336
BitForwardIterator< CONTAINER, CONTAINER_ITERATOR, MAX_TREE_DEGREE, MAX_BIT_CONTAINER_SIZE > get_bit_forward_iterator_begin() const
Returns an iterator to the beginning of the bit sequence.
Definition dynamic_bit_sequence.hpp:649
std::vector< std::string > get_memory_usage_info(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Returns memory usage information.
Definition dynamic_bit_sequence.hpp:411
void sort_leaf_containers()
Sorts the leaf containers.
Definition dynamic_bit_sequence.hpp:375
BitForwardIterator< CONTAINER, CONTAINER_ITERATOR, MAX_TREE_DEGREE, MAX_BIT_CONTAINER_SIZE > get_leaf_forward_iterator_end() const
Returns an iterator to the end of the bit sequence.
Definition dynamic_bit_sequence.hpp:659
bool operator[](uint64_t n) const
Returns the bit at the specified position.
Definition dynamic_bit_sequence.hpp:240