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
78 uint64_t height() const {
79 return this->tree.height();
80 }
81
87 {
88 return this->tree.size_in_bytes(only_extra_bytes);
89 }
90
92
97
98
102 bool empty() const
103 {
104 return this->tree.empty();
105 }
106
112 bool at(uint64_t pos) const
113 {
114 return this->tree.at(pos) & 1;
115 }
116
123 {
124 if (i == 0)
125 {
126 return 0;
127 }
128 else if (i <= this->size())
129 {
130 uint64_t p = this->tree.psum(i - 1);
131
132
133 return p;
134 }
135 else
136 {
137 assert(false);
138 throw std::range_error("Error: DynamicBitSequence::rank1()");
139 }
140 }
141
148 {
149 return i - this->rank1(i);
150 }
151
158 int64_t rank(uint64_t i, bool c) const
159 {
160 return c ? this->rank1(i) : this->rank0(i);
161 }
162
169 {
170 int64_t p = this->tree.search(i + 1);
171 if (p == -1)
172 {
173 return p;
174 }
175 else
176 {
177 if (p >= (int64_t)this->size())
178 {
179 return -1;
180 }
181 else
182 {
183 return p;
184 }
185 }
186 }
187
194 {
195 int64_t p = this->tree.select0(i);
196 if (p == -1)
197 {
198 return p;
199 }
200 else
201 {
202 if (p >= (int64_t)this->size())
203 {
204 return -1;
205 }
206 else
207 {
208 return p;
209 }
210 }
211 }
212
219 int64_t select(uint64_t i, bool c) const
220 {
221 return c ? this->select1(i) : this->select0(i);
222 }
223
229 int64_t count_c(bool c) const
230 {
231 uint64_t _size = this->size();
232 if (_size > 0)
233 {
234 return this->rank(_size, c);
235 }
236 else
237 {
238 return 0;
239 }
240 }
241
242 int64_t count0() const {
243 uint64_t _size = this->size();
244 if(_size > 0){
245 return this->rank0(_size);
246 }else{
247 return 0;
248 }
249 }
250 int64_t count1() const{
251 uint64_t _size = this->size();
252 if(_size > 0){
253 return this->rank1(_size);
254 }else{
255 return 0;
256 }
257 }
258
265 {
266 return this->at(n);
267 }
268
275 {
276 return this->tree.psum(x);
277 }
278
284 {
285 return this->tree.psum();
286 }
287
294 {
295 return this->tree.search(sum);
296 }
297
299
304
305
310 {
311 this->tree.initialize(degree, DynamicBitSequence::DEFAULT_CONTAINER_DEGREE);
312 }
313
319 {
320 this->tree.swap(item.tree);
321 }
322
326 void clear()
327 {
328 this->tree.clear();
329 }
330
335 void push_back(bool value)
336 {
337#if DEBUG
338 uint64_t p = this->size();
339#endif
340 this->tree.push_back(value);
341#if DEBUG
342 assert(p + 1 == this->size());
343#endif
344 }
345
350 void push_front(bool value)
351 {
352 this->tree.push_front(value);
353 }
354
361 {
362 this->tree.insert(pos, value, value);
363 }
364
370 {
372 this->tree.remove(pos);
373 }
374
380 void set_bit(uint64_t i, bool b)
381 {
382 bool b1 = this->at(i);
383 if (b != b1)
384 {
385 if (b)
386 {
387 this->tree.increment(i, 1);
388 }
389 else
390 {
391 this->tree.increment(i, -1);
392 }
393 }
394 }
395
396 void set_bits(uint64_t i, std::vector<bool> &bits){
397 for(uint64_t j = 0; j < bits.size(); j++){
398 this->set_bit(i + j, bits[j]);
399 }
400 }
401
406 {
407 bool b = this->tree.check_if_leaf_container_vec_is_sorted();
408 if (!b)
409 {
410 std::cout << "unsorted" << std::endl;
411 this->tree.sort_leaf_containers();
412 }
413 }
414
419 void push_many(const std::vector<bool> &items)
420 {
421 this->tree.push_many(items);
422 }
423
424 void print_debug_info() const{
425 std::cout << "DynamicBitSequence::print_debug_info()" << std::endl;
426 this->tree.print_debug_info();
427 }
428
430
435
436
441 std::vector<std::string> get_memory_usage_info(int message_paragraph = stool::Message::SHOW_MESSAGE) const
442 {
443 std::vector<std::string> log1 = this->tree.get_memory_usage_info(message_paragraph + 1);
444
445 std::vector<std::string> r;
447 uint64_t size = this->size();
448 double bits_per_element = size > 0 ? ((double)size_in_bytes / (double)size) : 0;
449
450 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "=DynamicBitSequence: " + std::to_string(this->size_in_bytes())
451 + " bytes, " + std::to_string(size) + " elements, " + std::to_string(bits_per_element) + " bytes per element =");
452 for (std::string &s : log1)
453 {
454 r.push_back(s);
455 }
456 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "==");
457 return r;
458 }
459
464 void print_memory_usage(int message_paragraph = stool::Message::SHOW_MESSAGE) const
465 {
466 std::vector<std::string> log = this->get_memory_usage_info(message_paragraph);
467 for (std::string &s : log)
468 {
469 std::cout << s << std::endl;
470 }
471 }
472
477 void print_statistics(int message_paragraph = stool::Message::SHOW_MESSAGE) const
478 {
479 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Statistics(DynamicBitSequence):" << std::endl;
480 this->tree.print_statistics(message_paragraph + 1);
481 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "[END]" << std::endl;
482 }
483
488 void print_content(int message_paragraph = stool::Message::SHOW_MESSAGE) const
489 {
490 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Content(DynamicBitSequence):" << std::endl;
491 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) << "Bits: " << this->to_string() << std::endl;
492 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "[END]" << std::endl;
493 }
494
500 void print(std::string name = "DynamicBitSequence", int message_paragraph = stool::Message::SHOW_MESSAGE) const
501 {
502 std::cout << stool::Message::get_paragraph_string(message_paragraph) << name << ": " << this->to_string() << std::endl;
503 }
505
510
511
515 std::vector<uint64_t> to_value_vector() const
516 {
517 auto vec = this->tree.to_value_vector();
518 std::vector<uint64_t> r;
519 r.resize(vec.size());
520 for (uint64_t i = 0; i < vec.size(); i++)
521 {
522 r[i] = vec[i];
523 }
524 return r;
525 }
526
531 std::string to_string() const
532 {
533 std::string s;
534 std::vector<uint64_t> bits = this->to_value_vector();
535 s.push_back('[');
536 for (uint64_t i = 0; i < bits.size(); i++)
537 {
538 s.push_back(bits[i] >= 1 ? '1' : '0');
539 //assert(bits[i] == this->at(i));
540 }
541 s.push_back(']');
542 return s;
543 }
544
549 std::vector<bool> to_vector() const
550 {
551 uint64_t _size = this->size();
552 std::vector<bool> r;
553 r.resize(_size, false);
554 uint64_t counter = 0;
555
556
557
558
559 auto _end = this->get_leaf_forward_iterator_end();
560
562 while(!it.is_end()){
563 uint64_t bits = *it;
564 uint64_t i = 0;
565
566 while (i < 64 && counter < _size)
567 {
568 bool b = stool::MSBByte::get_bit(bits, i);
569 r[counter] = b;
570
571
572 counter++;
573 i++;
574 }
575 ++it;
576
577 }
578
579 /*
580 for (BitForwardIterator<CONTAINER, CONTAINER_ITERATOR, MAX_TREE_DEGREE, MAX_BIT_CONTAINER_SIZE> it = this->get_bit_forward_iterator_begin(); it != _end; ++it)
581 {
582
583 uint64_t bits = *it;
584 uint64_t i = 0;
585
586
587 while (i < 64 && counter < _size)
588 {
589 bool b = stool::MSBByte::get_bit(bits, i);
590 r[counter] = b;
591
592
593 counter++;
594 i++;
595 }
596 }
597 */
598 assert(counter == _size);
599 return r;
600 }
602
607
608
614 static void store_to_bytes(DynamicBitSequence &item, std::vector<uint8_t> &output, uint64_t &pos)
615 {
617 }
618
624 static void store_to_file(DynamicBitSequence &item, std::ofstream &os)
625 {
627 }
628
635 static DynamicBitSequence build(const std::vector<bool> &items)
636 {
638 r.tree.initialize();
639 r.tree.build(items);
640 return r;
641 }
642
643
650 static DynamicBitSequence load_from_bytes(const std::vector<uint8_t> &data, uint64_t &pos)
651 {
653 r.tree.load_from_bytes(data, pos);
654 return r;
655 }
656
662 static DynamicBitSequence load_from_file(std::ifstream &ifs)
663 {
665 r.tree.load_from_file(ifs);
666 return r;
667 }
669
674
675
684
694
699
700
704 static std::string name()
705 {
706 std::string s;
707 s += "DynamicSequence(";
708 s += CONTAINER::name();
709 s += ")";
710 return s;
711 }
712
713 void print_information_about_performance(int message_paragraph = stool::Message::SHOW_MESSAGE) const{
714 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Performance Information (DynamicSequence)[" << std::endl;
715 this->tree.print_information_about_performance(message_paragraph + 1);
716 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "]" << std::endl;
717 }
718
719 double density() const{
720 return this->tree.get_value_density();
721 }
722
723 void verify() const{
724 this->tree.verify();
725 }
726
727
729
730
731
732
733 };
734
736
737 using DynamicBitDequeSequence = DynamicBitSequence<BDC, BDC::BitVectorContainerIterator, bptree::DEFAULT_MAX_DEGREE_OF_INTERNAL_NODE, 1024>;
738 //using SimpleDynamicBitSequence = DynamicBitSequence<BDC, BDC::BitVectorContainerIterator, 62, 8192>;
739 using SimpleDynamicBitSequence = DynamicBitSequence<BDC, BDC::BitVectorContainerIterator, 62, 8192>;
740
741 /*
742 using DynamicBitDequeSequenceA = DynamicBitSequence<BDC, BDC::BitVectorContainerIterator, 62, 512>;
743 using DynamicBitDequeSequenceB = DynamicBitSequence<BDC, BDC::BitVectorContainerIterator, 62, 1024>;
744 using DynamicBitDequeSequenceC = DynamicBitSequence<BDC, BDC::BitVectorContainerIterator, 62, 2048>;
745 using DynamicBitDequeSequenceD = DynamicBitSequence<BDC, BDC::BitVectorContainerIterator, 62, 4096>;
746
747 using DynamicBitDequeSequence1 = DynamicBitSequence<BDC, BDC::BitVectorContainerIterator, 14, 8192>;
748 using DynamicBitDequeSequence2 = DynamicBitSequence<BDC, BDC::BitVectorContainerIterator, 30, 8192>;
749 using DynamicBitDequeSequence3 = DynamicBitSequence<BDC, BDC::BitVectorContainerIterator, 62, 8192>;
750 using DynamicBitDequeSequence4 = DynamicBitSequence<BDC, BDC::BitVectorContainerIterator, 126, 8192>;
751 */
752
753 //using DynamicBitDequeSequenceE = DynamicBitSequence<stool::bptree::BitVectorContainer, stool::bptree::BitVectorContainer::BitVectorContainerIterator, 8190, 2048>;
754
755 // template <typename T>
756 // using VLCDequeSeq = DynamicSequence<VLCDeque, T>;
757 }
758
759}
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
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
bool check_if_leaf_container_vec_is_sorted() const
Checks if the leaf containers in the B+ tree are sorted.
Definition bp_tree.hpp:2434
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
bool empty() const
Checks if the B+ tree is empty.
Definition bp_tree.hpp:463
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
LeafForwardIterator get_leaf_forward_iterator_begin() const
Returns an iterator pointing to the first leaf in forward traversal.
Definition bp_tree.hpp:436
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
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
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 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 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
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
void sort_leaf_containers()
Sorts the leaf containers in the B+ tree.
Definition bp_tree.hpp:2537
uint64_t height() const
Return the height of this tree.
Definition bp_tree.hpp:308
static void store_to_file(BPTree &bp, std::ofstream &os)
Saves the B+ tree structure to a file stream.
Definition bp_tree.hpp:2945
A dynamic data structure supporting rank and select queries on a bit sequence [Unchecked AI's Comment...
Definition dynamic_bit_sequence.hpp:24
int64_t rank0(uint64_t i) const
Returns the number of 0 in S[0..i-1].
Definition dynamic_bit_sequence.hpp:147
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:158
DynamicBitSequence()
Default constructor initializes the tree with default degree.
Definition dynamic_bit_sequence.hpp:44
DynamicBitSequence(DynamicBitSequence &&) noexcept=default
Default move constructor.
uint64_t size_in_bytes(bool only_extra_bytes=false) const
Returns the size of the bit sequence in bytes.
Definition dynamic_bit_sequence.hpp:86
uint64_t psum() const
Returns the total prefix sum.
Definition dynamic_bit_sequence.hpp:283
static void store_to_file(DynamicBitSequence &item, std::ofstream &os)
Saves the bit sequence to a file.
Definition dynamic_bit_sequence.hpp:624
std::vector< bool > to_vector() const
Converts the bit sequence to a vector of bool.
Definition dynamic_bit_sequence.hpp:549
int64_t select1(uint64_t i) const
Returns the position of the i-th 1.
Definition dynamic_bit_sequence.hpp:168
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:219
uint64_t psum(uint64_t x) const
Returns the prefix sum up to position x.
Definition dynamic_bit_sequence.hpp:274
bool empty() const
Checks if the bit sequence is empty.
Definition dynamic_bit_sequence.hpp:102
int64_t rank1(uint64_t i) const
Returns the number of 1 in S[0..i-1].
Definition dynamic_bit_sequence.hpp:122
void set_bit(uint64_t i, bool b)
Sets the bit at the specified position.
Definition dynamic_bit_sequence.hpp:380
void print(std::string name="DynamicBitSequence", int message_paragraph=stool::Message::SHOW_MESSAGE) const
Prints the bit sequence.
Definition dynamic_bit_sequence.hpp:500
static DynamicBitSequence build(const std::vector< bool > &items)
Builds a bit sequence from a vector of bool.
Definition dynamic_bit_sequence.hpp:635
void swap(DynamicBitSequence &item)
Swaps the contents of this sequence with another.
Definition dynamic_bit_sequence.hpp:318
std::vector< uint64_t > to_value_vector() const
Converts the bit sequence to a vector of uint64_t.
Definition dynamic_bit_sequence.hpp:515
int64_t count_c(bool c) const
Returns the number of bits with value c in the sequence.
Definition dynamic_bit_sequence.hpp:229
std::string to_string() const
Converts the bit sequence to a string.
Definition dynamic_bit_sequence.hpp:531
void push_many(const std::vector< bool > &items)
Adds multiple bits to the end of the sequence.
Definition dynamic_bit_sequence.hpp:419
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:335
int64_t search(uint64_t sum) const
Searches for the position where the prefix sum equals sum.
Definition dynamic_bit_sequence.hpp:293
static DynamicBitSequence load_from_file(std::ifstream &ifs)
Builds a bit sequence from a file.
Definition dynamic_bit_sequence.hpp:662
DynamicBitSequence & operator=(const DynamicBitSequence &)=delete
Deleted copy assignment operator.
static void store_to_bytes(DynamicBitSequence &item, std::vector< uint8_t > &output, uint64_t &pos)
Saves the bit sequence to a vector.
Definition dynamic_bit_sequence.hpp:614
void print_memory_usage(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Prints memory usage information.
Definition dynamic_bit_sequence.hpp:464
uint64_t size() const
Returns the size of the bit sequence.
Definition dynamic_bit_sequence.hpp:73
static DynamicBitSequence load_from_bytes(const std::vector< uint8_t > &data, uint64_t &pos)
Builds a bit sequence from a vector of uint8_t.
Definition dynamic_bit_sequence.hpp:650
void print_statistics(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Prints statistics about the bit sequence.
Definition dynamic_bit_sequence.hpp:477
int64_t select0(uint64_t i) const
Returns the position of the i-th 0.
Definition dynamic_bit_sequence.hpp:193
void clear()
Clears the bit sequence.
Definition dynamic_bit_sequence.hpp:326
void remove(uint64_t pos)
Removes the bit at the specified position.
Definition dynamic_bit_sequence.hpp:369
void push_front(bool value)
Adds a bit to the beginning of the sequence.
Definition dynamic_bit_sequence.hpp:350
bool at(uint64_t pos) const
Returns the bit at the specified position.
Definition dynamic_bit_sequence.hpp:112
void set_degree(uint64_t degree)
Sets the degree of the tree.
Definition dynamic_bit_sequence.hpp:309
static std::string name()
Returns the name of the bit sequence.
Definition dynamic_bit_sequence.hpp:704
void print_content(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Prints the content of the bit sequence.
Definition dynamic_bit_sequence.hpp:488
void insert(uint64_t pos, bool value)
Inserts a bit at the specified position.
Definition dynamic_bit_sequence.hpp:360
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:679
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:441
void sort_leaf_containers()
Sorts the leaf containers.
Definition dynamic_bit_sequence.hpp:405
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:689
bool operator[](uint64_t n) const
Returns the bit at the specified position.
Definition dynamic_bit_sequence.hpp:264