Sux
FenwickByteL.hpp
Go to the documentation of this file.
1 /*
2  * Sux: Succinct data structures
3  *
4  * Copyright (C) 2019-2020 Stefano Marchini
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 "SearchablePrefixSums.hpp"
32 #include "Vector.hpp"
33 
34 namespace sux::util {
35 
42 template <size_t BOUND, AllocType AT = MALLOC> class FenwickByteL : public SearchablePrefixSums, public Expandable {
43  public:
44  static constexpr size_t BOUNDSIZE = ceil_log2_plus1(BOUND);
45  static_assert(BOUNDSIZE >= 1 && BOUNDSIZE <= 64, "Leaves can't be stored in a 64-bit word");
46 
47  protected:
49  size_t Levels, Size;
50 
51  public:
53  FenwickByteL() : Levels(0), Size(0) {}
54 
63  FenwickByteL(uint64_t sequence[], size_t size) : Levels(size != 0 ? lambda(size) + 1 : 1), Size(size) {
64  this->size(size ? size : 1);
65 
66  for (size_t l = 0; l < Levels; l++) {
67  for (size_t node = 1ULL << l; node <= Size; node += 1ULL << (l + 1)) {
68  size_t sequence_idx = node - 1;
69  uint64_t value = sequence[sequence_idx];
70 
71  for (size_t j = 0; j < l; j++) {
72  sequence_idx >>= 1;
73  size_t lowpos = heightsize(j) * sequence_idx;
74  value += byteread(&Tree[j][lowpos], heightsize(j));
75  }
76 
77  size_t highpos = heightsize(l) * (node >> (l + 1));
78  bytewrite(&Tree[l][highpos], heightsize(l), value);
79  }
80  }
81  }
82 
83  virtual uint64_t prefix(size_t idx) {
84  uint64_t sum = 0;
85 
86  while (idx != 0) {
87  const int height = rho(idx);
88  const size_t isize = heightsize(height);
89  const size_t pos = (idx >> (1 + height)) * isize;
90 
91  sum += byteread(&Tree[height][pos], isize);
92  idx = clear_rho(idx);
93  }
94 
95  return sum;
96  }
97 
98  virtual void add(size_t idx, int64_t inc) {
99  while (idx <= Size) {
100  int height = rho(idx);
101  size_t isize = heightsize(height);
102  size_t pos = (idx >> (1 + height)) * isize;
103 
104  bytewrite_inc(&Tree[height][pos], inc);
105  idx += mask_rho(idx);
106  }
107  }
108 
110  virtual size_t find(uint64_t *val) {
111  size_t node = 0, idx = 0;
112 
113  for (size_t height = Levels - 1; height != SIZE_MAX; height--) {
114  const size_t isize = heightsize(height);
115  const size_t pos = idx * heightsize(height);
116 
117  idx <<= 1;
118 
119  if (pos >= Tree[height].size() - 8) continue;
120 
121  const uint64_t value = byteread(&Tree[height][pos], isize);
122 
123  if (*val >= value) {
124  idx++;
125  *val -= value;
126  node += 1ULL << height;
127  }
128  }
129 
130  return min(node, Size);
131  }
132 
134  virtual size_t compFind(uint64_t *val) {
135  size_t node = 0, idx = 0;
136 
137  for (size_t height = Levels - 1; height != SIZE_MAX; height--) {
138  const size_t isize = heightsize(height);
139  const size_t pos = idx * heightsize(height);
140 
141  idx <<= 1;
142 
143  if (pos >= Tree[height].size() - 8) continue;
144 
145  const uint64_t value = (BOUND << height) - byteread(&Tree[height][pos], isize);
146 
147  if (*val >= value) {
148  idx++;
149  *val -= value;
150  node += 1ULL << height;
151  }
152  }
153 
154  return min(node, Size);
155  }
156 
157  virtual void push(uint64_t val) {
158  Levels = lambda(++Size) + 1;
159 
160  int height = rho(Size);
161  size_t idx = Size >> (1 + height);
162  size_t hisize = heightsize(height);
163  size_t highpos = idx * hisize;
164 
165  Tree[height].resize(highpos + 8);
166  bytewrite(&Tree[height][highpos], hisize, val);
167 
168  idx <<= 1;
169  for (size_t h = height - 1; h != SIZE_MAX; h--) {
170  size_t losize = heightsize(h);
171  size_t lowpos = idx * losize;
172 
173  int64_t inc = byteread(&Tree[h][lowpos], losize);
174 
175  bytewrite_inc(&Tree[height][highpos], inc);
176 
177  idx = (idx << 1) + 1;
178  }
179  }
180 
181  virtual void pop() {
182  int height = rho(Size);
183  Tree[height].resize((Size >> (1 + height)) * heightsize(height) + 7);
184  Size--;
185  }
186 
187  virtual void grow(size_t space) {
188  size_t levels = lambda(space) + 1;
189  for (size_t i = 0; i < levels; i++) Tree[i].grow(((space + (1ULL << i)) / (1ULL << (i + 1))) * heightsize(i) + 8);
190  };
191 
192  virtual void reserve(size_t space) {
193  size_t levels = lambda(space) + 1;
194  for (size_t i = 0; i < levels; i++) Tree[i].reserve(((space + (1ULL << i)) / (1ULL << (i + 1))) * heightsize(i) + 8);
195  }
196 
197  using Expandable::trimToFit;
198  virtual void trim(size_t space) {
199  size_t levels = lambda(space) + 1;
200  for (size_t i = 0; i < levels; i++) Tree[i].trim(((space + (1ULL << i)) / (1ULL << (i + 1))) * heightsize(i) + 8);
201  };
202 
203  virtual void resize(size_t space) {
204  size_t levels = lambda(space) + 1;
205  for (size_t i = 0; i < levels; i++) Tree[i].resize(((space + (1ULL << i)) / (1ULL << (i + 1))) * heightsize(i) + 8);
206  }
207 
208  virtual void size(size_t space) {
209  size_t levels = lambda(space) + 1;
210  for (size_t i = 0; i < levels; i++) Tree[i].size(((space + (1ULL << i)) / (1ULL << (i + 1))) * heightsize(i) + 8);
211  }
212 
213  virtual size_t size() const { return Size; }
214 
215  virtual size_t bitCount() const {
216  size_t ret = sizeof(*this) * 8;
217  for (size_t i = 0; i < 64; i++) ret += Tree[i].bitCount() - sizeof(Tree[i]) * 8;
218  return ret;
219  }
220 
221  private:
222  static inline size_t heightsize(size_t height) { return ((height + BOUNDSIZE - 1) >> 3) + 1; }
223 
224  friend std::ostream &operator<<(std::ostream &os, const FenwickByteL<BOUND, AT> &ft) {
225  os.write((char *)&ft.Size, sizeof(uint64_t));
226  os.write((char *)&ft.Levels, sizeof(uint64_t));
227  for (size_t i = 0; i < ft.Levels; i++) os << ft.Tree[i];
228  return os;
229  }
230 
231  friend std::istream &operator>>(std::istream &is, FenwickByteL<BOUND, AT> &ft) {
232  is.read((char *)&ft.Size, sizeof(uint64_t));
233  is.read((char *)&ft.Levels, sizeof(uint64_t));
234  for (size_t i = 0; i < ft.Levels; i++) is >> ft.Tree[i];
235  return is;
236  }
237 };
238 
239 } // namespace sux::util
sux::rho
int rho(uint64_t word)
Definition: common.hpp:168
sux::util
Definition: Expandable.hpp:37
Vector.hpp
sux::util::FenwickByteL::FenwickByteL
FenwickByteL(uint64_t sequence[], size_t size)
Definition: FenwickByteL.hpp:63
sux::util::Expandable::trimToFit
void trimToFit()
Definition: Expandable.hpp:93
sux::util::FenwickByteL::size
virtual void size(size_t space)
Definition: FenwickByteL.hpp:208
sux::util::Expandable
Definition: Expandable.hpp:43
sux::util::FenwickByteL::operator<<
friend std::ostream & operator<<(std::ostream &os, const FenwickByteL< BOUND, AT > &ft)
Definition: FenwickByteL.hpp:224
sux::util::SearchablePrefixSums::find
virtual size_t find(uint64_t *val)=0
sux::bytewrite
void bytewrite(void *const word, int length, uint64_t val)
Definition: common.hpp:265
sux::util::FenwickByteL::BOUNDSIZE
static constexpr size_t BOUNDSIZE
Definition: FenwickByteL.hpp:44
sux::util::FenwickByteL::Levels
size_t Levels
Definition: FenwickByteL.hpp:49
sux::util::FenwickByteL::FenwickByteL
FenwickByteL()
Definition: FenwickByteL.hpp:53
sux::util::FenwickByteL::size
virtual size_t size() const
Definition: FenwickByteL.hpp:213
sux::util::FenwickByteL::reserve
virtual void reserve(size_t space)
Definition: FenwickByteL.hpp:192
SearchablePrefixSums.hpp
sux::ceil_log2_plus1
constexpr size_t ceil_log2_plus1(size_t n)
Definition: common.hpp:100
sux::util::FenwickByteL::find
virtual size_t find(uint64_t *val)
Definition: FenwickByteL.hpp:110
sux::util::FenwickByteL::bitCount
virtual size_t bitCount() const
Definition: FenwickByteL.hpp:215
sux::util::FenwickByteL::prefix
virtual uint64_t prefix(size_t idx)
Definition: FenwickByteL.hpp:83
sux::util::FenwickByteL::push
virtual void push(uint64_t val)
Definition: FenwickByteL.hpp:157
sux::clear_rho
uint64_t clear_rho(uint64_t word)
Definition: common.hpp:194
sux::lambda
int lambda(uint64_t word)
Definition: common.hpp:178
sux::util::SearchablePrefixSums
Definition: SearchablePrefixSums.hpp:53
sux::util::FenwickByteL::pop
virtual void pop()
Definition: FenwickByteL.hpp:181
sux::util::FenwickByteL::compFind
virtual size_t compFind(uint64_t *val)
Definition: FenwickByteL.hpp:134
sux::util::Vector::resize
void resize(size_t size)
Definition: Vector.hpp:166
sux::util::FenwickByteL
Definition: FenwickByteL.hpp:42
sux::util::FenwickByteL::grow
virtual void grow(size_t space)
Definition: FenwickByteL.hpp:187
sux::util::FenwickByteL::trim
virtual void trim(size_t space)
Definition: FenwickByteL.hpp:198
sux::mask_rho
uint64_t mask_rho(uint64_t word)
Definition: common.hpp:208
sux::util::FenwickByteL::add
virtual void add(size_t idx, int64_t inc)
Definition: FenwickByteL.hpp:98
sux::bytewrite_inc
void bytewrite_inc(void *const word, uint64_t inc)
Definition: common.hpp:273
sux::util::FenwickByteL::operator>>
friend std::istream & operator>>(std::istream &is, FenwickByteL< BOUND, AT > &ft)
Definition: FenwickByteL.hpp:231
sux::util::Vector< uint8_t, AT >
sux::util::FenwickByteL::resize
virtual void resize(size_t space)
Definition: FenwickByteL.hpp:203
sux::util::SearchablePrefixSums::compFind
virtual size_t compFind(uint64_t *val)=0
sux::util::FenwickByteL::Size
size_t Size
Definition: FenwickByteL.hpp:49
sux::byteread
uint64_t byteread(const void *const word, int length)
Definition: common.hpp:259
sux::util::FenwickByteL::Tree
Vector< uint8_t, AT > Tree[64]
Definition: FenwickByteL.hpp:45