Sux
Rank9.hpp
Go to the documentation of this file.
1 /*
2  * Sux: Succinct data structures
3  *
4  * Copyright (C) 2007-2020 Sebastiano Vigna
5  *
6  * This library is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by the Free
8  * Software Foundation; either version 3 of the License, or (at your option)
9  * any later version.
10  *
11  * This library is free software; you can redistribute it and/or modify it under
12  * the terms of the GNU General Public License as published by the Free Software
13  * Foundation; either version 3, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
16  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
17  * PARTICULAR PURPOSE. See the GNU General Public License for more details.
18  *
19  * Under Section 7 of GPL version 3, you are granted additional permissions
20  * described in the GCC Runtime Library Exception, version 3.1, as published by
21  * the Free Software Foundation.
22  *
23  * You should have received a copy of the GNU General Public License and a copy of
24  * the GCC Runtime Library Exception along with this program; see the files
25  * COPYING3 and COPYING.RUNTIME respectively. If not, see
26  * <http://www.gnu.org/licenses/>.
27  */
28 
29 #pragma once
30 
31 #include "../support/common.hpp"
32 #include "../util/Vector.hpp"
33 #include "Rank.hpp"
34 
35 #include <cstdint>
36 
37 namespace sux::bits {
38 
39 using namespace sux;
40 
55 template <util::AllocType AT = util::AllocType::MALLOC> class Rank9 : public Rank {
56  protected:
57  const size_t num_bits;
58  size_t num_ones;
59  const uint64_t *bits;
61 
62  public:
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;
80 
81  // Init rank structure
82  counts.size(num_counts + 2);
83 
84  num_ones = 0;
85  uint64_t pos = 0;
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]);
92  }
93  }
94 
95  counts[num_counts] = num_ones;
96 
97  assert(num_ones <= num_bits);
98  }
99 
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));
105  }
106 
108  size_t bitCount() const { return counts.bitCount() - sizeof(counts) * 8 + sizeof(*this) * 8; }
109 
111  size_t size() const { return num_bits; }
112 };
113 
114 } // namespace sux::bits
sux::bits::Rank9::num_bits
const size_t num_bits
Definition: Rank9.hpp:57
sux::Rank
Definition: Rank.hpp:46
sux::bits::Rank9::Rank9
Rank9(const uint64_t *const bits, const uint64_t num_bits)
Definition: Rank9.hpp:77
sux::bits::Rank9
Definition: Rank9.hpp:55
Rank.hpp
sux::util::Vector::size
void size(size_t size)
Definition: Vector.hpp:178
sux
Definition: DynamicBitVector.hpp:31
sux::bits::Rank9::bitCount
size_t bitCount() const
Definition: Rank9.hpp:108
sux::bits::Rank9::bits
const uint64_t * bits
Definition: Rank9.hpp:59
sux::bits
Definition: DynamicBitVector.hpp:31
sux::util::Vector::bitCount
size_t bitCount() const
Definition: Vector.hpp:231
sux::bits::Rank9::counts
util::Vector< uint64_t, AT > counts
Definition: Rank9.hpp:60
sux::bits::Rank9::num_ones
size_t num_ones
Definition: Rank9.hpp:58
sux::bits::Rank9::rank
uint64_t rank(const size_t k)
Definition: Rank9.hpp:100
sux::bits::Rank9::size
size_t size() const
Definition: Rank9.hpp:111
sux::util::Vector< uint64_t, AT >