Sux
WordDynRankSel.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 "../util/Vector.hpp"
32 #include "DynamicBitVector.hpp"
33 #include "Rank.hpp"
34 #include "Select.hpp"
35 #include "SelectZero.hpp"
36 
37 namespace sux::bits {
38 
56 template <template <size_t, util::AllocType AT> class SPS, util::AllocType AT = util::AllocType::MALLOC> class WordDynRankSel : public DynamicBitVector, public Rank, public Select, public SelectZero {
57  private:
58  static constexpr size_t BOUND = 64;
59  uint64_t *const Vector;
60  size_t Size;
61  SPS<BOUND, AT> SrcPrefSum;
62 
63  public:
78  WordDynRankSel(uint64_t bitvector[], size_t size) : Vector(bitvector), Size(size), SrcPrefSum(buildSrcPrefSum(bitvector, divRoundup(size, BOUND))) {}
79 
80  uint64_t *bitvector() const { return Vector; }
81 
82  using Rank::rank;
83  using Rank::rankZero;
84  virtual uint64_t rank(size_t pos) { return SrcPrefSum.prefix(pos / 64) + nu(Vector[pos / 64] & ((1ULL << (pos % 64)) - 1)); }
85 
86  virtual size_t select(uint64_t rank) {
87  size_t idx = SrcPrefSum.find(&rank);
88  uint64_t rank_chunk = nu(Vector[idx]);
89  if (rank < rank_chunk) return idx * 64 + select64(Vector[idx], rank);
90 
91  return SIZE_MAX;
92  }
93 
94  virtual size_t selectZero(uint64_t rank) {
95  const size_t idx = SrcPrefSum.compFind(&rank);
96 
97  uint64_t rank_chunk = nu(~Vector[idx]);
98  if (rank < rank_chunk) return idx * 64 + select64(~Vector[idx], rank);
99 
100  return SIZE_MAX;
101  }
102 
103  virtual uint64_t update(size_t index, uint64_t word) {
104  uint64_t old = Vector[index];
105  Vector[index] = word;
106  SrcPrefSum.add(index + 1, nu(word) - nu(old));
107 
108  return old;
109  }
110 
111  virtual bool set(size_t index) {
112  uint64_t old = Vector[index / 64];
113  Vector[index / 64] |= uint64_t(1) << (index % 64);
114 
115  if (Vector[index / 64] != old) {
116  SrcPrefSum.add(index / 64 + 1, 1);
117  return false;
118  }
119 
120  return true;
121  }
122 
123  virtual bool clear(size_t index) {
124  uint64_t old = Vector[index / 64];
125  Vector[index / 64] &= ~(uint64_t(1) << (index % 64));
126 
127  if (Vector[index / 64] != old) {
128  SrcPrefSum.add(index / 64 + 1, -1);
129  return true;
130  }
131 
132  return false;
133  }
134 
135  virtual bool toggle(size_t index) {
136  uint64_t old = Vector[index / 64];
137  Vector[index / 64] ^= uint64_t(1) << (index % 64);
138  bool was_set = Vector[index / 64] < old;
139  SrcPrefSum.add(index / 64 + 1, was_set ? -1 : 1);
140 
141  return was_set;
142  }
143 
144  virtual size_t size() const { return Size; }
145 
146  virtual size_t bitCount() const { return SrcPrefSum.bitCount() - sizeof(SrcPrefSum) * 8 + sizeof(*this) * 8 + ((Size + 63) & ~63); }
147 
148  private:
149  static size_t divRoundup(size_t x, size_t y) { return (x + y - 1) / y; }
150 
151  SPS<BOUND, AT> buildSrcPrefSum(const uint64_t bitvector[], size_t size) {
152  unique_ptr<uint64_t[]> sequence = make_unique<uint64_t[]>(size);
153  for (size_t i = 0; i < size; i++) sequence[i] = nu(bitvector[i]);
154  return SPS<BOUND, AT>(sequence.get(), size);
155  }
156 
157  friend std::ostream &operator<<(std::ostream &os, const WordDynRankSel<SPS, AT> &bv) {
158  os.write((char *)&bv.Size, sizeof(uint64_t));
159  return os << bv.SrcPrefSum << bv.Vector;
160  }
161 
162  friend std::istream &operator>>(std::istream &is, WordDynRankSel<SPS, AT> &bv) {
163  is.read((char *)&bv.Size, sizeof(uint64_t));
164  return is >> bv.SrcPrefSum >> bv.Vector;
165  }
166 };
167 
168 } // namespace sux::bits
sux::Rank
Definition: Rank.hpp:46
sux::util::AllocType
AllocType
Definition: Vector.hpp:45
sux::bits::WordDynRankSel::clear
virtual bool clear(size_t index)
Definition: WordDynRankSel.hpp:123
sux::bits::WordDynRankSel::WordDynRankSel
WordDynRankSel(uint64_t bitvector[], size_t size)
Definition: WordDynRankSel.hpp:78
sux::bits::WordDynRankSel
Definition: WordDynRankSel.hpp:56
sux::bits::WordDynRankSel::select
virtual size_t select(uint64_t rank)
Definition: WordDynRankSel.hpp:86
Rank.hpp
sux::util::MALLOC
Definition: Vector.hpp:47
sux::bits::WordDynRankSel::rank
virtual uint64_t rank(size_t pos)
Definition: WordDynRankSel.hpp:84
sux::bits::WordDynRankSel::set
virtual bool set(size_t index)
Definition: WordDynRankSel.hpp:111
sux::bits::DynamicBitVector
Definition: DynamicBitVector.hpp:41
sux::Select
Definition: Select.hpp:38
sux::bits::WordDynRankSel::toggle
virtual bool toggle(size_t index)
Definition: WordDynRankSel.hpp:135
sux::bits
Definition: DynamicBitVector.hpp:31
sux::bits::WordDynRankSel::selectZero
virtual size_t selectZero(uint64_t rank)
Definition: WordDynRankSel.hpp:94
Select.hpp
DynamicBitVector.hpp
sux::SelectZero
Definition: SelectZero.hpp:42
sux::bits::WordDynRankSel::operator>>
friend std::istream & operator>>(std::istream &is, WordDynRankSel< SPS, AT > &bv)
Definition: WordDynRankSel.hpp:162
sux::Rank::rank
virtual uint64_t rank(std::size_t pos)=0
sux::nu
int nu(uint64_t word)
Definition: common.hpp:339
sux::bits::WordDynRankSel::update
virtual uint64_t update(size_t index, uint64_t word)
Definition: WordDynRankSel.hpp:103
SelectZero.hpp
sux::bits::WordDynRankSel::bitvector
uint64_t * bitvector() const
Definition: WordDynRankSel.hpp:80
sux::bits::WordDynRankSel::operator<<
friend std::ostream & operator<<(std::ostream &os, const WordDynRankSel< SPS, AT > &bv)
Definition: WordDynRankSel.hpp:157
sux::Rank::rankZero
virtual uint64_t rankZero(std::size_t pos)
Definition: Rank.hpp:70
sux::bits::WordDynRankSel::bitCount
virtual size_t bitCount() const
Definition: WordDynRankSel.hpp:146
sux::bits::WordDynRankSel::size
virtual size_t size() const
Definition: WordDynRankSel.hpp:144
sux::select64
uint64_t select64(uint64_t x, uint64_t k)
Definition: common.hpp:372