31 #include "../support/common.hpp"
32 #include "../util/Vector.hpp"
55 template <util::AllocType AT = util::AllocType::MALLOC>
class Rank9 :
public Rank {
77 Rank9(
const uint64_t *
const bits,
const uint64_t num_bits) : num_bits(num_bits), bits(bits) {
78 const uint64_t num_words = (num_bits + 63) / 64;
79 const uint64_t num_counts = ((num_bits + 64 * 8 - 1) / (64 * 8)) * 2;
82 counts.
size(num_counts + 2);
86 for (uint64_t i = 0; i < num_words; i += 8, pos += 2) {
87 counts[pos] = num_ones;
88 num_ones += __builtin_popcountll(bits[i]);
89 for (
int j = 1; j < 8; j++) {
90 counts[pos + 1] |= (num_ones - counts[pos]) << 9 * (j - 1);
91 if (i + j < num_words) num_ones += __builtin_popcountll(bits[i + j]);
95 counts[num_counts] = num_ones;
97 assert(num_ones <= num_bits);
100 uint64_t
rank(
const size_t k) {
101 const uint64_t word = k / 64;
102 const uint64_t block = word / 4 & ~1;
103 const int offset = word % 8 - 1;
104 return counts[block] + (counts[block + 1] >> (offset + (offset >> (
sizeof offset * 8 - 4) & 0x8)) * 9 & 0x1FF) + __builtin_popcountll(bits[word] & ((1ULL << k % 64) - 1));
108 size_t bitCount()
const {
return counts.
bitCount() -
sizeof(counts) * 8 +
sizeof(*
this) * 8; }
111 size_t size()
const {
return num_bits; }