EWAHBoolArray 0.8.0
A compressed bitmap class in C++
Loading...
Searching...
No Matches
runninglengthword.h
1// See LICENSE file for license information.
2#ifndef RUNNINGLENGTHWORD_H_
3#define RUNNINGLENGTHWORD_H_
4
5#include <iostream>
6
7namespace ewah {
8
15template <class uword> class RunningLengthWord {
16public:
17 RunningLengthWord(uword &data) : mydata(data) {}
18
19 RunningLengthWord(const RunningLengthWord &rlw) : mydata(rlw.mydata) {}
20
21 RunningLengthWord &operator=(const RunningLengthWord &rlw) {
22 mydata = rlw.mydata;
23 return *this;
24 }
25
29 bool getRunningBit() const { return mydata & static_cast<uword>(1); }
30
34 static inline bool getRunningBit(uword data) {
35 return data & static_cast<uword>(1);
36 }
37
41 uword getRunningLength() const {
42 return static_cast<uword>((mydata >> 1) & largestrunninglengthcount);
43 }
44
48 static inline uword getRunningLength(uword data) {
49 return static_cast<uword>((data >> 1) & largestrunninglengthcount);
50 }
51
56 return static_cast<uword>(mydata >> (1 + runninglengthbits));
57 }
58
62 uword size() const {
63 return static_cast<uword>(getRunningLength() + getNumberOfLiteralWords());
64 }
65
69 static inline uword size(uword data) {
70 return static_cast<uword>(getRunningLength(data) +
72 }
73
77 static inline uword getNumberOfLiteralWords(uword data) {
78 return static_cast<uword>(data >> (1 + runninglengthbits));
79 }
80
84 void setRunningBit(bool b) {
85 if (b)
86 mydata |= static_cast<uword>(1);
87 else
88 mydata &= static_cast<uword>(~1);
89 }
90
91 void discardFirstWords(uword x) {
92 const uword rl(getRunningLength());
93 if (rl >= x) {
94 setRunningLength(rl - x);
95 return;
96 }
97 x -= rl;
98 setRunningLength(0);
99 setNumberOfLiteralWords(getNumberOfLiteralWords() - x);
100 }
101
105 static inline void setRunningBit(uword &data, bool b) {
106 if (b)
107 data |= static_cast<uword>(1);
108 else
109 data &= static_cast<uword>(~1);
110 }
111
112 void setRunningLength(uword l) {
113 mydata |= shiftedlargestrunninglengthcount;
114 mydata &=
115 static_cast<uword>((l << 1) | notshiftedlargestrunninglengthcount);
116 }
117
118 // static call for people who hate objects
119 static inline void setRunningLength(uword &data, uword l) {
120 data |= shiftedlargestrunninglengthcount;
121 data &= static_cast<uword>((l << 1) | notshiftedlargestrunninglengthcount);
122 }
123
124 void setNumberOfLiteralWords(uword l) {
125 mydata |= notrunninglengthplusrunningbit;
126 mydata &= static_cast<uword>((l << (runninglengthbits + 1)) |
127 runninglengthplusrunningbit);
128 }
129 // static call for people who hate objects
130 static inline void setNumberOfLiteralWords(uword &data, uword l) {
131 data |= notrunninglengthplusrunningbit;
132 data &= static_cast<uword>(l << (runninglengthbits + 1)) |
133 runninglengthplusrunningbit;
134 }
135
136 static const uint32_t runninglengthbits = sizeof(uword) * 4;
137 static const uint32_t literalbits = sizeof(uword) * 8 - 1 - runninglengthbits;
138 static const uword largestliteralcount =
139 (static_cast<uword>(1) << literalbits) - 1;
140 static const uword largestrunninglengthcount =
141 (static_cast<uword>(1) << runninglengthbits) - 1;
142 static const uword shiftedlargestrunninglengthcount =
143 largestrunninglengthcount << 1;
144 static const uword notshiftedlargestrunninglengthcount =
145 static_cast<uword>(~shiftedlargestrunninglengthcount);
146 static const uword runninglengthplusrunningbit =
147 (static_cast<uword>(1) << (runninglengthbits + 1)) - 1;
148 static const uword notrunninglengthplusrunningbit =
149 static_cast<uword>(~runninglengthplusrunningbit);
150 static const uword notlargestrunninglengthcount =
151 static_cast<uword>(~largestrunninglengthcount);
152
153 uword &mydata;
154};
155
159template <class uword = uint32_t> class ConstRunningLengthWord {
160public:
161 ConstRunningLengthWord() : mydata(0) {}
162
163 ConstRunningLengthWord(const uword data) : mydata(data) {}
164
166 : mydata(rlw.mydata) {}
167
171 bool getRunningBit() const { return mydata & static_cast<uword>(1); }
172
176 uword getRunningLength() const {
177 return static_cast<uword>(
179 }
180
185 return static_cast<uword>(
187 }
188
192 uword size() const { return getRunningLength() + getNumberOfLiteralWords(); }
193
194 uword mydata;
195};
196
197template <class uword> class EWAHBoolArray;
198
199template <class uword> class EWAHBoolArrayRawIterator;
200
205template <class uword = uint32_t> class BufferedRunningLengthWord {
206public:
207 enum { wordinbits = sizeof(uword) * 8 };
208
209 BufferedRunningLengthWord(const uword &data,
211 : RunningBit(data & static_cast<uword>(1)),
212 RunningLength(static_cast<uword>(
214 NumberOfLiteralWords(static_cast<uword>(
216 parent(p) {}
218 : RunningBit(p.mydata & static_cast<uword>(1)),
219 RunningLength((p.mydata >> 1) &
221 NumberOfLiteralWords(p.mydata >>
223 parent(p.parent) {}
224
225 void discharge(EWAHBoolArray<uword> &container) {
226 while (size() > 0) {
227 // first run
228 size_t pl = getRunningLength();
230 size_t pd = getNumberOfLiteralWords();
231 writeLiteralWords(pd, container);
232 if (!next())
233 break;
234 }
235 }
236
237 size_t dischargeCount() {
238 size_t answer = 0;
239 while (size() > 0) {
240 // first run
241 if (getRunningBit()) {
242 answer += wordinbits * getRunningLength();
243 }
244 size_t pd = getNumberOfLiteralWords();
245 for (size_t i = 0; i < pd; ++i)
246 answer += countOnes((uword)getLiteralWordAt(i));
247 if (!next())
248 break;
249 }
250 return answer;
251 }
252
253 size_t dischargeCountNegated() {
254 size_t answer = 0;
255 while (size() > 0) {
256 // first run
257 if (!getRunningBit()) {
258 answer += wordinbits * getRunningLength();
259 }
260 size_t pd = getNumberOfLiteralWords();
261 for (size_t i = 0; i < pd; ++i)
262 answer += countOnes((uword)(~getLiteralWordAt(i)));
263 if (!next())
264 break;
265 }
266 return answer;
267 }
268
269 // Symbolically write out up to max words, returns how many were written,
270 // write to count the number bits written (we assume that count was initially
271 // zero)
272 size_t dischargeCount(size_t max, size_t *count) {
273 size_t index = 0;
274 while (true) {
275 if (index + RunningLength > max) {
276 const size_t offset = max - index;
277 if (getRunningBit())
278 *count += offset * wordinbits;
279 RunningLength -= offset;
280 return max;
281 }
282 if (getRunningBit())
283 *count += RunningLength * wordinbits;
284 index += RunningLength;
285 if (NumberOfLiteralWords + index > max) {
286 const size_t offset = max - index;
287 for (size_t i = 0; i < offset; ++i)
288 *count += countOnes((uword)getLiteralWordAt(i));
289 RunningLength = 0;
290 NumberOfLiteralWords -= offset;
291 return max;
292 }
293 for (size_t i = 0; i < NumberOfLiteralWords; ++i)
294 *count += countOnes((uword)getLiteralWordAt(i));
295 index += NumberOfLiteralWords;
296 if (!next())
297 break;
298 }
299 return index;
300 }
301
302 size_t dischargeCountNegated(size_t max, size_t *count) {
303 size_t index = 0;
304 while (true) {
305 if (index + RunningLength > max) {
306 const size_t offset = max - index;
307 if (!getRunningBit())
308 *count += offset * wordinbits;
309 RunningLength -= offset;
310 return max;
311 }
312 if (!getRunningBit())
313 *count += RunningLength * wordinbits;
314 index += RunningLength;
315 if (NumberOfLiteralWords + index > max) {
316 const size_t offset = max - index;
317 for (size_t i = 0; i < offset; ++i)
318 *count += countOnes((uword)(~getLiteralWordAt(i)));
319 RunningLength = 0;
320 NumberOfLiteralWords -= offset;
321 return max;
322 }
323 for (size_t i = 0; i < NumberOfLiteralWords; ++i)
324 *count += countOnes((uword)(~getLiteralWordAt(i)));
325 index += NumberOfLiteralWords;
326 if (!next())
327 break;
328 }
329 return index;
330 }
331 bool nonzero_discharge() {
332 while (size() > 0) {
333 // first run
334 size_t pl = getRunningLength();
335 if ((pl > 0) && (getRunningBit()))
336 return true;
337 size_t pd = getNumberOfLiteralWords();
338 if (pd > 0)
339 return true;
340 discardFirstWordsWithReload(static_cast<uword>(pl + pd));
341 }
342 return false;
343 }
344
345 // Write out up to max words, returns how many were written
346 size_t discharge(EWAHBoolArray<uword> &container, size_t max) {
347 size_t index = 0;
348 while (true) {
349 if (index + RunningLength > max) {
350 const size_t offset = max - index;
351 container.fastaddStreamOfEmptyWords(getRunningBit(), offset);
352 RunningLength = static_cast<uword>(RunningLength - offset);
353 return max;
354 }
355 container.fastaddStreamOfEmptyWords(getRunningBit(), RunningLength);
356 index += RunningLength;
357 if (NumberOfLiteralWords + index > max) {
358 const size_t offset = max - index;
359 writeLiteralWords(offset, container);
360 RunningLength = 0;
361 NumberOfLiteralWords =
362 static_cast<uword>(NumberOfLiteralWords - offset);
363 return max;
364 }
365 writeLiteralWords(NumberOfLiteralWords, container);
366 index += NumberOfLiteralWords;
367 if (!next())
368 break;
369 }
370 return index;
371 }
372
373 bool nonzero_discharge(size_t max, size_t &index) {
374 index = 0;
375 while ((index < max) && (size() > 0)) {
376 // first run
377 size_t pl = getRunningLength();
378 if (index + pl > max) {
379 pl = max - index;
380 }
381 if ((getRunningBit()) && (pl > 0))
382 return true;
383 index += pl;
384 size_t pd = getNumberOfLiteralWords();
385 if (pd + index > max) {
386 pd = max - index;
387 }
388 if (pd > 0)
389 return true;
390 discardFirstWordsWithReload(static_cast<uword>(pl + pd));
391 }
392 return false;
393 }
394
395 // Write out up to max words, returns how many were written
396 size_t dischargeNegated(EWAHBoolArray<uword> &container, size_t max) {
397 // todo: could be optimized further
398 size_t index = 0;
399 while ((index < max) && (size() > 0)) {
400 // first run
401 size_t pl = getRunningLength();
402 if (index + pl > max) {
403 pl = max - index;
404 }
406 index += pl;
407 size_t pd = getNumberOfLiteralWords();
408 if (pd + index > max) {
409 pd = max - index;
410 }
411 writeNegatedLiteralWords(pd, container);
412 discardFirstWordsWithReload(static_cast<uword>(pl + pd));
413 index += pd;
414 }
415 return index;
416 }
417 bool nonzero_dischargeNegated(size_t max, size_t &index) {
418 while ((index < max) && (size() > 0)) {
419 // first run
420 size_t pl = getRunningLength();
421 if (index + pl > max) {
422 pl = max - index;
423 }
424 if ((!getRunningBit()) && (pl > 0))
425 return true;
426 index += pl;
427 size_t pd = getNumberOfLiteralWords();
428 if (pd + index > max) {
429 pd = max - index;
430 }
431 if (pd > 0)
432 return true;
433 discardFirstWordsWithReload(static_cast<uword>(pl + pd));
434 index += pd;
435 }
436 return false;
437 }
438
439 uword getLiteralWordAt(size_t index) { return parent->dirtyWords()[index]; }
440
441 void writeLiteralWords(size_t numWords, EWAHBoolArray<uword> &container) {
442 container.fastaddStreamOfDirtyWords(parent->dirtyWords(), numWords);
443 }
444
445 void writeNegatedLiteralWords(size_t numWords,
446 EWAHBoolArray<uword> &container) {
447 container.addStreamOfNegatedDirtyWords(parent->dirtyWords(), numWords);
448 }
449
450 void discardRunningWords() { RunningLength = 0; }
451
452 void discardRunningWordsWithReload() {
453 RunningLength = 0;
454 if (NumberOfLiteralWords == 0)
455 next();
456 }
457
458 bool next() {
459 if (!parent->hasNext()) {
460 NumberOfLiteralWords = 0;
461 RunningLength = 0;
462 return false;
463 }
464 parent->next();
465 return true;
466 }
467
468 void read(const uword &data) {
469 RunningBit = data & static_cast<uword>(1);
470 RunningLength = static_cast<uword>(
472 NumberOfLiteralWords = static_cast<uword>(
474 }
475
479 bool getRunningBit() const { return RunningBit; }
480
481 void discardFirstWords(uword x) {
482 if (RunningLength >= x) {
483 RunningLength = static_cast<uword>(RunningLength - x);
484 return;
485 }
486 x = static_cast<uword>(x - RunningLength);
487 RunningLength = 0;
488 NumberOfLiteralWords = static_cast<uword>(NumberOfLiteralWords - x);
489 }
490
494 uword getRunningLength() const { return RunningLength; }
495
499 uword getNumberOfLiteralWords() const { return NumberOfLiteralWords; }
500
504 uword size() const {
505 return static_cast<uword>(RunningLength + NumberOfLiteralWords);
506 }
507
508 friend std::ostream &operator<<(std::ostream &out,
509 const BufferedRunningLengthWord &a) {
510 out << "{RunningBit:" << a.RunningBit
511 << ",RunningLength:" << a.RunningLength
512 << ",NumberOfLiteralWords:" << a.NumberOfLiteralWords << "}";
513 return out;
514 }
515 void discardLiteralWordsWithReload(uword x) {
516 assert(NumberOfLiteralWords >= x);
517 NumberOfLiteralWords -= x;
518 if (NumberOfLiteralWords == 0)
519 next();
520 }
521
522 void discardFirstWordsWithReload(uword x) {
523 while (x > 0) {
524 if (RunningLength > x) {
525 RunningLength = static_cast<uword>(RunningLength - x);
526 return;
527 }
528 x = static_cast<uword>(x - RunningLength);
529 RunningLength = 0;
530 size_t toDiscard = x > NumberOfLiteralWords ? NumberOfLiteralWords : x;
531 NumberOfLiteralWords =
532 static_cast<uword>(NumberOfLiteralWords - toDiscard);
533 x = static_cast<uword>(x - toDiscard);
534 if ((x > 0) || (size() == 0)) {
535 if (!next())
536 break;
537 }
538 }
539 }
540
541private:
542 bool RunningBit;
543 uword RunningLength;
544 uword NumberOfLiteralWords;
545 EWAHBoolArrayRawIterator<uword> *parent;
546};
547} // namespace ewah
548
549#endif /* RUNNINGLENGTHWORD_H_ */
Same as RunningLengthWord, except that the values are buffered for quick access.
uword getRunningLength() const
how many words should be filled by the running bit (see previous method)
uword getNumberOfLiteralWords() const
followed by how many literal words?
uword size() const
Total of getRunningLength() and getNumberOfLiteralWords()
bool getRunningBit() const
Which bit is being repeated?
Same as RunningLengthWord, except that the values cannot be modified.
bool getRunningBit() const
Which bit is being repeated?
uword getRunningLength() const
how many words should be filled by the running bit
uword size() const
Total of getRunningLength() and getNumberOfLiteralWords()
uword getNumberOfLiteralWords() const
followed by how many literal words?
This class is a compressed bitmap.
void fastaddStreamOfDirtyWords(const uword *v, const size_t number)
LikeaddStreamOfDirtyWords but does not return the cost increse, does not update sizeinbits.
Definition ewah-inl.h:1036
size_t addStreamOfNegatedDirtyWords(const uword *v, const size_t number)
add a stream of dirty words, each one negated, returns the number of words added (storage cost increa...
Definition ewah-inl.h:1069
void fastaddStreamOfEmptyWords(const bool v, size_t number)
Like addStreamOfEmptyWords but addStreamOfEmptyWords but does not return the cost increase,...
Definition ewah-inl.h:953
This is a low-level iterator.
uword getNumberOfLiteralWords() const
followed by how many literal words?
uword size() const
Total of getRunningLength() and getNumberOfLiteralWords()
void setRunningBit(bool b)
running length of which type of bits
static uword getNumberOfLiteralWords(uword data)
followed by how many literal words?
static bool getRunningBit(uword data)
how many words should be filled by the running bit
static void setRunningBit(uword &data, bool b)
running length of which type of bits
bool getRunningBit() const
Which bit is being repeated?
static uword size(uword data)
Total of getRunningLength() and getNumberOfLiteralWords()
static uword getRunningLength(uword data)
followed by how many literal words?
uword getRunningLength() const
how many words should be filled by the running bit