tudocomp
– The TU Dortmund Compression Framework
Rank.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <tudocomp/util.hpp>
6 
7 namespace tdc {
8 
16 class Rank {
17 public:
19  static constexpr size_t block_size =
21 
22  static_assert(block_size <= 64, "block_size cannot be larger than 64 bits");
23 
24 private:
25  const BitVector* m_bv;
26 
27  size_t m_supblock_size;
28  DynamicIntVector m_blocks;
29  DynamicIntVector m_supblocks;
30 
31 public:
33  inline Rank()
34  : m_bv(nullptr),
35  m_supblock_size(0) {
36  }
37 
39  inline Rank(const Rank& other)
40  : m_bv(other.m_bv),
41  m_supblock_size(other.m_supblock_size),
42  m_blocks(other.m_blocks),
43  m_supblocks(other.m_supblocks) {
44  }
45 
47  inline Rank(Rank&& other)
48  : m_bv(other.m_bv),
49  m_supblock_size(other.m_supblock_size),
50  m_blocks(std::move(other.m_blocks)),
51  m_supblocks(std::move(other.m_supblocks)) {
52  }
53 
55  inline Rank& operator=(const Rank& other) {
56  m_bv = other.m_bv;
57  m_supblock_size = other.m_supblock_size;
58  m_blocks = other.m_blocks;
59  m_supblocks = other.m_supblocks;
60  return *this;
61  }
62 
64  inline Rank& operator=(Rank&& other) {
65  m_bv = other.m_bv;
66  m_supblock_size = other.m_supblock_size;
67  m_blocks = std::move(other.m_blocks);
68  m_supblocks = std::move(other.m_supblocks);
69  return *this;
70  }
71 
79  inline Rank(const BitVector& bv)
80  : m_bv(&bv),
81  m_supblock_size(block_size * block_size) {
82 
83  DCHECK_GT(m_supblock_size, block_size)
84  << "superblocks must be larger than blocks!";
85  DCHECK_EQ(0, m_supblock_size % block_size)
86  << "superblock size must be a multiple of the block size!";
87 
88  const size_t n = m_bv->size();
89  const auto data = m_bv->data();
90 
91  // compute number of superblocks / blocks
92  const size_t num_supblocks = idiv_ceil(n, m_supblock_size);
93  const size_t num_blocks = idiv_ceil(n, block_size);
94 
95  const size_t blocks_per_supblock = m_supblock_size / block_size;
96 
97  m_supblocks = DynamicIntVector(num_supblocks, 0, bits_for(n));
98  m_blocks = DynamicIntVector(num_blocks, 0, bits_for(m_supblock_size));
99 
100  // construct
101  size_t rank_bv = 0; // 1-bits in whole BV
102  size_t rank_sb = 0; // 1-bits in current superblock
103  size_t cur_sb = 0; // current superblock
104 
105  for(size_t j = 0; j < num_blocks; j++) {
106  size_t i = j / blocks_per_supblock;
107  if(i > cur_sb) {
108  // we reached a new superblock
109  m_supblocks[cur_sb] = rank_bv;
110  rank_sb = 0;
111  cur_sb = i;
112  }
113 
114  auto rank_b = tdc::rank1(data[j]);
115  rank_sb += rank_b;
116  rank_bv += rank_b;
117 
118  m_blocks[j] = rank_sb;
119  }
120  }
121 
126  inline size_t rank1(size_t x) const {
127  DCHECK_LT(x, m_bv->size());
128  size_t r = 0;
129  size_t i = x / m_supblock_size;
130  if(i > 0) r += m_supblocks[i-1];
131  size_t j = x / block_size;
132 
133  size_t k = j - i * (m_supblock_size / block_size);
134  if(k > 0) r += m_blocks[j-1];
135 
136  r += tdc::rank1(m_bv->data()[j], x % block_size);
137  return r;
138  }
139 
145  inline size_t rank1(size_t x, size_t y) const {
146  DCHECK_LE(x, y);
147  size_t r = rank1(y);
148  if(x > 0) r -= rank1(x-1);
149  return r;
150  }
151 
153  inline size_t operator()(size_t x) const {
154  return rank1(x);
155  }
156 
158  inline size_t operator()(size_t x, size_t y) const {
159  return rank1(x, y);
160  }
161 
166  inline size_t rank0(size_t x) const {
167  return x + 1 - rank1(x);
168  }
169 
175  inline size_t rank0(size_t x, size_t y) const {
176  return (y - x + 1) - rank1(x, y);
177  }
178 };
179 
180 }
static constexpr size_t block_size
The size of a block in bits.
Definition: Rank.hpp:19
Contains the text compression and encoding framework.
Definition: namespaces.hpp:11
constexpr uint_fast8_t bits_for(size_t n)
Computes the number of bits required to store the given integer value.
constexpr size_t idiv_ceil(size_t a, size_t b)
Performs an integer division with the result rounded up to the next integer.
size_t rank1(size_t x, size_t y) const
Counts the amount of 1-bits in the given interval (borders included) of the bit vector.
Definition: Rank.hpp:145
A vector over arbitrary unsigned integer types.
Definition: IntVector.hpp:175
Implements a rank data structure for a BitVector.
Definition: Rank.hpp:16
size_t rank0(size_t x) const
Counts the amount of 0-bits from the beginning of the bit vector up to (including) the given position...
Definition: Rank.hpp:166
size_t operator()(size_t x, size_t y) const
Definition: Rank.hpp:158
Rank(const Rank &other)
Copy constructor.
Definition: Rank.hpp:39
size_t rank0(size_t x, size_t y) const
Counts the amount of 0-bits in the given interval (borders included) of the bit vector.
Definition: Rank.hpp:175
Rank(const BitVector &bv)
Constructs the rank data structure for the given bit vector.
Definition: Rank.hpp:79
constexpr uint8_t rank1(uint8_t v)
Computes the amount of 1-bits in the binary representation of the given 8-bit value.
Definition: rank_64bit.hpp:51
size_t operator()(size_t x) const
Definition: Rank.hpp:153
IntVectorTrait< T >::internal_data_type internal_data_type
The element type of the internal data buffer accessed with data()
Definition: IntVector.hpp:191
internal_data_type * data() noexcept
Definition: IntVector.hpp:405
size_t rank1(size_t x) const
Counts the amount of 1-bits from the beginning of the bit vector up to (including) the given position...
Definition: Rank.hpp:126
Rank(Rank &&other)
Move constructor.
Definition: Rank.hpp:47
Rank & operator=(Rank &&other)
Move assignment.
Definition: Rank.hpp:64
Rank & operator=(const Rank &other)
Copy assignment.
Definition: Rank.hpp:55
IntVector< dynamic_t > DynamicIntVector
Represents an integer vector with unspecified (dynamic) bit width.
Definition: IntVector.hpp:553
size_type size() const
Definition: IntVector.hpp:284
Rank()
Default constructor.
Definition: Rank.hpp:33