EWAHBoolArray 0.8.0
A compressed bitmap class in C++
Loading...
Searching...
No Matches
boolarray.h
1// See LICENSE file for license information.
2#ifndef BOOLARRAY_H
3#define BOOLARRAY_H
4
5#include <cassert>
6#include <iostream>
7#include <iso646.h> // mostly for Microsoft compilers
8#include <sstream>
9#include <stdarg.h>
10#include <stdexcept>
11#include <vector>
12
13#include "ewahutil.h"
14
15namespace ewah {
19template <class uword = uint32_t> class BoolArray {
20public:
21 BoolArray(const size_t n, const uword initval = 0)
22 : buffer(n / wordinbits + (n % wordinbits == 0 ? 0 : 1), initval),
23 sizeinbits(n) {}
24
25 BoolArray() : buffer(), sizeinbits(0) {}
26
27 BoolArray(const BoolArray &ba)
28 : buffer(ba.buffer), sizeinbits(ba.sizeinbits) {}
29 static BoolArray bitmapOf(size_t n, ...) {
30 BoolArray ans;
31 va_list vl;
32 va_start(vl, n);
33 for (size_t i = 0; i < n; i++) {
34 ans.set(static_cast<size_t>(va_arg(vl, int)));
35 }
36 va_end(vl);
37 return ans;
38 }
39 size_t sizeInBytes() const { return buffer.size() * sizeof(uword); }
40
41 void read(std::istream &in) {
42 sizeinbits = 0;
43 in.read(reinterpret_cast<char *>(&sizeinbits), sizeof(sizeinbits));
44 buffer.resize(sizeinbits / wordinbits +
45 (sizeinbits % wordinbits == 0 ? 0 : 1));
46 if (buffer.size() == 0)
47 return;
48 in.read(reinterpret_cast<char *>(&buffer[0]),
49 static_cast<std::streamsize>(buffer.size() * sizeof(uword)));
50 }
51
52 void readBuffer(std::istream &in, const size_t size) {
53 buffer.resize(size);
54 sizeinbits = size * sizeof(uword) * 8;
55 if (buffer.empty())
56 return;
57 in.read(reinterpret_cast<char *>(&buffer[0]),
58 buffer.size() * sizeof(uword));
59 }
60
61 void setSizeInBits(const size_t sizeib) { sizeinbits = sizeib; }
62
63 void write(std::ostream &out) { write(out, sizeinbits); }
64
65 void write(std::ostream &out, const size_t numberofbits) const {
66 const size_t size =
67 numberofbits / wordinbits + (numberofbits % wordinbits == 0 ? 0 : 1);
68 out.write(reinterpret_cast<const char *>(&numberofbits),
69 sizeof(numberofbits));
70 if (numberofbits == 0)
71 return;
72 out.write(reinterpret_cast<const char *>(&buffer[0]),
73 static_cast<std::streamsize>(size * sizeof(uword)));
74 }
75
76 void writeBuffer(std::ostream &out, const size_t numberofbits) const {
77 const size_t size =
78 numberofbits / wordinbits + (numberofbits % wordinbits == 0 ? 0 : 1);
79 if (size == 0)
80 return;
81#ifdef EWAHASSERT
82 assert(buffer.size() >= size);
83#endif
84 out.write(reinterpret_cast<const char *>(&buffer[0]), size * sizeof(uword));
85 }
86
87 size_t sizeOnDisk() const {
88 size_t size =
89 sizeinbits / wordinbits + (sizeinbits % wordinbits == 0 ? 0 : 1);
90 return sizeof(sizeinbits) + size * sizeof(uword);
91 }
92
93 BoolArray &operator=(const BoolArray &x) {
94 this->buffer = x.buffer;
95 this->sizeinbits = x.sizeinbits;
96 return *this;
97 }
98
99 bool operator==(const BoolArray &x) const {
100 if (sizeinbits != x.sizeinbits)
101 return false;
102 for (size_t k = 0; k < buffer.size(); ++k)
103 if (buffer[k] != x.buffer[k])
104 return false;
105 return true;
106 }
107
108 bool operator!=(const BoolArray &x) const { return !operator==(x); }
109
110 void setWord(const size_t pos, const uword val) {
111#ifdef EWAHASSERT
112 assert(pos < buffer.size());
113#endif
114 buffer[pos] = val;
115 }
116
117 void addWord(const uword val) {
118 if (sizeinbits % wordinbits != 0)
119 throw std::invalid_argument("you probably didn't want to do this");
120 sizeinbits += wordinbits;
121 buffer.push_back(val);
122 }
123
124 uword getWord(const size_t pos) const {
125#ifdef EWAHASSERT
126 assert(pos < buffer.size());
127#endif
128 return buffer[pos];
129 }
130
134 void set(const size_t pos) {
135 if (pos >= sizeinbits)
136 padWithZeroes(pos + 1);
137 buffer[pos / wordinbits] |=
138 static_cast<uword>((static_cast<uword>(1) << (pos % wordinbits)));
139 }
140
145 void unset(const size_t pos) {
146 if (pos < sizeinbits)
147 buffer[pos / wordinbits] &=
148 ~(static_cast<uword>(1) << (pos % wordinbits));
149 }
150
154 bool get(const size_t pos) const {
155#ifdef EWAHASSERT
156 assert(pos / wordinbits < buffer.size());
157#endif
158 return (buffer[pos / wordinbits] &
159 (static_cast<uword>(1) << (pos % wordinbits))) != 0;
160 }
161
165 void reset() {
166 if (buffer.size() > 0)
167 memset(&buffer[0], 0, sizeof(uword) * buffer.size());
168 sizeinbits = 0;
169 }
170
171 size_t sizeInBits() const { return sizeinbits; }
172
173 ~BoolArray() {}
174
179 void logicaland(const BoolArray &ba, BoolArray &out) const {
180 if (ba.buffer.size() < buffer.size())
181 out.setToSize(ba);
182 else
183 out.setToSize(*this);
184 for (size_t i = 0; i < out.buffer.size(); ++i)
185 out.buffer[i] = buffer[i] & ba.buffer[i];
186 }
187
193 BoolArray answer;
194 logicaland(a, answer);
195 return answer;
196 }
197
198 void inplace_logicaland(const BoolArray &ba) {
199 if (ba.buffer.size() < buffer.size())
200 setToSize(ba);
201 for (size_t i = 0; i < buffer.size(); ++i)
202 buffer[i] = buffer[i] & ba.buffer[i];
203 }
204
209 void logicalandnot(const BoolArray &ba, BoolArray &out) const {
210 out.setToSize(*this);
211 size_t upto = out.buffer.size() < ba.buffer.size() ? out.buffer.size()
212 : ba.buffer.size();
213 for (size_t i = 0; i < upto; ++i)
214 out.buffer[i] = static_cast<uword>(buffer[i] & (~ba.buffer[i]));
215 for (size_t i = upto; i < out.buffer.size(); ++i)
216 out.buffer[i] = buffer[i];
217 out.clearBogusBits();
218 }
219
225 BoolArray answer;
226 logicalandnot(a, answer);
227 return answer;
228 }
229
230 void inplace_logicalandnot(const BoolArray &ba) {
231 size_t upto =
232 buffer.size() < ba.buffer.size() ? buffer.size() : ba.buffer.size();
233 for (size_t i = 0; i < upto; ++i)
234 buffer[i] = buffer[i] & (~ba.buffer[i]);
235 clearBogusBits();
236 }
237
242 void logicalor(const BoolArray &ba, BoolArray &out) const {
243 const BoolArray *smallest;
244 const BoolArray *largest;
245 if (ba.buffer.size() > buffer.size()) {
246 smallest = this;
247 largest = &ba;
248 out.setToSize(ba);
249 } else {
250 smallest = &ba;
251 largest = this;
252 out.setToSize(*this);
253 }
254 for (size_t i = 0; i < smallest->buffer.size(); ++i)
255 out.buffer[i] = buffer[i] | ba.buffer[i];
256 for (size_t i = smallest->buffer.size(); i < largest->buffer.size(); ++i)
257 out.buffer[i] = largest->buffer[i];
258 }
259
264 BoolArray logicalor(const BoolArray &a) const {
265 BoolArray answer;
266 logicalor(a, answer);
267 return answer;
268 }
269
270 void inplace_logicalor(const BoolArray &ba) { logicalor(ba, *this); }
271
276 void logicalxor(const BoolArray &ba, BoolArray &out) const {
277 const BoolArray *smallest;
278 const BoolArray *largest;
279 if (ba.buffer.size() > buffer.size()) {
280 smallest = this;
281 largest = &ba;
282 out.setToSize(ba);
283 } else {
284 smallest = &ba;
285 largest = this;
286 out.setToSize(*this);
287 }
288 for (size_t i = 0; i < smallest->buffer.size(); ++i)
289 out.buffer[i] = buffer[i] ^ ba.buffer[i];
290 for (size_t i = smallest->buffer.size(); i < largest->buffer.size(); ++i)
291 out.buffer[i] = largest->buffer[i];
292 }
293
299 BoolArray answer;
300 logicalxor(a, answer);
301 return answer;
302 }
303
304 void inplace_logicalxor(const BoolArray &ba) { logicalxor(ba, *this); }
305
310 void logicalnot(BoolArray &out) const {
311 out.setToSize(*this);
312 for (size_t i = 0; i < buffer.size(); ++i)
313 out.buffer[i] = ~buffer[i];
314 out.clearBogusBits();
315 }
316
322 BoolArray answer;
323 logicalnot(answer);
324 return answer;
325 }
326
327 void inplace_logicalnot() {
328 for (size_t i = 0; i < buffer.size(); ++i)
329 buffer[i] = ~buffer[i];
330 clearBogusBits();
331 }
332
340 size_t numberOfOnes() const {
341 size_t count = 0;
342 for (size_t i = 0; i < buffer.size(); ++i) {
343 count += countOnes(buffer[i]);
344 }
345 return count;
346 }
347
348 inline void printout(std::ostream &o = std::cout) {
349 for (size_t k = 0; k < sizeinbits; ++k)
350 o << get(k) << " ";
351 o << std::endl;
352 }
353
359 if (a.sizeinbits < sizeinbits)
360 a.padWithZeroes(sizeinbits);
361 else if (sizeinbits < a.sizeinbits)
362 padWithZeroes(a.sizeinbits);
363 }
367 void setToSize(const BoolArray &a) {
368 sizeinbits = a.sizeinbits;
369 buffer.resize(a.buffer.size());
370 }
371
376 size_t padWithZeroes(const size_t totalbits) {
377 size_t currentwordsize = (sizeinbits + wordinbits - 1) / wordinbits;
378 size_t neededwordsize = (totalbits + wordinbits - 1) / wordinbits;
379#ifdef EWAHASSERT
380 assert(neededwordsize >= currentwordsize);
381#endif
382 buffer.resize(neededwordsize);
383 sizeinbits = totalbits;
384 return static_cast<size_t>(neededwordsize - currentwordsize);
385 }
386
387 void append(const BoolArray &a);
388
389 enum { wordinbits = sizeof(uword) * 8 };
390
391 std::vector<size_t> toArray() const {
392 std::vector<size_t> ans;
393 for (size_t k = 0; k < buffer.size(); ++k) {
394 uword myword = buffer[k];
395 while (myword != 0) {
396 uint32_t ntz = numberOfTrailingZeros(myword);
397 ans.push_back(sizeof(uword) * 8 * k + ntz);
398 myword ^= (static_cast<uword>(1) << ntz);
399 }
400 }
401 return ans;
402 }
403
408 operator std::string() const {
409 std::stringstream ss;
410 ss << *this;
411 return ss.str();
412 }
413
414 friend std::ostream &operator<<(std::ostream &out, const BoolArray &a) {
415 std::vector<size_t> v = a.toArray();
416 out << "{";
417 for (std::vector<size_t>::const_iterator i = v.begin(); i != v.end();) {
418 out << *i;
419 ++i;
420 if (i != v.end())
421 out << ",";
422 }
423 out << "}";
424 return out;
425
426 return (out << static_cast<std::string>(a));
427 }
428
429private:
430 void clearBogusBits() {
431 if ((sizeinbits % wordinbits) != 0) {
432 const uword maskbogus = static_cast<uword>(
433 (static_cast<uword>(1) << (sizeinbits % wordinbits)) - 1);
434 buffer[buffer.size() - 1] &= maskbogus;
435 }
436 }
437
438 std::vector<uword> buffer;
439 size_t sizeinbits;
440};
441
448template <class uword>
449void fast_logicalor_tocontainer(size_t n, const BoolArray<uword> **inputs,
450 BoolArray<uword> &container) {
451 if (n == 0) {
452 container.reset();
453 return;
454 }
455 container = *inputs[0];
456 for (size_t i = 0; i < n; i++) {
457 container.inplace_logicalor(*inputs[i]);
458 }
459}
460
467template <class uword>
468BoolArray<uword> fast_logicalor(size_t n, const BoolArray<uword> **inputs) {
469 BoolArray<uword> answer;
470 fast_logicalor_tocontainer(n, inputs, answer);
471 return answer;
472}
473
474template <class uword> void BoolArray<uword>::append(const BoolArray &a) {
475 if (sizeinbits % wordinbits == 0) {
476 buffer.insert(buffer.end(), a.buffer.begin(), a.buffer.end());
477 } else {
478 throw std::invalid_argument(
479 "Cannot append if parent does not meet boundary");
480 }
481 sizeinbits += a.sizeinbits;
482}
483} // namespace ewah
484#endif
A dynamic bitset implementation.
Definition boolarray.h:19
BoolArray logicaland(const BoolArray &a) const
Computes the logical and and return the result.
Definition boolarray.h:192
bool get(const size_t pos) const
true of false? (set or unset)
Definition boolarray.h:154
void logicalnot(BoolArray &out) const
Computes the logical not and writes to the provided BoolArray (out).
Definition boolarray.h:310
void unset(const size_t pos)
set to false (whether it was already set to false or not)
Definition boolarray.h:145
size_t padWithZeroes(const size_t totalbits)
make sure the size of the array is totalbits bits by padding with zeroes.
Definition boolarray.h:376
BoolArray logicalxor(const BoolArray &a) const
Computes the logical xor and return the result.
Definition boolarray.h:298
BoolArray logicalor(const BoolArray &a) const
Computes the logical or and return the result.
Definition boolarray.h:264
void logicalxor(const BoolArray &ba, BoolArray &out) const
Computes the logical xor and writes to the provided BoolArray (out).
Definition boolarray.h:276
void logicalor(const BoolArray &ba, BoolArray &out) const
Computes the logical or and writes to the provided BoolArray (out).
Definition boolarray.h:242
void logicaland(const BoolArray &ba, BoolArray &out) const
Computes the logical and and writes to the provided BoolArray (out).
Definition boolarray.h:179
size_t numberOfOnes() const
Returns the number of bits set to the value 1.
Definition boolarray.h:340
void setToSize(const BoolArray &a)
Make sure the current bitmap has the size of the provided bitmap.
Definition boolarray.h:367
BoolArray logicalandnot(const BoolArray &a) const
Computes the logical andnot and return the result.
Definition boolarray.h:224
void set(const size_t pos)
set to true (whether it was already set to true or not)
Definition boolarray.h:134
void makeSameSize(BoolArray &a)
Make sure the two bitmaps have the same size (padding with zeroes if necessary).
Definition boolarray.h:358
void reset()
set all bits to 0
Definition boolarray.h:165
BoolArray logicalandnot() const
Computes the logical not and return the result.
Definition boolarray.h:321
void logicalandnot(const BoolArray &ba, BoolArray &out) const
Computes the logical andnot and writes to the provided BoolArray (out).
Definition boolarray.h:209