Sux
FenwickFixedL.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 FenwickFixedL : 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  FenwickFixedL() : Levels(0), Size(0) {}
54 
63  FenwickFixedL(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  for (size_t j = 0; j < l; j++) {
71  sequence_idx >>= 1;
72  value += Tree[j][sequence_idx];
73  }
74 
75  Tree[l][node >> (l + 1)] = value;
76  }
77  }
78  }
79 
80  virtual uint64_t prefix(size_t idx) {
81  uint64_t sum = 0;
82 
83  while (idx != 0) {
84  const int height = rho(idx);
85  size_t level_idx = idx >> (1 + height);
86  sum += Tree[height][level_idx];
87 
88  idx = clear_rho(idx);
89  }
90 
91  return sum;
92  }
93 
94  virtual void add(size_t idx, int64_t inc) {
95  while (idx <= Size) {
96  const int height = rho(idx);
97  size_t level_idx = idx >> (1 + height);
98  Tree[height][level_idx] += inc;
99 
100  idx += mask_rho(idx);
101  }
102  }
103 
105  virtual size_t find(uint64_t *val) {
106  size_t node = 0, idx = 0;
107 
108  for (size_t height = Levels - 1; height != SIZE_MAX; height--) {
109  size_t pos = idx;
110 
111  idx <<= 1;
112 
113  if (pos >= Tree[height].size()) continue;
114 
115  uint64_t value = Tree[height][pos];
116  if (*val >= value) {
117  idx++;
118  *val -= value;
119  node += 1ULL << height;
120  }
121  }
122 
123  return min(node, Size);
124  }
125 
127  virtual size_t compFind(uint64_t *val) {
128  size_t node = 0, idx = 0;
129 
130  for (size_t height = Levels - 1; height != SIZE_MAX; height--) {
131  size_t pos = idx;
132 
133  idx <<= 1;
134 
135  if (pos >= Tree[height].size()) continue;
136 
137  uint64_t value = (BOUND << height) - Tree[height][pos];
138  if (*val >= value) {
139  idx++;
140  *val -= value;
141  node += 1ULL << height;
142  }
143  }
144 
145  return min(node, Size);
146  }
147 
148  virtual void push(uint64_t val) {
149  Levels = lambda(++Size) + 1;
150 
151  int height = rho(Size);
152  size_t level_idx = Size >> (1 + height);
153  Tree[height].resize(level_idx + 1);
154 
155  Tree[height][level_idx] = val;
156 
157  size_t idx = level_idx << 1;
158  for (size_t h = height - 1; h != SIZE_MAX; h--) {
159  Tree[height][level_idx] += Tree[h][idx];
160  idx = (idx << 1) + 1;
161  }
162  }
163 
164  virtual void pop() {
165  int height = rho(Size--);
166  Tree[height].popBack();
167  }
168 
169  virtual void grow(size_t space) {
170  size_t levels = lambda(space) + 1;
171  for (size_t i = 0; i < levels; i++) Tree[i].grow((space + (1ULL << i)) / (1ULL << (i + 1)));
172  }
173 
174  virtual void reserve(size_t space) {
175  size_t levels = lambda(space) + 1;
176  for (size_t i = 0; i < levels; i++) Tree[i].reserve((space + (1ULL << i)) / (1ULL << (i + 1)));
177  }
178 
179  using Expandable::trimToFit;
180  virtual void trim(size_t space) {
181  size_t levels = lambda(space) + 1;
182  for (size_t i = 0; i < levels; i++) Tree[i].trim((space + (1ULL << i)) / (1ULL << (i + 1)));
183  }
184 
185  virtual void resize(size_t space) {
186  size_t levels = lambda(space) + 1;
187  for (size_t i = 0; i < levels; i++) Tree[i].resize((space + (1ULL << i)) / (1ULL << (i + 1)));
188  }
189 
190  virtual void size(size_t space) {
191  size_t levels = lambda(space) + 1;
192  for (size_t i = 0; i < levels; i++) Tree[i].size((space + (1ULL << i)) / (1ULL << (i + 1)));
193  }
194 
195  virtual size_t size() const { return Size; }
196 
197  virtual size_t bitCount() const {
198  size_t ret = sizeof(*this) * 8;
199  for (size_t i = 0; i < 64; i++) ret += Tree[i].bitCount() - sizeof(Tree[i]) * 8;
200  return ret;
201  }
202 
203  private:
204  friend std::ostream &operator<<(std::ostream &os, const FenwickFixedL<BOUND, AT> &ft) {
205  os.write((char *)&ft.Size, sizeof(uint64_t));
206  os.write((char *)&ft.Levels, sizeof(uint64_t));
207  for (size_t i = 0; i < 64; i++) os << ft.Tree[i];
208  return os;
209  }
210 
211  friend std::istream &operator>>(std::istream &is, FenwickFixedL<BOUND, AT> &ft) {
212  is.read((char *)&ft.Size, sizeof(uint64_t));
213  is.read((char *)&ft.Levels, sizeof(uint64_t));
214  for (size_t i = 0; i < ft.Levels; i++) is >> ft.Tree[i];
215  return is;
216  }
217 };
218 
219 } // namespace sux::util
sux::util::FenwickFixedL::push
virtual void push(uint64_t val)
Definition: FenwickFixedL.hpp:148
sux::util::FenwickFixedL::add
virtual void add(size_t idx, int64_t inc)
Definition: FenwickFixedL.hpp:94
sux::rho
int rho(uint64_t word)
Definition: common.hpp:168
sux::util
Definition: Expandable.hpp:37
Vector.hpp
sux::util::FenwickFixedL::find
virtual size_t find(uint64_t *val)
Definition: FenwickFixedL.hpp:105
sux::util::Expandable::trimToFit
void trimToFit()
Definition: Expandable.hpp:93
sux::util::Expandable
Definition: Expandable.hpp:43
sux::util::FenwickFixedL::compFind
virtual size_t compFind(uint64_t *val)
Definition: FenwickFixedL.hpp:127
sux::util::SearchablePrefixSums::find
virtual size_t find(uint64_t *val)=0
sux::util::FenwickFixedL::bitCount
virtual size_t bitCount() const
Definition: FenwickFixedL.hpp:197
sux::util::FenwickFixedL::prefix
virtual uint64_t prefix(size_t idx)
Definition: FenwickFixedL.hpp:80
sux::util::FenwickFixedL::resize
virtual void resize(size_t space)
Definition: FenwickFixedL.hpp:185
sux::util::FenwickFixedL::BOUNDSIZE
static constexpr size_t BOUNDSIZE
Definition: FenwickFixedL.hpp:44
sux::util::FenwickFixedL::trim
virtual void trim(size_t space)
Definition: FenwickFixedL.hpp:180
SearchablePrefixSums.hpp
sux::ceil_log2_plus1
constexpr size_t ceil_log2_plus1(size_t n)
Definition: common.hpp:100
sux::util::FenwickFixedL::Levels
size_t Levels
Definition: FenwickFixedL.hpp:49
sux::util::FenwickFixedL::size
virtual void size(size_t space)
Definition: FenwickFixedL.hpp:190
sux::util::FenwickFixedL
Definition: FenwickFixedL.hpp:42
sux::clear_rho
uint64_t clear_rho(uint64_t word)
Definition: common.hpp:194
sux::util::FenwickFixedL::Size
size_t Size
Definition: FenwickFixedL.hpp:49
sux::lambda
int lambda(uint64_t word)
Definition: common.hpp:178
sux::util::FenwickFixedL::FenwickFixedL
FenwickFixedL(uint64_t sequence[], size_t size)
Definition: FenwickFixedL.hpp:63
sux::util::SearchablePrefixSums
Definition: SearchablePrefixSums.hpp:53
sux::util::FenwickFixedL::FenwickFixedL
FenwickFixedL()
Definition: FenwickFixedL.hpp:53
sux::util::FenwickFixedL::grow
virtual void grow(size_t space)
Definition: FenwickFixedL.hpp:169
sux::util::FenwickFixedL::Tree
Vector< uint64_t, AT > Tree[64]
Definition: FenwickFixedL.hpp:45
sux::util::Vector::resize
void resize(size_t size)
Definition: Vector.hpp:166
sux::util::FenwickFixedL::operator<<
friend std::ostream & operator<<(std::ostream &os, const FenwickFixedL< BOUND, AT > &ft)
Definition: FenwickFixedL.hpp:204
sux::util::FenwickFixedL::pop
virtual void pop()
Definition: FenwickFixedL.hpp:164
sux::mask_rho
uint64_t mask_rho(uint64_t word)
Definition: common.hpp:208
sux::util::Vector< uint64_t, AT >
sux::util::FenwickFixedL::operator>>
friend std::istream & operator>>(std::istream &is, FenwickFixedL< BOUND, AT > &ft)
Definition: FenwickFixedL.hpp:211
sux::util::Vector::popBack
T popBack()
Definition: Vector.hpp:200
sux::util::FenwickFixedL::reserve
virtual void reserve(size_t space)
Definition: FenwickFixedL.hpp:174
sux::util::SearchablePrefixSums::compFind
virtual size_t compFind(uint64_t *val)=0
sux::util::FenwickFixedL::size
virtual size_t size() const
Definition: FenwickFixedL.hpp:195