tudocomp
– The TU Dortmund Compression Framework
BitPackingVectorSlice.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <cstring>
7 #include <fstream>
8 #include <iomanip>
9 #include <iostream>
10 #include <iterator>
11 #include <memory>
12 #include <sstream>
13 #include <string>
14 #include <type_traits>
15 #include <utility>
16 #include <climits>
17 
18 #include <tudocomp/ds/IntPtr.hpp>
19 #include <tudocomp/ds/uint_t.hpp>
22 
23 #include <sdsl/bits.hpp>
24 #include <glog/logging.h>
25 
27 
29 
30 namespace tdc {
31 namespace int_vector {
32  template<class T>
33  struct BitPackingVectorSliceBase {};
34 
35  template<>
36  struct BitPackingVectorSliceBase<dynamic_t> {
37  typedef DynamicIntValueType internal_data_type;
38  typedef dynamic_t value_type;
39 
40  ConstGenericView<internal_data_type> m_vec;
41  uint64_t m_real_size;
42  uint8_t m_width;
43  uint8_t m_offset;
44 
45  inline BitPackingVectorSliceBase():
46  m_vec(), m_real_size(0), m_width(64), m_offset(0) {}
47  inline BitPackingVectorSliceBase(const BitPackingVectorSliceBase& other):
48  m_vec(other.m_vec), m_real_size(other.m_real_size), m_width(other.m_width), m_offset(other.m_offset) {}
49 
50  inline uint8_t raw_width() const { return m_width; }
51  inline void set_width_raw(uint8_t width) { m_width = width; }
52 
53  };
54 
55  template<class T>
56  struct BitPackingVectorSlice: BitPackingVectorSliceBase<T> {
57  typedef typename BitPackingVectorSliceBase<T>::value_type value_type;
58 
59  typedef ConstIntRef<value_type> const_reference;
60 
61  typedef ConstIntPtr<value_type> const_pointer;
62 
63  typedef const_pointer const_iterator;
64 
65  typedef typename std::reverse_iterator<const_iterator> const_reverse_iterator;
66 
67  typedef ptrdiff_t difference_type;
68  typedef size_t size_type;
69 
70  typedef typename BitPackingVectorSliceBase<T>::internal_data_type internal_data_type;
71 
72  template<class M>
73  friend bool operator==(const BitPackingVectorSlice<M>& lhs, const BitPackingVectorSlice<M>& rhs);
74 
75  inline static uint64_t backing2bits_w(size_t n) {
76  return uint64_t(sizeof(internal_data_type) * CHAR_BIT) * uint64_t(n);
77  }
78  inline uint64_t backing2bits(size_t n) const {
79  return backing2bits_w(n);
80  }
81 
82  inline static uint64_t elem2bits_w(size_t n, uint8_t w) {
83  return uint64_t(w) * uint64_t(n);
84  }
85  inline uint64_t elem2bits(size_t n) const {
86  return elem2bits_w(n, this->width());
87  }
88 
89  inline static uint64_t bits2backing_w(uint64_t bits) {
90  if (bits == 0) {
91  return 0;
92  }
93  return ((bits - 1) / backing2bits_w(1)) + 1;
94  }
95  inline uint64_t bits2backing(uint64_t bits) const {
96  return bits2backing_w(bits);
97  }
98 
99  inline static uint64_t bits2elem_w(uint64_t bits, uint8_t w) {
100  if (bits == 0) {
101  return 0;
102  }
103  return ((bits - 1) / elem2bits_w(1, w)) + 1;
104  }
105  inline uint64_t bits2elem(uint64_t bits) const {
106  return bits2elem_w(bits, this->width());
107  }
108 
109  struct PosAndOffset { size_t pos; uint8_t offset; };
110  inline static PosAndOffset bitpos2backingpos_w(uint64_t bits) {
111  return PosAndOffset {
112  bits / backing2bits_w(1),
113  uint8_t(bits % backing2bits_w(1))
114  };
115  }
116  inline PosAndOffset bitpos2backingpos(uint64_t bits) const {
117  return bitpos2backingpos_w(bits);
118  }
119 
120  inline explicit BitPackingVectorSlice(): BitPackingVectorSliceBase<T>::BitPackingVectorSliceBase() {}
121 
122  inline BitPackingVectorSlice(ConstGenericView<internal_data_type> raw, size_type n, uint8_t width, uint8_t offset):
123  BitPackingVectorSlice()
124  {
125  this->m_vec = raw;
126  this->m_real_size = n;
127  this->m_offset = offset;
128  this->set_width_raw(width);
129  }
130 
131  inline BitPackingVectorSlice(const IntVector<dynamic_t>& vec):
132  BitPackingVectorSlice(ConstGenericView<internal_data_type>(vec.data(), bits2backing_w(elem2bits_w(vec.size(), vec.width()))), vec.size(), vec.width(), 0)
133  {}
134 
135  inline BitPackingVectorSlice (const BitPackingVectorSlice& other):
136  BitPackingVectorSliceBase<T>(other) {}
137 
138  inline BitPackingVectorSlice& operator=(const BitPackingVectorSlice& other) {
139  this->m_vec = other.m_vec;
140  this->m_real_size = other.m_real_size;
141  this->m_offset = other.m_offset;
142  this->set_width_raw(other.width());
143  return *this;
144  }
145 
146  inline const_iterator begin() const {
147  using Base = typename int_vector::IntPtrBase<const_pointer>;
148  auto x = bitpos2backingpos(this->m_offset);
149  return const_pointer(Base(this->m_vec.data() + x.pos, x.offset, this->width()));
150  }
151 
152  inline const_iterator end() const {
153  using Base = typename int_vector::IntPtrBase<const_pointer>;
154  auto x = bitpos2backingpos(this->m_offset + elem2bits(this->m_real_size));
155  return const_pointer(Base(this->m_vec.data() + x.pos, x.offset, this->width()));
156  }
157 
158  inline const_reverse_iterator rbegin() const {
159  return std::reverse_iterator<const_iterator>(end());
160  }
161 
162  inline const_reverse_iterator rend() const {
163  return std::reverse_iterator<const_iterator>(begin());
164  }
165 
166  inline const_iterator cbegin() const {
167  return begin();
168  }
169 
170  inline const_iterator cend() const {
171  return end();
172  }
173 
174  inline const_reverse_iterator crbegin() const {
175  return rbegin();
176  }
177 
178  inline const_reverse_iterator crend() const {
179  return rend();
180  }
181 
182  inline size_type size() const {
183  return this->m_real_size;
184  }
185 
186  inline uint64_t bit_size() const {
187  return elem2bits(this->m_real_size);
188  }
189 
190  inline size_type max_size() const {
191  // Empty vector does not allocate, so this is fine
192  return size();
193  }
194 
195  inline bool empty() const {
196  return size() == 0;
197  }
198 
199  inline const_reference operator[](size_type n) const {
200  using Base = typename int_vector::IntPtrBase<const_pointer>;
201  DCHECK(n < size());
202  auto x = bitpos2backingpos(this->m_offset + elem2bits(n));
203  return const_reference(const_pointer(Base(this->m_vec.data() + x.pos, x.offset, this->width())));
204  }
205 
206  inline void range_check(size_type n) const {
207  if (n >= size()) {
208  std::stringstream ss;
209  ss << "Out-of-range access of IntVector: index is ";
210  ss << n;
211  ss << ", size() is ";
212  ss << size();
213  throw std::out_of_range(ss.str());
214  }
215  }
216 
217  inline const_reference at(size_type n) const {
218  range_check(n);
219  return operator[](n);
220  }
221 
222  inline const_reference front() const {
223  return operator[](0);
224  }
225 
226  inline const_reference back() const {
227  return operator[](size() - 1);
228  }
229 
230  inline uint8_t width() const {
231  return this->raw_width();
232  }
233 
234  inline BitPackingVectorSlice slice(size_t from, size_t to = size_t(-1)) const {
235  if (to == size_t(-1)) {
236  to = size();
237  }
238 
239  auto from_bits = bitpos2backingpos(this->m_offset + elem2bits(from));
240  auto to_bits = bitpos2backingpos(this->m_offset + elem2bits(to));
241 
242  auto from_idx = from_bits.pos;
243  auto to_idx = to_bits.pos;
244  if (to_bits.offset != 0) {
245  to_idx += 1;
246  }
247 
248  auto raw = this->m_vec.slice(from_idx, to_idx);
249 
250  return BitPackingVectorSlice(raw, to - from, width(), from_bits.offset);
251  }
252  };
253 
254  template<class N>
255  bool operator==(const BitPackingVectorSlice<N>& lhs, const BitPackingVectorSlice<N>& rhs) {
256  DCHECK(lhs.width() == rhs.width());
257  if (lhs.size() == rhs.size()) {
258  return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin());
259  }
260  return false;
261  }
262 
263  template<class N>
264  bool operator!=(const BitPackingVectorSlice<N>& lhs, const BitPackingVectorSlice<N>& rhs) {
265  return !(lhs == rhs);
266  }
267 
268  template<class N>
269  bool operator<(const BitPackingVectorSlice<N>& lhs, const BitPackingVectorSlice<N>& rhs) {
270  return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
271  }
272 
273  template<class N>
274  bool operator<=(const BitPackingVectorSlice<N>& lhs, const BitPackingVectorSlice<N>& rhs) {
275  return !(lhs > rhs);
276  }
277 
278  template<class N>
279  bool operator>(const BitPackingVectorSlice<N>& lhs, const BitPackingVectorSlice<N>& rhs) {
280  return std::lexicographical_compare(rhs.cbegin(), rhs.cend(), lhs.cbegin(), lhs.cend());
281  }
282 
283  template<class N>
284  bool operator>=(const BitPackingVectorSlice<N>& lhs, const BitPackingVectorSlice<N>& rhs) {
285  return !(lhs < rhs);
286  }
287 }
288 
289 template<class T>
290 using BitPackingVectorSlice = int_vector::BitPackingVectorSlice<T>;
291 
292 }
293 
295 
Contains the text compression and encoding framework.
Definition: namespaces.hpp:11
uint_impl_t & operator=(const uint_impl_t &b)
Definition: uint_t.hpp:43
bool operator>(const IntVector< T > &lhs, const IntVector< T > &rhs)
Definition: IntVector.hpp:522
bool operator==(const IntVector< T > &lhs, const IntVector< T > &rhs)
Definition: IntVector.hpp:502
len_compact_t pos
Definition: LZSSFactors.hpp:38
bool operator>=(const IntVector< T > &lhs, const IntVector< T > &rhs)
Definition: IntVector.hpp:527
bool operator!=(const IntVector< T > &lhs, const IntVector< T > &rhs)
Definition: IntVector.hpp:507