b-tree-plus-alpha
Loading...
Searching...
No Matches
bit_container.hpp
1#pragma once
2#include "../bp_tree/bp_tree.hpp"
3
4namespace stool
5{
6 namespace bptree
7 {
12 {
13 uint64_t bits = 1;
14
15 public:
17 {
18
19 public:
20 uint64_t bits;
21 uint16_t index;
22
23 using iterator_category = std::random_access_iterator_tag;
24 using value_type = bool;
25 using difference_type = std::ptrdiff_t;
26
27 BitContainerIterator() : bits(0), index(UINT16_MAX) {}
29
30 bool operator*() const
31 {
32 return stool::LSBByte::get_bit(this->bits, index);
33 }
34 uint64_t get_size() const
35 {
36 return stool::LSBByte::get_code_length(this->bits) - 1;
37 }
38 bool is_end() const
39 {
40 return this->index == UINT16_MAX;
41 }
42
43 BitContainerIterator &operator++()
44 {
45 uint64_t size = this->get_size();
46 if ((uint64_t)(this->index + 1) < size)
47 {
48 this->index++;
49 }
50 else if ((uint64_t)(this->index + 1) == size)
51 {
52 this->index = UINT16_MAX;
53 }
54 else
55 {
56 throw std::invalid_argument("Error: BitDequeIterator::operator++()");
57 }
58
59 return *this;
60 }
61
62 BitContainerIterator operator++(int)
63 {
65
66 ++(*this);
67 return temp;
68 }
69
70 BitContainerIterator &operator--()
71 {
72 if (this->index > 1)
73 {
74 this->index--;
75 }
76 else
77 {
78 throw std::invalid_argument("Error: BitDequeIterator::operator--()");
79 }
80
81 return *this;
82 }
83
84 BitContainerIterator operator--(int)
85 {
87 --(*this);
88 return temp;
89 }
90
91 BitContainerIterator operator+(difference_type n) const
92 {
93 if ((uint64_t)(this->index + n) < this->get_size())
94 {
95 return BitContainerIterator(this->bits, this->index + n);
96 }
97 else
98 {
99 return BitContainerIterator(this->bits, UINT16_MAX);
100 }
101 }
102
103 BitContainerIterator &operator+=(difference_type n)
104 {
105 if ((uint64_t)(this->index + n) < this->get_size())
106 {
107 this->index += n;
108 }
109 else
110 {
111 this->index = UINT16_MAX;
112 }
113 return *this;
114 }
115
116 BitContainerIterator operator-(difference_type n) const
117 {
118 if (this->index - n >= 0)
119 {
120 return BitContainerIterator(this->bits, this->index - n);
121 }
122 else
123 {
124 throw std::invalid_argument("Error: BitContainerIterator::operator-()");
125 }
126 }
127
128 BitContainerIterator &operator-=(difference_type n)
129 {
130 if (this->index < n)
131 {
132 throw std::invalid_argument("Error: BitDequeIterator::operator-()");
133 }
134 this->index -= n;
135 return *this;
136 }
137
138 uint64_t read_64bit_MSB_string() const
139 {
140 uint64_t size = this->get_size();
141 if (this->index == size)
142 {
143 throw std::invalid_argument("Error: BitContainerIterator::read_64_bit_string()");
144 }
145 else if (size == 0)
146 {
147 return 0;
148 }
149 else
150 {
151 uint64_t p = size - this->index;
153
154
155 for(uint64_t x = 0; x < p; x++){
156 uint64_t y = x + this->index;
157 if(stool::LSBByte::get_bit(this->bits, y)){
158 return_bits = return_bits | (1ULL << (63-x));
159 }
160 }
161
162 return return_bits;
163 }
164 }
165
166
167 difference_type operator-(const BitContainerIterator &other) const
168 {
169 return (int16_t)this->index - (int16_t)other.index;
170 }
171
175 bool operator==(const BitContainerIterator &other) const { return this->index == other.index; }
176
180 bool operator!=(const BitContainerIterator &other) const { return this->index != other.index; }
181
185 bool operator<(const BitContainerIterator &other) const { return this->index < other.index; }
186
190 bool operator>(const BitContainerIterator &other) const { return this->index > other.index; }
191
195 bool operator<=(const BitContainerIterator &other) const { return this->index <= other.index; }
196
200 bool operator>=(const BitContainerIterator &other) const { return this->index >= other.index; }
201 };
202
204 {
205 }
206 BitContainer(std::vector<uint64_t> &_items)
207 {
208 for (uint64_t x : _items)
209 {
210 this->push_back(x);
211 }
212 }
213 BitContainer(std::vector<bool> &_items)
214 {
215 for (uint64_t i = 0; i < _items.size(); i++)
216 {
217 this->push_back(_items[i]);
218 }
219 }
220
221 void swap(BitContainer &item)
222 {
223 std::swap(this->bits, item.bits);
224 }
225 uint64_t size() const
226 {
227 return stool::LSBByte::get_code_length(this->bits) - 1;
228 }
229 uint64_t size_in_bytes(bool only_extra_bytes) const
230 {
231 if (only_extra_bytes)
232 {
233 return 0;
234 }
235 else
236 {
237 return sizeof(uint64_t);
238 }
239 }
240 uint64_t unused_size_in_bytes() const
241 {
242 return 0;
243 }
244
245 uint64_t at(uint64_t pos) const
246 {
247 return stool::LSBByte::get_bit(this->bits, pos);
248 }
249 void print() const
250 {
251 throw std::runtime_error("Error: BitContainer");
252 }
253
254 void clear()
255 {
256 this->bits = 1;
257 }
258 static std::string name()
259 {
260 return "Bits";
261 }
262 uint64_t psum(uint64_t i) const noexcept
263 {
264 uint64_t x = (this->bits << (63 - i));
265 return __builtin_popcountll(x);
266 }
267 uint64_t psum() const noexcept
268 {
269 return __builtin_popcountll(this->bits) - 1;
270 }
271 int64_t search(uint64_t x) const noexcept
272 {
273 if (x == 0)
274 {
275 return 0;
276 }
277 else
278 {
279 uint64_t count = this->psum();
280 if (x <= count)
281 {
282 return stool::LSBByte::select1(this->bits, x - 1);
283 }
284 else
285 {
286 return -1;
287 }
288 }
289 }
290
291 std::string to_string() const
292 {
293 std::string s;
294 for (uint64_t i = 0; i < this->size(); i++)
295 {
296 if (this->at(i) >= 1)
297 {
298 s.push_back('1');
299 }
300 else
301 {
302 s.push_back('0');
303 }
304 }
305
306 return s;
307 }
308 std::vector<uint64_t> to_value_vector() const
309 {
310 std::vector<uint64_t> r;
311 for (uint64_t i = 0; i < this->size(); i++)
312 {
313 r.push_back(this->at(i));
314 }
315 return r;
316 }
317 uint64_t to_uint64() const
318 {
319 return stool::LSBByte::write_bit(this->bits, this->size(), false);
320 }
321
322 template <typename VEC>
323 void to_values(VEC &output_vec) const
324 {
325 output_vec.clear();
326 output_vec.resize(this->size());
327 for (uint64_t i = 0; i < this->size(); i++)
328 {
329 output_vec[i] = this->at(i);
330 }
331 }
332
333 void insert(uint64_t pos, uint64_t value)
334 {
335 assert(this->size() + 1 < 64);
336 this->bits = stool::LSBByte::insert_bit(this->bits, pos, value >= 1);
337 }
338 void remove(uint64_t pos)
339 {
340 assert(this->size() > 0);
341 this->bits = stool::LSBByte::remove_bit(this->bits, pos);
342 }
343 void push_front(std::vector<uint64_t> &new_items)
344 {
345 assert(this->size() + new_items.size() < 64);
346
347 for (int64_t i = new_items.size() - 1; i >= 0; i--)
348 {
349 this->push_front(new_items[i]);
350 }
351 }
352 void push_front(uint64_t new_item)
353 {
354 assert(this->size() + 1 < 64);
355 this->bits = (this->bits << 1) | (new_item >= 1 ? 1 : 0);
356 }
357
358 void push_back(std::vector<uint64_t> &new_items)
359 {
360 assert(this->size() + 1 < 64);
361 assert(this->size() + new_items.size() < 64);
362
363 for (uint64_t v : new_items)
364 {
365 this->push_back(v);
366 }
367 }
368 void verify() const{
369
370 }
371 void push_back(uint64_t value)
372 {
373 assert(this->size() + 1 < 64);
374 this->bits = stool::LSBByte::insert_bit(this->bits, this->size(), value >= 1);
375 }
376 void pop_front()
377 {
378 assert(this->size() > 0);
379 this->bits = this->bits >> 1;
380 }
381 std::vector<uint64_t> pop_front(uint64_t len)
382 {
383 assert(len <= this->size());
384 std::vector<uint64_t> r;
385 for (uint64_t i = 0; i < len; i++)
386 {
387 r.push_back(this->at(0));
388 this->pop_front();
389 }
390 return r;
391 }
392 void pop_back()
393 {
394 assert(this->size() > 0);
395 this->remove(this->size() - 1);
396 }
397
398 std::vector<uint64_t> pop_back(uint64_t len)
399 {
400 assert(len <= this->size());
401 std::vector<uint64_t> r;
402 r.resize(len);
403
404 for (uint64_t i = 0; i < len; i++)
405 {
406 r[len - i - 1] = this->at(this->size() - 1);
407 this->pop_back();
408 }
409 return r;
410 }
411
412 uint64_t reverse_psum(uint64_t i) const
413 {
414 if (i == this->size() - 1)
415 {
416 return this->psum();
417 }
418 else
419 {
420 uint64_t len1 = i + 1;
421 uint64_t idx = this->size() - len1;
422 return this->psum() - this->psum(idx - 1);
423 }
424 }
425
426 uint64_t psum(uint64_t i, uint64_t j) const
427 {
428 if (i == j)
429 {
430 return this->at(i);
431 }
432 else
433 {
434 throw std::runtime_error("No implementation");
435 }
436 }
437
438 void increment(uint64_t i, int64_t delta)
439 {
440 if (delta >= 1)
441 {
442 this->bits = stool::LSBByte::write_bit(this->bits, i, true);
443 }
444 else if (delta <= -1)
445 {
446 this->bits = stool::LSBByte::write_bit(this->bits, i, false);
447 }
448 }
449
450 BitContainerIterator begin() const
451 {
452 if (this->size() == 0)
453 {
454 return BitContainerIterator(this->bits, UINT16_MAX);
455 }
456 else
457 {
458 return BitContainerIterator(this->bits, 0);
459 }
460 }
461
462 BitContainerIterator end() const
463 {
464 return BitContainerIterator(this->bits, UINT16_MAX);
465 }
466
467 int64_t rank1(uint64_t i) const
468 {
469 if (i == 0)
470 {
471 return 0;
472 }
473 else
474 {
475 return this->psum(i - 1);
476 }
477 }
478
479 int64_t rank0(uint64_t i) const
480 {
481 return i - this->rank1(i);
482 }
483 int64_t rank(uint64_t i, bool b) const
484 {
485 return b ? this->rank1(i) : this->rank0(i);
486 }
487
488 int64_t select(uint64_t i, bool b) const
489 {
490 return b ? this->select1(i) : this->select0(i);
491 }
492
493 int64_t select1(uint64_t i) const
494 {
495 return this->search(i + 1);
496 }
497 int64_t select0(uint64_t i) const
498 {
499 return stool::LSBByte::select0(this->bits, i);
500 }
501
502 void to_data(std::vector<uint8_t> &output) const
503 {
504 output.push_back(this->bits);
505 }
506 /*
507 void load_from_data(std::vector<uint64_t> &output){
508
509 }
510 */
511
512 static uint64_t get_byte_size(const std::vector<BitContainer> &items)
513 {
514 return sizeof(uint64_t) + (items.size() * sizeof(BitContainer));
515 }
516 static void save(const std::vector<BitContainer> &items, std::vector<uint8_t> &output, uint64_t &pos)
517 {
518 uint64_t size = get_byte_size(items);
519 if (pos + size > output.size())
520 {
521 output.resize(pos + size);
522 }
523
524 uint64_t items_size = items.size();
525 std::memcpy(output.data() + pos, &items_size, sizeof(uint64_t));
526 pos += sizeof(uint64_t);
527
528 std::memcpy(output.data() + pos, items.data(), items_size * sizeof(BitContainer));
529 pos += size * sizeof(BitContainer);
530 }
531 static void save(const std::vector<BitContainer> &items, std::ofstream &os)
532 {
533 uint64_t items_size = items.size();
534 os.write(reinterpret_cast<const char *>(&items_size), sizeof(uint64_t));
535 os.write(reinterpret_cast<const char *>(items.data()), items.size() * sizeof(BitContainer));
536 }
537
538 static std::vector<BitContainer> load_vector(const std::vector<uint8_t> &data, uint64_t &pos)
539 {
540 uint64_t size = 0;
541 std::memcpy(&size, data.data() + pos, sizeof(uint64_t));
542 pos += sizeof(uint64_t);
543
544 std::vector<BitContainer> output;
545 output.resize(size);
546 std::memcpy(output.data(), data.data() + pos, size * sizeof(BitContainer));
547 pos += size * sizeof(BitContainer);
548 return output;
549 }
550 static std::vector<BitContainer> load_vector(std::ifstream &ifs)
551 {
552 uint64_t size = 0;
553 ifs.read(reinterpret_cast<char *>(&size), sizeof(uint64_t));
554
555 std::vector<BitContainer> output;
556 output.resize(size);
557
558 ifs.read(reinterpret_cast<char *>(output.data()), size * sizeof(BitContainer));
559
560 return output;
561 }
562 void sort_leaf_containers()
563 {
564 }
565 };
566 }
567
568}
An implementation of B+-tree.
Definition bp_tree.hpp:24
uint64_t size() const
Return the number of values stored in this tree.
Definition bp_tree.hpp:316
bool operator<=(const BitContainerIterator &other) const
Less than or equal comparison.
Definition bit_container.hpp:195
bool operator>=(const BitContainerIterator &other) const
Greater than or equal comparison.
Definition bit_container.hpp:200
bool operator>(const BitContainerIterator &other) const
Greater than comparison.
Definition bit_container.hpp:190
bool operator==(const BitContainerIterator &other) const
Equality comparison.
Definition bit_container.hpp:175
bool operator!=(const BitContainerIterator &other) const
Inequality comparison.
Definition bit_container.hpp:180
bool operator<(const BitContainerIterator &other) const
Less than comparison.
Definition bit_container.hpp:185
A container that stores a short sequence of bits.
Definition bit_container.hpp:12