diff --git a/persistent-data/data-structures/bitset.cc b/persistent-data/data-structures/bitset.cc index 9400222..9625dae 100644 --- a/persistent-data/data-structures/bitset.cc +++ b/persistent-data/data-structures/bitset.cc @@ -2,6 +2,7 @@ #include "persistent-data/data-structures/bitset.h" #include "persistent-data/math_utils.h" +using namespace boost; using namespace persistent_data; using namespace persistent_data::bitset_detail; using namespace std; @@ -75,7 +76,52 @@ namespace persistent_data { void flush() { } + void walk_bitset(bitset_visitor &v) const { + bit_visitor vv(v); + damage_visitor dv(v); + array_.visit_values(vv, dv); + } + private: + class bit_visitor { + public: + bit_visitor(bitset_visitor &v) + : v_(v) { + } + + void visit(uint32_t word_index, uint64_t word) { + uint32_t bit_index = word_index * 64; + for (unsigned bit = 0; bit < 64; bit++, bit_index++) + v_.visit(bit_index, !!(word & (1 << bit))); + } + + private: + bitset_visitor &v_; + }; + + class damage_visitor { + public: + damage_visitor(bitset_visitor &v) + : v_(v) { + } + + void visit(array_detail::damage const &d) { + run bits(lifted_mult64(d.lost_keys_.begin_), + lifted_mult64(d.lost_keys_.end_)); + v_.visit(bits); + } + + private: + optional lifted_mult64(optional const &m) { + if (!m) + return m; + + return optional(*m * 64); + } + + bitset_visitor &v_; + }; + void pad_last_block(bool default_value) { // Set defaults in the final word if (bit(nr_bits_)) { @@ -198,5 +244,11 @@ bitset::flush() impl_->flush(); } +void +bitset::walk_bitset(bitset_visitor &v) const +{ + impl_->walk_bitset(v); +} + //---------------------------------------------------------------- diff --git a/persistent-data/data-structures/bitset.h b/persistent-data/data-structures/bitset.h index 89fa5e1..3e26985 100644 --- a/persistent-data/data-structures/bitset.h +++ b/persistent-data/data-structures/bitset.h @@ -19,11 +19,31 @@ #ifndef BITSET_H #define BITSET_H +#include "persistent-data/run.h" + //---------------------------------------------------------------- namespace persistent_data { namespace bitset_detail { class bitset_impl; + + class missing_bits { + public: + missing_bits(base::run const &keys) + : keys_(keys) { + } + + base::run keys_; + }; + + class bitset_visitor { + public: + typedef boost::shared_ptr ptr; + + virtual ~bitset_visitor(); + virtual void visit(uint32_t index, bool value); + virtual void visit(missing_bits const &d); + }; } class bitset { @@ -42,6 +62,8 @@ namespace persistent_data { void set(unsigned n, bool value); void flush(); + void walk_bitset(bitset_detail::bitset_visitor &v) const; + private: boost::shared_ptr impl_; };