41#include "pasta/bit_vector/bit_vector.hpp"
42#include "pasta/bit_vector/support/l12_type.hpp"
49#include <pasta/utils/container/aligned_vector.hpp>
50#include <pasta/utils/debug_asserts.hpp>
51#include <tlx/container/simple_vector.hpp>
67 static_cast<uint32_t
>(std::numeric_limits<int32_t>::max()) + 1;
107 VectorType::RawDataConstAccess
data_;
112 tlx::SimpleVector<uint64_t, tlx::SimpleVectorMode::NoInitNoDestroy>
l0_;
115 tlx::SimpleVector<L12Type, tlx::SimpleVectorMode::NoInitNoDestroy>
l12_;
129 data_(bv.data().data()),
156 [[nodiscard(
"rank0 computed but not used")]]
inline size_t
158 PASTA_ASSERT(index <=
bit_size_,
"Index outside of bit vector");
159 return index -
rank1(index);
167 [[nodiscard(
"rank1 computed but not used")]]
inline size_t
169 PASTA_ASSERT(index <=
bit_size_,
"Index outside of bit vector");
177 auto l2 =
l12_[l1_pos].l2_values;
178 for (
size_t i = 0; i < l2_pos; ++i) {
179 result += (l2 & uint16_t(0b1111111111));
195 "Trying to access bits that should be "
196 "covered in an L1-block");
197 for (
size_t i = 0; i < index / 64; ++i) {
198 result += std::popcount(
data_[offset++]);
200 if (index %= 64; index > 0) [[likely]] {
201 uint64_t
const remaining =
data_[offset] << (64 - index);
202 result += std::popcount(remaining);
211 [[nodiscard(
"space usage computed but not used")]]
virtual size_t
213 return l0_.size() *
sizeof(uint64_t) +
l12_.size() *
sizeof(
L12Type) +
225 uint32_t l1_entry = 0UL;
227 uint64_t
const* data =
data_;
231 std::array<uint16_t, 3> l2_entries = {0, 0, 0};
232 while (data + 32 <= data_end) {
233 uint32_t new_l1_entry = l1_entry;
234 for (
size_t i = 0; i < 3; ++i) {
236 l2_entries[i] = popcount<8>(data);
238 l2_entries[i] = popcount_zeros<8>(data);
241 new_l1_entry += l2_entries[i];
243 l12_[l12_pos++] = L12Type(l1_entry, l2_entries);
245 new_l1_entry += popcount<8>(data);
247 new_l1_entry += popcount_zeros<8>(data);
250 l1_entry = new_l1_entry;
255 l0_[l0_pos] = (
l0_[l0_pos - 1] + l1_entry);
261 l2_entries = {0, 0, 0};
263 while (data + 8 < data_end) {
265 l2_entries[l2_pos++] = popcount<8>(data);
267 l2_entries[l2_pos++] = popcount_zeros<8>(data);
272 while (data < data_end) {
274 l2_entries[l2_pos] += popcount<1>(data++);
276 l2_entries[l2_pos] += popcount_zeros<1>(data++);
280 l12_[l12_pos] = L12Type(l1_entry, l2_entries);
284 l0_[l0_pos] += (
l0_[l0_pos - 1] + l1_entry);
290 l0_[l0_pos] = std::numeric_limits<uint64_t>::max();
Uncompressed, highly tuned, fixed size bit vector.
Definition bit_vector.hpp:178
Rank support for BitVector.
Definition rank.hpp:102
tlx::SimpleVector< uint64_t, tlx::SimpleVectorMode::NoInitNoDestroy > l0_
Array containing the number of set bits in the L0-blocks.
Definition rank.hpp:112
VectorType::RawDataConstAccess data_
Pointer to the data of the bit vector.
Definition rank.hpp:107
Rank(Rank &&other)=default
Default move constructor.
size_t rank1(size_t index) const
Computes rank of ones.
Definition rank.hpp:168
virtual size_t space_usage() const
Estimate for the space usage.
Definition rank.hpp:212
Rank & operator=(Rank &&other)=default
Default move assignment.
~Rank()=default
Destructor. Deleting manually created arrays.
size_t const bit_size_
Size of the bit vector in bits (only used for debug asserts)
Definition rank.hpp:109
Rank()=default
Default constructor w/o parameter.
Rank(VectorType &bv)
Constructor. Creates the auxiliary information for efficient rank queries.
Definition rank.hpp:127
size_t data_size_
Size of the bit vector the rank support is constructed for.
Definition rank.hpp:105
tlx::SimpleVector< L12Type, tlx::SimpleVectorMode::NoInitNoDestroy > l12_
Array containing the information about the L1- and L2-blocks.
Definition rank.hpp:115
size_t rank0(size_t index) const
Computes rank of zeros.
Definition rank.hpp:157
OptimizedFor
Enum used to specify which queries the rank (and select) data structures should be optimized for.
Definition optimized_for.hpp:40
constexpr bool optimize_one_or_dont_care(OptimizedFor const optimized_for)
Helper function indicating if queries should be optimized for one queries or the caller does not care...
Definition optimized_for.hpp:59
@ DONT_CARE
It does not matter (both types are called equally often).
Struct used to store L1- and L2-blocks for BitVectorRank and BitVectorSelect.
Definition l12_type.hpp:37
Static configuration for Rank and RankSelect.
Definition rank.hpp:60
static constexpr size_t L0_WORD_SIZE
Number of 64-bit words covered by an L0-block.
Definition rank.hpp:74
static constexpr size_t SELECT_SAMPLE_RATE
Sample rate of positions for faster select queries.
Definition rank.hpp:77
static constexpr size_t L2_WORD_SIZE
Number of 64-bit words covered by an L2-block.
Definition rank.hpp:70
static constexpr size_t L2_BIT_SIZE
Bits covered by an L2-block.
Definition rank.hpp:62
static constexpr size_t L0_BIT_SIZE
Bits covered by an L0-block.
Definition rank.hpp:66
static constexpr size_t L1_BIT_SIZE
Bits covered by an L1-block.
Definition rank.hpp:64
static constexpr size_t L1_WORD_SIZE
Number of 64-bit words covered by an L1-block.
Definition rank.hpp:72