24 #ifndef GRAPHLAB_DENSE_BITSET_HPP
25 #define GRAPHLAB_DENSE_BITSET_HPP
32 #include <graphlab/parallel/atomic_ops.hpp>
33 #include <graphlab/serialization/serialization_includes.hpp>
69 memcpy(array, db.array,
sizeof(
size_t) * arrlen);
83 arrlen = (n / (
sizeof(size_t) * 8)) + (n % (
sizeof(
size_t) * 8) > 0);
84 array = (
size_t*)realloc(array,
sizeof(
size_t) * arrlen);
90 for (
size_t i = 0; i < arrlen; ++i) array[i] = 0;
93 inline bool empty()
const {
94 for (
size_t i = 0; i < arrlen; ++i)
if (array[i])
return false;
100 for (
size_t i = 0;i < arrlen; ++i) array[i] = (
size_t) - 1;
106 __builtin_prefetch(&(array[b / (8 *
sizeof(
size_t))]));
110 inline bool get(
size_t b)
const{
111 size_t arrpos, bitpos;
112 bit_to_pos(b, arrpos, bitpos);
113 return array[arrpos] & (size_t(1) << size_t(bitpos));
119 size_t arrpos, bitpos;
120 bit_to_pos(b, arrpos, bitpos);
121 const size_t mask(
size_t(1) <<
size_t(bitpos));
122 return __sync_fetch_and_or(array + arrpos, mask) & mask;
128 size_t arrpos, bitpos;
129 bit_to_pos(b, arrpos, bitpos);
130 const size_t mask(
size_t(1) <<
size_t(bitpos));
131 return __sync_fetch_and_xor(array + arrpos, mask) & mask;
136 size_t arrpos, bitpos;
137 bit_to_pos(b, arrpos, bitpos);
138 return array[arrpos];
143 size_t arrpos, bitpos;
144 bit_to_pos(b, arrpos, bitpos);
177 ASSERT_EQ(other.len, len);
178 ASSERT_EQ(other.arrlen, arrlen);
179 size_t arrpos, bitpos;
180 bit_to_pos(start, arrpos, bitpos);
181 size_t initial_arrpos = arrpos;
182 if (arrpos >= arrlen) arrpos = 0;
184 size_t transferred = 0;
185 while(transferred < b) {
186 if (other.array[arrpos] > 0) {
187 transferred += __builtin_popcountl(other.array[arrpos]);
188 array[arrpos] |= other.array[arrpos];
189 other.array[arrpos] = 0;
192 if (arrpos >= other.arrlen) arrpos = 0;
193 else if (arrpos == initial_arrpos)
break;
195 start = 8 *
sizeof(size_t) * arrpos;
206 size_t arrpos, bitpos;
207 bit_to_pos(b, arrpos, bitpos);
208 const size_t mask(
size_t(1) <<
size_t(bitpos));
209 bool ret = array[arrpos] & mask;
210 array[arrpos] |= mask;
215 inline bool set(
size_t b,
bool value) {
233 size_t arrpos, bitpos;
234 bit_to_pos(b, arrpos, bitpos);
235 const size_t test_mask(
size_t(1) <<
size_t(bitpos));
236 const size_t clear_mask(~test_mask);
237 return __sync_fetch_and_and(array + arrpos, clear_mask) & test_mask;
246 size_t arrpos, bitpos;
247 bit_to_pos(b, arrpos, bitpos);
248 const size_t test_mask(
size_t(1) <<
size_t(bitpos));
249 const size_t clear_mask(~test_mask);
250 bool ret = array[arrpos] & test_mask;
251 array[arrpos] &= clear_mask;
255 struct bit_pos_iterator {
256 typedef std::input_iterator_tag iterator_category;
257 typedef size_t value_type;
258 typedef size_t difference_type;
259 typedef const size_t reference;
260 typedef const size_t* pointer;
263 bit_pos_iterator():pos(-1),db(NULL) {}
264 bit_pos_iterator(
const dense_bitset*
const db,
size_t pos):pos(pos),db(db) {}
266 size_t operator*()
const {
270 if (db->next_bit(pos) ==
false) pos = (
size_t)(-1);
273 size_t operator++(
int){
274 size_t prevpos = pos;
275 if (db->next_bit(pos) ==
false) pos = (
size_t)(-1);
278 bool operator==(
const bit_pos_iterator& other)
const {
279 ASSERT_TRUE(db == other.db);
280 return other.pos == pos;
282 bool operator!=(
const bit_pos_iterator& other)
const {
283 ASSERT_TRUE(db == other.db);
284 return other.pos != pos;
288 typedef bit_pos_iterator iterator;
289 typedef bit_pos_iterator const_iterator;
292 bit_pos_iterator begin()
const {
294 if (
first_bit(pos) ==
false) pos = size_t(-1);
295 return bit_pos_iterator(
this, pos);
298 bit_pos_iterator end()
const {
299 return bit_pos_iterator(
this, (
size_t)(-1));
307 for (
size_t i = 0; i < arrlen; ++i) {
309 b = (size_t)(i * (
sizeof(
size_t) * 8)) + first_bit_in_block(array[i]);
322 for (
size_t i = 0; i < arrlen; ++i) {
324 b = (size_t)(i * (
sizeof(
size_t) * 8)) + first_bit_in_block(~array[i]);
336 size_t arrpos, bitpos;
337 bit_to_pos(b, arrpos, bitpos);
339 bitpos = next_bit_in_block(bitpos, array[arrpos]);
341 b = (size_t)(arrpos * (
sizeof(
size_t) * 8)) + bitpos;
346 for (
size_t i = arrpos + 1; i < arrlen; ++i) {
348 b = (size_t)(i * (
sizeof(
size_t) * 8)) + first_bit_in_block(array[i]);
363 oarc <<len << arrlen;
364 if (arrlen > 0) serialize(oarc, array, arrlen*
sizeof(
size_t));
369 if (array != NULL) free(array);
371 iarc >> len >> arrlen;
373 array = (
size_t*)malloc(arrlen*
sizeof(
size_t));
374 deserialize(iarc, array, arrlen*
sizeof(
size_t));
379 size_t popcount()
const {
381 for (
size_t i = 0;i < arrlen; ++i) {
382 ret += __builtin_popcountl(array[i]);
388 ASSERT_EQ(
size(), other.size());
390 for (
size_t i = 0; i < arrlen; ++i) {
391 ret.array[i] = array[i] & other.array[i];
398 ASSERT_EQ(
size(), other.size());
400 for (
size_t i = 0; i < arrlen; ++i) {
401 ret.array[i] = array[i] | other.array[i];
407 ASSERT_EQ(
size(), other.size());
409 for (
size_t i = 0; i < arrlen; ++i) {
410 ret.array[i] = array[i] - (array[i] & other.array[i]);
417 ASSERT_EQ(
size(), other.size());
418 for (
size_t i = 0; i < arrlen; ++i) {
419 array[i] &= other.array[i];
426 ASSERT_EQ(
size(), other.size());
427 for (
size_t i = 0; i < arrlen; ++i) {
428 array[i] |= other.array[i];
434 ASSERT_EQ(
size(), other.size());
435 for (
size_t i = 0; i < arrlen; ++i) {
436 array[i] = array[i] - (array[i] & other.array[i]);
442 for (
size_t i = 0; i < arrlen; ++i) {
443 array[i] = ~array[i];
450 inline static void bit_to_pos(
size_t b,
size_t& arrpos,
size_t& bitpos) {
452 arrpos = b / (8 *
sizeof(size_t));
453 bitpos = b & (8 *
sizeof(size_t) - 1);
457 inline size_t next_bit_in_block(
const size_t& b,
const size_t& block)
const {
458 size_t belowselectedbit = size_t(-1) - (((size_t(1) << b) - 1)|(size_t(1)<<b));
459 size_t x = block & belowselectedbit ;
460 if (x == 0)
return 0;
461 else return (
size_t)__builtin_ctzl(x);
465 inline size_t first_bit_in_block(
const size_t& block)
const{
466 if (block == 0)
return 0;
467 else return (
size_t)__builtin_ctzl(block);
471 void fix_trailing_bits() {
473 size_t lastbits = len % (8 *
sizeof(size_t));
474 if (lastbits == 0)
return;
475 array[arrlen - 1] &= ((size_t(1) << lastbits) - 1);
483 friend class fixed_dense_bitset;
531 memcpy(array, mem, memlen);
539 memcpy(array, db.array,
sizeof(
size_t) * arrlen);
545 memset((
void*)array, 0,
sizeof(
size_t) * arrlen);
550 for (
size_t i = 0;i < arrlen; ++i) array[i] = -1;
554 inline bool empty()
const {
555 for (
size_t i = 0; i < arrlen; ++i)
if (array[i])
return false;
561 __builtin_prefetch(&(array[b / (8 *
sizeof(
size_t))]));
565 inline bool get(
size_t b)
const{
566 size_t arrpos, bitpos;
567 bit_to_pos(b, arrpos, bitpos);
568 return array[arrpos] & (size_t(1) << size_t(bitpos));
574 size_t arrpos, bitpos;
575 bit_to_pos(b, arrpos, bitpos);
576 const size_t mask(
size_t(1) <<
size_t(bitpos));
577 return __sync_fetch_and_or(array + arrpos, mask) & mask;
583 size_t arrpos, bitpos;
584 bit_to_pos(b, arrpos, bitpos);
585 return array[arrpos];
595 size_t arrpos, bitpos;
596 bit_to_pos(b, arrpos, bitpos);
597 const size_t mask(
size_t(1) <<
size_t(bitpos));
598 bool ret = array[arrpos] & mask;
599 array[arrpos] |= mask;
607 inline bool set(
size_t b,
bool value) {
625 size_t arrpos, bitpos;
626 bit_to_pos(b, arrpos, bitpos);
627 const size_t test_mask(
size_t(1) <<
size_t(bitpos));
628 const size_t clear_mask(~test_mask);
629 return __sync_fetch_and_and(array + arrpos, clear_mask) & test_mask;
638 size_t arrpos, bitpos;
639 bit_to_pos(b, arrpos, bitpos);
640 const size_t test_mask(
size_t(1) <<
size_t(bitpos));
641 const size_t clear_mask(~test_mask);
642 bool ret = array[arrpos] & test_mask;
643 array[arrpos] &= clear_mask;
648 struct bit_pos_iterator {
649 typedef std::input_iterator_tag iterator_category;
650 typedef size_t value_type;
651 typedef size_t difference_type;
652 typedef const size_t reference;
653 typedef const size_t* pointer;
656 bit_pos_iterator():pos(-1),db(NULL) {}
659 size_t operator*()
const {
663 if (db->next_bit(pos) ==
false) pos = (
size_t)(-1);
666 size_t operator++(
int){
667 size_t prevpos = pos;
668 if (db->next_bit(pos) ==
false) pos = (
size_t)(-1);
671 bool operator==(
const bit_pos_iterator& other)
const {
672 ASSERT_TRUE(db == other.db);
673 return other.pos == pos;
675 bool operator!=(
const bit_pos_iterator& other)
const {
676 ASSERT_TRUE(db == other.db);
677 return other.pos != pos;
681 typedef bit_pos_iterator iterator;
682 typedef bit_pos_iterator const_iterator;
685 bit_pos_iterator begin()
const {
687 if (
first_bit(pos) ==
false) pos = size_t(-1);
688 return bit_pos_iterator(
this, pos);
691 bit_pos_iterator end()
const {
692 return bit_pos_iterator(
this, (
size_t)(-1));
700 for (
size_t i = 0; i < arrlen; ++i) {
702 b = (size_t)(i * (
sizeof(
size_t) * 8)) + first_bit_in_block(array[i]);
714 for (
size_t i = 0; i < arrlen; ++i) {
716 b = (size_t)(i * (
sizeof(
size_t) * 8)) + first_bit_in_block(~array[i]);
730 size_t arrpos, bitpos;
731 bit_to_pos(b, arrpos, bitpos);
733 bitpos = next_bit_in_block(bitpos, array[arrpos]);
735 b = (size_t)(arrpos * (
sizeof(
size_t) * 8)) + bitpos;
740 for (
size_t i = arrpos + 1; i < arrlen; ++i) {
742 b = (size_t)(i * (
sizeof(
size_t) * 8)) + first_bit_in_block(array[i]);
759 serialize(oarc, array, arrlen*
sizeof(
size_t));
770 deserialize(iarc, array, arrlen*
sizeof(
size_t));
774 size_t popcount()
const {
776 for (
size_t i = 0;i < arrlen; ++i) {
777 ret += __builtin_popcountl(array[i]);
783 inline static void bit_to_pos(
size_t b,
size_t &arrpos,
size_t &bitpos) {
785 arrpos = b / (8 *
sizeof(size_t));
786 bitpos = b & (8 *
sizeof(size_t) - 1);
791 inline size_t next_bit_in_block(
const size_t &b,
const size_t &block)
const {
792 size_t belowselectedbit = size_t(-1) - (((size_t(1) << b) - 1)|(size_t(1)<<b));
793 size_t x = block & belowselectedbit ;
794 if (x == 0)
return 0;
795 else return (
size_t)__builtin_ctzl(x);
799 inline size_t first_bit_in_block(
const size_t &block)
const {
801 if (block == 0)
return 0;
802 else return (
size_t)__builtin_ctzl(block);
805 void fix_trailing_bits() {
807 size_t lastbits = len % (8 *
sizeof(size_t));
808 if (lastbits == 0)
return;
809 array[arrlen - 1] &= ((size_t(1) << lastbits) - 1);
813 static const size_t arrlen;
814 size_t array[len / (
sizeof(size_t) * 8) + (len % (
sizeof(size_t) * 8) > 0)];
818 const size_t fixed_dense_bitset<len>::arrlen = len / (
sizeof(size_t) * 8) + (len % (
sizeof(size_t) * 8) > 0);