34#ifndef INCLUDED_SDSL_HYB_VECTOR
35#define INCLUDED_SDSL_HYB_VECTOR
57template <u
int8_t t_b = 1, u
int32_t k_sb_rate = 16>
58class rank_support_hyb;
59template <u
int8_t t_b = 1, u
int32_t k_sb_rate = 16>
60class select_support_hyb;
71template <u
int32_t k_sblock_rate = 16>
90 static const uint32_t k_block_size;
91 static const uint32_t k_block_bytes;
92 static const uint32_t k_sblock_header_size;
93 static const uint32_t k_sblock_size;
94 static const uint32_t k_hblock_rate;
115 size_type n_blocks = (m_size + k_block_size - 1) / k_block_size;
116 size_type n_sblocks = (n_blocks + k_sblock_rate - 1) / k_sblock_rate;
117 size_type n_hblocks = (n_blocks + k_hblock_rate - 1) / k_hblock_rate;
124 for (uint32_t i = 1; i < 65536; ++i)
126 runs_lookup[i] = runs_lookup[i >> 1];
129 if ((i & 1) != ((i >> 1) & 1))
134 uint64_t
const * bv_ptr = bv.
data();
135 for (
size_type block_id = 0; block_id < n_blocks; ++block_id)
137 size_type block_beg = block_id * k_block_size;
138 size_type block_end = block_beg + k_block_size;
143 if (block_end <= m_size)
146 uint64_t
const * ptr64 = bv_ptr;
147 for (uint8_t i = 0; i < 4; ++i)
152 for (uint8_t i = 0; i < 4; ++i)
155 for (uint8_t j = 0; j < 4; ++j)
156 runs += runs_lookup[((*ptr64) >> (16 * j)) & 0xffff];
159 for (uint8_t j = 0; j < 3; ++j)
160 runs += ((((*ptr64) >> (16 * j + 15)) & 1) ^ (((*ptr64) >> (16 * j + 16)) & 1));
166 for (uint8_t i = 0; i < 3; ++i)
168 runs += ((((*ptr64) >> 63) & 1) ^ ((*(ptr64 + 1)) & 1));
177 for (
size_type i = block_beg; i < block_end; ++i)
179 uint8_t bit = (i < m_size ? bv[i] : 0);
189 uint32_t minority_enc_size = std::min(ones, k_block_size - ones);
190 uint32_t runs_enc_size = (uint32_t)std::max(0, (int32_t)runs - 2);
191 uint32_t best_enc_size = std::min(minority_enc_size, runs_enc_size);
192 best_enc_size = std::min(best_enc_size, k_block_bytes);
195 trunk_size += best_enc_size;
196 bv_ptr += k_block_size / 64;
200 m_sblock_header =
int_vector<8>(n_sblocks * k_sblock_header_size, 0);
211 for (
size_type block_id = 0; block_id < n_blocks; ++block_id)
213 size_type block_beg = block_id * k_block_size;
214 size_type block_end = block_beg + k_block_size;
215 size_type sblock_id = block_id / k_sblock_rate;
216 size_type hblock_id = block_id / k_hblock_rate;
219 if (!(block_id % k_hblock_rate))
221 m_hblock_header[2 * hblock_id] = trunk_ptr;
222 m_hblock_header[2 * hblock_id + 1] = tot_rank;
226 if (!(block_id % k_sblock_rate))
228 uint32_t * ptr = (uint32_t *)(((uint8_t *)m_sblock_header.
data()) + k_sblock_header_size * sblock_id);
229 *ptr++ = trunk_ptr - m_hblock_header[2 * hblock_id];
230 *ptr = tot_rank - m_hblock_header[2 * hblock_id + 1];
233 if (sblock_id && (!sblock_ones || sblock_ones == k_sblock_size))
235 ptr = (uint32_t *)(((uint8_t *)m_sblock_header.
data()) + k_sblock_header_size * (sblock_id - 1));
247 if (block_end <= m_size)
250 uint64_t
const * ptr64 = bv_ptr;
251 for (uint8_t i = 0; i < 4; ++i)
256 for (uint8_t i = 0; i < 4; ++i)
258 for (uint8_t j = 0; j < 4; ++j)
259 runs += runs_lookup[((*ptr64) >> (16 * j)) & 0xffff];
260 for (uint8_t j = 0; j < 3; ++j)
261 runs += ((((*ptr64) >> (16 * j + 15)) & 1) ^ (((*ptr64) >> (16 * j + 16)) & 1));
265 for (uint8_t i = 0; i < 3; ++i)
267 runs += ((((*ptr64) >> 63) & 1) ^ ((*(ptr64 + 1)) & 1));
276 for (
size_type i = block_beg; i < block_end; ++i)
278 uint8_t bit = (i < m_size ? bv[i] : 0);
286 uint32_t zeros = k_block_size - ones;
289 uint16_t * header_ptr16 =
290 (uint16_t *)(((uint8_t *)m_sblock_header.
data()) + sblock_id * k_sblock_header_size + 8
291 + (block_id % k_sblock_rate) * 2);
293 (*header_ptr16) = ones;
294 if (ones == k_block_size)
295 (*header_ptr16) |= 0x200;
297 if (0 < ones && ones < k_block_size)
299 uint32_t minority_enc_size = std::min(ones, zeros);
300 uint32_t runs_enc_size = (uint32_t)std::max(0, (int32_t)runs - 2);
301 uint32_t best_enc_size = std::min(minority_enc_size, runs_enc_size);
303 if (k_block_bytes <= best_enc_size)
306 (*header_ptr16) |= (k_block_bytes << 10);
309 if (block_end <= m_size)
311 for (uint8_t i = 0; i < 4; ++i)
313 *((uint64_t *)(((uint8_t *)m_trunk.
data()) + trunk_ptr)) = *(bv_ptr + i);
319 for (
size_type i = block_beg; i < block_end; i += 64)
322 for (
size_type j = i; j < std::min(i + 64, block_end); ++j)
324 uint8_t bit = (j < m_size ? bv[j] : 0);
326 w |= ((uint64_t)1 << (j - i));
328 *((uint64_t *)(((uint8_t *)m_trunk.
data()) + trunk_ptr)) = w;
335 if (runs_enc_size < minority_enc_size)
339 (*header_ptr16) |= (runs_enc_size << 10);
340 (*header_ptr16) |= (bv[block_beg] << 9);
342 if (block_end <= m_size)
346 uint64_t
const * ptr64 = bv_ptr;
349 for (uint8_t i = 0; runid < runs_enc_size && i < 4; ++i)
352 if (i > 0 && (w & 1) != ((*ptr64) & 1))
353 m_trunk[trunk_ptr + runid++] = 64 * i - 1;
356 for (uint8_t j = 0; runid < runs_enc_size && j < 63; ++j)
358 if ((w & 1) != ((w >> 1) & 1))
359 m_trunk[trunk_ptr + runid++] = j + i * 64;
371 for (
size_type i = block_beg; runid < runs_enc_size; ++i)
373 uint8_t bit = (i < m_size ? bv[i] : 0);
374 if (bit != prevbit && i != block_beg)
375 m_trunk[trunk_ptr + runid++] = (i - block_beg - 1);
385 (*header_ptr16) |= (minority_enc_size << 10);
387 (*header_ptr16) |= 0x200;
388 uint8_t keybit = (ones < zeros);
391 if (block_end <= m_size)
393 uint64_t
const * ptr64 = bv_ptr;
394 for (uint8_t i = 0; i < 4; ++i)
396 uint64_t w = (*ptr64++);
397 for (uint8_t j = 0; j < 64; ++j)
399 if ((w & 1) == keybit)
400 m_trunk[trunk_ptr++] = j + 64 * i;
407 for (
size_type i = block_beg; i < block_end; ++i)
409 uint8_t bit = (i < m_size ? bv[i] : 0);
412 m_trunk[trunk_ptr++] = i - block_beg;
422 bv_ptr += k_block_size / 64;
433 size_type block_id = (i - 1) / k_block_size;
434 size_type sblock_id = block_id / k_sblock_rate;
435 size_type hblock_id = block_id / k_hblock_rate;
437 size_type trunk_base = m_hblock_header[2 * hblock_id];
439 uint32_t local_i = i - block_id * k_block_size;
442 uint8_t
const * header_ptr8 = ((uint8_t
const *)m_sblock_header.
data()) + (sblock_id * k_sblock_header_size);
443 uint32_t * header_ptr32 = (uint32_t *)header_ptr8;
444 size_type trunk_ptr = trunk_base + ((*header_ptr32) & 0x3fffffff);
447 uint16_t * header_ptr16 = (uint16_t *)header_ptr8;
450 if ((*header_ptr32) & 0x80000000)
451 return (
value_type)((*(header_ptr8 + 1)) & 0x01);
454 for (
size_type j = sblock_id * k_sblock_rate; j != block_id; ++j)
456 trunk_ptr += ((*header_ptr16) >> 10);
460 uint8_t
const * trunk_p = ((uint8_t
const *)m_trunk.
data()) + trunk_ptr;
462 uint32_t encoding_size = ((*header_ptr16) >> 10);
463 uint32_t ones = ((*header_ptr16) & 0x1ff);
464 uint32_t zeros = k_block_size - ones;
467 uint32_t special_bit = (((*header_ptr16) & 0x200) >> 9);
470 uint32_t first_run_length = special_bit * ones + (1 - special_bit) * zeros;
471 uint8_t inside_second_run = (first_run_length < local_i);
472 return (inside_second_run ^ special_bit);
476 if (encoding_size < k_block_bytes)
478 if (std::min(ones, zeros) == encoding_size)
482 while (tot < encoding_size && *trunk_p < local_i)
487 uint8_t last_was_majority = ((!tot) || (*(trunk_p - 1) != local_i - 1));
488 return (last_was_majority ^ special_bit);
498 while (j + 1 < encoding_size && *(trunk_p + 1) < local_i)
500 acc += *trunk_p - last;
507 uint8_t access_i = 0;
508 if (j + 1 >= encoding_size)
510 if (j < encoding_size)
512 if (local_i <= (uint32_t)(*trunk_p) + 1)
513 access_i = (((int32_t)local_i - last - 1) > 0);
516 acc += (int32_t)(*trunk_p) - last;
517 if (ones - acc <= k_block_size - local_i)
525 if ((int32_t)(ones - acc) < (int32_t)local_i - last - 1)
528 access_i = (((int32_t)local_i - last - 1) > 0);
533 if ((*trunk_p) < local_i - 1)
536 access_i = (((int32_t)local_i - last - 1) > 0);
547 while (j + 1 < encoding_size && *(trunk_p + 1) < local_i)
549 acc += *trunk_p - last;
556 uint8_t access_i = 0;
557 if (j + 1 >= encoding_size)
559 if (j < encoding_size)
561 if (local_i <= (uint32_t)(*trunk_p) + 1)
562 access_i = (((int32_t)local_i - last - 1) == 0);
565 acc += (*trunk_p) - last;
566 if (zeros - acc <= k_block_size - local_i)
574 if ((int32_t)(zeros - acc) < (int32_t)local_i - last - 1)
577 access_i = ((local_i - last - 1) == 0);
582 if ((*trunk_p) < local_i - 1)
585 access_i = (((int32_t)local_i - last - 1) == 0);
594 uint64_t * trunk_ptr64 = (uint64_t *)(((uint8_t *)m_trunk.
data()) + trunk_ptr);
596 for (bit = 0; bit + 64 <= local_i; bit += 64)
599 uint8_t access_i = 0;
601 access_i = (((*trunk_ptr64) >> (local_i - bit - 1)) & 1);
603 access_i = (((*(trunk_ptr64 - 1)) >> 63) & 1);
620 for (
size_t i = 0; i < len; ++i)
623 res |= (*this)[idx + len - 1 - i];
631 return access0(i + 1);
645 written_bytes +=
write_member(m_size, out, child,
"size");
646 written_bytes += m_trunk.
serialize(out, child,
"trunk");
647 written_bytes += m_sblock_header.
serialize(out, child,
"sblock_header");
648 written_bytes += m_hblock_header.
serialize(out, child,
"hblock_header");
650 return written_bytes;
658 m_sblock_header.
load(in);
659 m_hblock_header.
load(in);
662 template <
typename archive_t>
671 template <
typename archive_t>
692 return m_size == v.m_size && m_trunk == v.m_trunk && m_sblock_header == v.m_sblock_header
693 && m_hblock_header == v.m_hblock_header;
698 return !(*
this == v);
702template <u
int32_t k_sblock_rate>
703const uint32_t hyb_vector<k_sblock_rate>::k_block_size = 256;
704template <u
int32_t k_sblock_rate>
705const uint32_t hyb_vector<k_sblock_rate>::k_block_bytes = 32;
706template <u
int32_t k_sblock_rate>
707const uint32_t hyb_vector<k_sblock_rate>::k_sblock_header_size = 8 + 2 * k_sblock_rate;
708template <u
int32_t k_sblock_rate>
709const uint32_t hyb_vector<k_sblock_rate>::k_sblock_size = 256 * k_sblock_rate;
710template <u
int32_t k_sblock_rate>
711const uint32_t hyb_vector<k_sblock_rate>::k_hblock_rate = (1U << 31) / 256;
713template <u
int8_t t_bp>
739template <u
int8_t t_b, u
int32_t k_sblock_rate>
767 assert(m_v !=
nullptr);
768 assert(i <= m_v->
size());
774 size_type block_id = (i - 1) / bit_vector_type::k_block_size;
775 size_type sblock_id = block_id / k_sblock_rate;
776 size_type hblock_id = block_id / bit_vector_type::k_hblock_rate;
778 size_type trunk_base = m_v->m_hblock_header[2 * hblock_id];
779 size_type hblock_rank = m_v->m_hblock_header[2 * hblock_id + 1];
781 uint32_t local_i = i - block_id * bit_vector_type::k_block_size;
784 uint8_t
const * header_ptr8 =
785 ((uint8_t
const *)(m_v->m_sblock_header.data())) + (sblock_id * bit_vector_type::k_sblock_header_size);
786 uint32_t * header_ptr32 = (uint32_t *)header_ptr8;
787 size_type trunk_ptr = trunk_base + ((*header_ptr32) & 0x3fffffff);
788 size_type sblock_rank = *(header_ptr32 + 1);
791 uint16_t * header_ptr16 = (uint16_t *)header_ptr8;
794 if ((*header_ptr32) & 0x80000000)
797 + ((*(header_ptr8 + 1)) & 0x01)
798 * (i - sblock_id * bit_vector_type::k_sblock_size),
804 for (
size_type j = sblock_id * k_sblock_rate; j != block_id; ++j)
806 trunk_ptr += ((*header_ptr16) >> 10);
807 block_rank += ((*header_ptr16) & 0x1ff);
811 uint8_t
const * trunk_p = ((uint8_t *)m_v->m_trunk.data()) + trunk_ptr;
813 uint32_t encoding_size = ((*header_ptr16) >> 10);
814 uint32_t ones = ((*header_ptr16) & 0x1ff);
815 uint32_t zeros = bit_vector_type::k_block_size - ones;
818 uint32_t special_bit = (((*header_ptr16) & 0x200) >> 9);
821 uint32_t first_run_length = special_bit * ones + (1 - special_bit) * zeros;
822 uint32_t local_rank = std::min(local_i, first_run_length);
825 hblock_rank + sblock_rank + block_rank
826 + (special_bit * local_rank + (1 - special_bit) * (local_i - local_rank)),
831 if (encoding_size < bit_vector_type::k_block_bytes)
833 if (std::min(ones, zeros) == encoding_size)
837 while (tot < encoding_size && (*trunk_p++) < local_i)
841 + (1 - special_bit) * (local_i - tot),
852 while (j + 1 < encoding_size && *(trunk_p + 1) < local_i)
854 acc += *trunk_p - last;
861 if (j + 1 >= encoding_size)
863 if (j < encoding_size)
865 if (*trunk_p >= local_i)
866 acc += local_i - last - 1;
869 acc += (*trunk_p) - last;
870 acc += (ones - acc) - std::min(ones - acc, bit_vector_type::k_block_size - local_i);
874 acc += std::min(ones - acc, local_i - last - 1);
877 acc += std::min((int32_t)(*trunk_p), (int32_t)local_i - 1) - last;
887 while (j + 1 < encoding_size && *(trunk_p + 1) < local_i)
889 acc += *trunk_p - last;
896 if (j + 1 >= encoding_size)
898 if (j < encoding_size)
900 if (*trunk_p >= local_i)
901 acc += local_i - last - 1;
904 acc += (*trunk_p) - last;
905 acc += (zeros - acc) - std::min(zeros - acc, bit_vector_type::k_block_size - local_i);
909 acc += std::min(zeros - acc, local_i - last - 1);
912 acc += std::min((int32_t)(*trunk_p), (int32_t)local_i - 1) - last;
920 uint64_t * trunk_ptr64 = (uint64_t *)(((uint8_t *)m_v->m_trunk.data()) + trunk_ptr);
922 for (bit = 0; bit + 64 <= local_i; bit += 64)
925 block_rank +=
bits::cnt((*trunk_ptr64) & (((uint64_t)1 << (local_i - bit)) - 1));
973 template <
typename archive_t>
977 template <
typename archive_t>
983 return *m_v == *other.m_v;
988 return !(*
this == other);
998template <u
int8_t t_b, u
int32_t k_sblock_rate>
1026 fprintf(stderr,
"\nhyb_vector: select queries are not currently supported\n");
1027 std::exit(EXIT_FAILURE);
1072 template <
typename archive_t>
1076 template <
typename archive_t>
1082 return *m_v == *other.m_v;
1087 return !(*
this == other);
bits.hpp contains the sdsl::bits class.
cereal.hpp offers cereal support
A hybrid-encoded compressed bitvector representation.
bool operator==(hyb_vector const &v) const
hyb_vector()=default
Default constructor.
select_support_hyb< 0, k_sblock_rate > select_0_type
hyb_vector & operator=(hyb_vector &&hybrid)=default
uint64_t get_int(size_type idx, const uint8_t len=64) const
Get the integer value of the binary string of length len starting at position idx.
hyb_vector & operator=(hyb_vector const &hybrid)=default
void load(std::istream &in)
Loads the data structure from the given istream.
hyb_vector(hyb_vector &&hybrid)=default
void CEREAL_LOAD_FUNCTION_NAME(archive_t &ar)
size_type serialize(std::ostream &out, structure_tree_node *v=nullptr, std::string name="") const
Serializes the data structure into the given ostream.
rank_support_hyb< 0, k_sblock_rate > rank_0_type
select_support_hyb< 1, k_sblock_rate > select_1_type
hyb_vector(hyb_vector const &hybrid)=default
hyb_vector(bit_vector const &bv)
Constructor.
random_access_const_iterator< hyb_vector > iterator
size_type size() const
Returns the size of the original bitvector.
bit_vector::difference_type difference_type
bit_vector::size_type size_type
bool operator!=(hyb_vector const &v) const
void CEREAL_SAVE_FUNCTION_NAME(archive_t &ar) const
value_type operator[](size_type i) const
Accessing the i-th element of the original bitvector.
rank_support_hyb< 1, k_sblock_rate > rank_1_type
bit_vector::value_type value_type
A generic vector class for integers of width .
uint64_t const * data() const noexcept
Pointer to the raw data of the int_vector.
int_vector_size_type size_type
ptrdiff_t difference_type
void load(std::istream &in)
Load the int_vector for a stream.
size_type size() const noexcept
The number of elements in the int_vector.
int_vector_trait< t_width >::value_type value_type
size_type serialize(std::ostream &out, structure_tree_node *v=nullptr, std::string name="") const
Serializes the int_vector to a stream.
Generic iterator for a random access container.
Rank_support for the hyb_vector class.
void CEREAL_SAVE_FUNCTION_NAME(archive_t &) const
rank_support_hyb(bit_vector_type const *v=nullptr)
Standard constructor.
const size_type size() const
Return the size of the original vector.
void set_vector(bit_vector_type const *v=nullptr)
Set the supported vector.
bool operator!=(rank_support_hyb const &other) const noexcept
void load(std::istream &, bit_vector_type const *v=nullptr)
Load the data structure from a stream and set the supported vector.
void CEREAL_LOAD_FUNCTION_NAME(archive_t &)
bool operator==(rank_support_hyb const &other) const noexcept
size_type serialize(std::ostream &, structure_tree_node *v=nullptr, std::string name="") const
Serializes the data structure into a stream.
bit_vector_type::size_type size_type
const size_type rank(size_type i) const
Answers rank queries.
rank_support_hyb & operator=(rank_support_hyb const &rs)
Assignment operator.
const size_type operator()(size_type i) const
Shorthand for rank(i)
hyb_vector< k_sblock_rate > bit_vector_type
Select support for the hyb_vector class.
select_support_hyb(bit_vector_type const *v=nullptr)
Standard constructor.
bit_vector_type::size_type size_type
void CEREAL_LOAD_FUNCTION_NAME(archive_t &)
select_support_hyb & operator=(select_support_hyb const &rs)
Assignment operator.
size_type serialize(std::ostream &, structure_tree_node *v=nullptr, std::string name="") const
Serializes the data structure into a stream.
void load(std::istream &, bit_vector_type const *v=nullptr)
Load the data structure from a stream and set the supported vector.
bool operator==(select_support_hyb const &other) const noexcept
size_type select(size_type) const
Answers select queries.
const size_type operator()(size_type i) const
Shorthand for select(i)
const size_type size() const
Return the size of the original vector.
void set_vector(bit_vector_type const *v=nullptr)
Set the supported vector.
hyb_vector< k_sblock_rate > bit_vector_type
bool operator!=(select_support_hyb const &other) const noexcept
void CEREAL_SAVE_FUNCTION_NAME(archive_t &) const
static structure_tree_node * add_child(structure_tree_node *v, std::string const &name, std::string const &type)
static void add_size(structure_tree_node *v, uint64_t value)
int_vector.hpp contains the sdsl::int_vector class.
io.hpp contains some methods for reading/writing sdsl structures.
iterators.hpp contains an generic iterator for random access containers.
Namespace for the succinct data structure library.
size_t write_member(T const &t, std::ostream &out, sdsl::structure_tree_node *v=nullptr, std::string name="")
void read_member(T &t, std::istream &in)
static constexpr uint64_t cnt(uint64_t x)
Counts the number of set bits in x.
bit_vector::size_type size_type
static size_type adapt(size_type res, size_type i)
static size_type adapt(size_type res, size_type)
bit_vector::size_type size_type
structure_tree.hpp contains a helper class which can represent the memory structure of a class.
util.hpp contains some helper methods for int_vector and other stuff like demangle class names.