31 #include "../util/Vector.hpp"
54 static constexpr
size_t BOUND = 64 * WORDS;
55 uint64_t *
const Vector;
57 SPS<BOUND, AT> SrcPrefSum;
78 virtual uint64_t
rank(
size_t pos) {
79 size_t idx = pos / (64 * WORDS);
80 uint64_t value = SrcPrefSum.prefix(idx);
82 for (
size_t i = idx * WORDS; i < pos / 64; i++) value +=
nu(Vector[i]);
84 return value +
nu(Vector[pos / 64] & ((1ULL << (pos % 64)) - 1));
89 virtual uint64_t
rank(
size_t from,
size_t to) {
return rank(to) -
rank(from); }
92 size_t idx = SrcPrefSum.find(&
rank);
94 for (
size_t i = idx * WORDS; i < idx * WORDS + WORDS; i++) {
95 uint64_t rank_chunk =
nu(Vector[i]);
96 if (
rank < rank_chunk)
106 size_t idx = SrcPrefSum.compFind(&
rank);
108 for (
size_t i = idx * WORDS; i < idx * WORDS + WORDS; i++) {
109 uint64_t rank_chunk =
nu(~Vector[i]);
110 if (
rank < rank_chunk)
119 virtual uint64_t
update(
size_t index, uint64_t word) {
120 uint64_t old = Vector[index];
121 Vector[index] = word;
122 SrcPrefSum.add(index / WORDS + 1,
nu(word) -
nu(old));
127 virtual bool set(
size_t index) {
128 uint64_t old = Vector[index / 64];
129 Vector[index / 64] |= uint64_t(1) << (index % 64);
131 if (Vector[index / 64] != old) {
132 SrcPrefSum.add(index / (WORDS * 64) + 1, 1);
140 uint64_t old = Vector[index / 64];
141 Vector[index / 64] &= ~(uint64_t(1) << (index % 64));
143 if (Vector[index / 64] != old) {
144 SrcPrefSum.add(index / (WORDS * 64) + 1, -1);
152 uint64_t old = Vector[index / 64];
153 Vector[index / 64] ^= uint64_t(1) << (index % 64);
154 bool was_set = Vector[index / 64] < old;
155 SrcPrefSum.add(index / (WORDS * 64) + 1, was_set ? -1 : 1);
160 virtual size_t size()
const {
return Size; }
162 virtual size_t bitCount()
const {
return SrcPrefSum.bitCount() -
sizeof(SrcPrefSum) * 8 +
sizeof(*
this) * 8 + ((Size + 63) & ~63); }
165 static size_t divRoundup(
size_t x,
size_t y) {
167 return (x / y) + ((x % y != 0) ? 1 : 0);
170 static SPS<BOUND, AT> buildSrcPrefSum(
const uint64_t
bitvector[],
size_t size) {
171 unique_ptr<uint64_t[]> sequence = make_unique<uint64_t[]>(divRoundup(
size, WORDS));
172 for (
size_t i = 0; i <
size; i++) sequence[i / WORDS] +=
nu(
bitvector[i]);
173 return SPS<BOUND, AT>(sequence.get(), divRoundup(
size, WORDS));
177 os.write((
char *)&bv.Size,
sizeof(uint64_t));
178 return os << bv.SrcPrefSum << bv.Vector;
182 is.read((
char *)&bv.Size,
sizeof(uint64_t));
183 return is >> bv.SrcPrefSum >> bv.Vector;