diff --git a/src/search/algorithms/dynamic_bitset.h b/src/search/algorithms/dynamic_bitset.h index 68fffab158..f2e891b6ba 100644 --- a/src/search/algorithms/dynamic_bitset.h +++ b/src/search/algorithms/dynamic_bitset.h @@ -4,11 +4,14 @@ #include #include #include +#include /* Poor man's version of boost::dynamic_bitset, mostly copied from there. */ +class BitsetView; + namespace dynamic_bitset { template class DynamicBitset { @@ -16,8 +19,10 @@ class DynamicBitset { !std::numeric_limits::is_signed, "Block type must be unsigned"); + friend class ::BitsetView; // in ../per_state_bitset.h , global namespace + std::vector blocks; - const std::size_t num_bits; + std::size_t num_bits; static const Block zeros; static const Block ones; @@ -55,15 +60,42 @@ class DynamicBitset { } public: + explicit DynamicBitset() + : blocks(0, zeros), + num_bits(0) { + } explicit DynamicBitset(std::size_t num_bits) : blocks(compute_num_blocks(num_bits), zeros), num_bits(num_bits) { } + // copy constructor + DynamicBitset(const DynamicBitset &other) + : blocks(other.blocks), + num_bits(other.num_bits) { + } + // copy assignment operator + DynamicBitset& operator=(const DynamicBitset& other) { + if (this == &other) { + return *this; + } + blocks = other.blocks; + num_bits = other.num_bits; + return *this; + } + std::size_t size() const { return num_bits; } + void resize(std::size_t _num_bits){ + if (num_bits != _num_bits){ + num_bits = _num_bits; + std::size_t num_blocks = compute_num_blocks(num_bits); + blocks.resize(num_blocks, zeros); + } + } + /* Count the number of set bits. @@ -72,11 +104,22 @@ class DynamicBitset { */ int count() const { int result = 0; - for (std::size_t pos = 0; pos < num_bits; ++pos) { - result += static_cast(test(pos)); - } + // for (std::size_t pos = 0; pos < num_bits; ++pos) { + // result += static_cast(test(pos)); + // } + for (Block blk : blocks){ + result += std::popcount(blk); + } return result; } + bool any() const{ + for (Block blk : blocks){ + if (blk != 0){ + return true; + } + } + return false; + } void set() { std::fill(blocks.begin(), blocks.end(), ones); @@ -123,8 +166,78 @@ class DynamicBitset { } return true; } + + void update_not() { + for (std::size_t i = 0; i < blocks.size(); ++i) { + blocks[i] = ~blocks[i]; + } + } + void update_and(const DynamicBitset &other) { + assert(size() == other.size()); + for (std::size_t i = 0; i < blocks.size(); ++i) { + blocks[i] &= other.blocks[i]; + } + } + void update_or(const DynamicBitset &other) { + assert(size() == other.size()); + for (std::size_t i = 0; i < blocks.size(); ++i) { + blocks[i] |= other.blocks[i]; + } + } + void update_andc(const DynamicBitset &other) { // and complement + assert(size() == other.size()); + for (std::size_t i = 0; i < blocks.size(); ++i) { + blocks[i] &= ~(other.blocks[i]); + } + } + void update_orc(const DynamicBitset &other) { // or complement + assert(size() == other.size()); + for (std::size_t i = 0; i < blocks.size(); ++i) { + blocks[i] |= ~(other.blocks[i]); + } + } + void update_xor(const DynamicBitset &other) { + assert(size() == other.size()); + for (std::size_t i = 0; i < blocks.size(); ++i) { + blocks[i] ^= other.blocks[i]; + } + } + DynamicBitset& operator&=(const DynamicBitset &other){ + update_and(other); + return *this; + } + DynamicBitset& operator|=(const DynamicBitset &other){ + update_or(other); + return *this; + } + DynamicBitset& operator^=(const DynamicBitset &other){ + update_xor(other); + return *this; + } }; +template +DynamicBitset operator~(DynamicBitset copy){ + copy.update_not(); + return copy; +} +template +DynamicBitset operator&&(DynamicBitset copy, const DynamicBitset &other){ + copy &= other; + return copy; +} +template +DynamicBitset operator||(DynamicBitset copy, const DynamicBitset &other){ + copy |= other; + return copy; +} +template +DynamicBitset operator^(DynamicBitset copy, const DynamicBitset &other){ + copy ^= other; + return copy; +} + + template const Block DynamicBitset::zeros = Block(0); diff --git a/src/search/per_state_array.h b/src/search/per_state_array.h index 1fad15ddc9..a90e86572d 100644 --- a/src/search/per_state_array.h +++ b/src/search/per_state_array.h @@ -5,7 +5,7 @@ #include #include - +#include template class ConstArrayView { @@ -54,6 +54,12 @@ class ArrayView { int size() const { return size_; } + void copy_from(const ArrayView &other) { + assert(size_ == other.size_); + if (p != other.p){ + std::memcpy(p, other.p, sizeof(T) * size_); + } + } }; /* diff --git a/src/search/per_state_bitset.cc b/src/search/per_state_bitset.cc index 374b5213fb..92c1eddc26 100644 --- a/src/search/per_state_bitset.cc +++ b/src/search/per_state_bitset.cc @@ -55,6 +55,140 @@ int BitsetView::size() const { return num_bits; } +int BitsetView::count() const { + int result = 0; + for (int i = 0; i < data.size(); i++){ + result += std::popcount(data[i]); + } + return result; +} + +bool BitsetView::any() const { + for (int i = 0; i < data.size(); i++){ + if (data[i] != 0){ + return true; + } + } + return false; +} + +void BitsetView::copy_from(const BitsetView& other) { + assert(num_bits == other.num_bits); + // for (int i = 0; i < data.size(); i++){ + // data[i] = other.data[i]; + // } + data.copy_from(other.data); +} + + +void BitsetView::update_not() { + for (int i = 0; i < data.size(); ++i) { + data[i] = ~data[i]; + } +} +void BitsetView::update_and(const BitsetView &other) { + assert(size() == other.size()); + for (int i = 0; i < data.size(); ++i) { + data[i] &= other.data[i]; + } +} +void BitsetView::update_or(const BitsetView &other) { + assert(size() == other.size()); + for (int i = 0; i < data.size(); ++i) { + data[i] |= other.data[i]; + } +} +void BitsetView::update_andc(const BitsetView &other) { // and complement + assert(size() == other.size()); + for (int i = 0; i < data.size(); ++i) { + data[i] &= ~(other.data[i]); + } +} +void BitsetView::update_orc(const BitsetView &other) { // or complement + assert(size() == other.size()); + for (int i = 0; i < data.size(); ++i) { + data[i] |= ~(other.data[i]); + } +} +void BitsetView::update_xor(const BitsetView &other) { + assert(size() == other.size()); + for (int i = 0; i < data.size(); ++i) { + data[i] ^= other.data[i]; + } +} + +void BitsetView::copy_from(const dynamic_bitset::DynamicBitset& other) { + assert(num_bits == other.num_bits); + for (int i = 0; i < data.size(); i++){ + data[i] = other.blocks[i]; + } +} +void BitsetView::update_and(const dynamic_bitset::DynamicBitset &other) { + assert(size() == other.size()); + for (int i = 0; i < data.size(); ++i) { + data[i] &= other.blocks[i]; + } +} +void BitsetView::update_or(const dynamic_bitset::DynamicBitset &other) { + assert(size() == other.size()); + for (int i = 0; i < data.size(); ++i) { + data[i] |= other.blocks[i]; + } +} +void BitsetView::update_andc(const dynamic_bitset::DynamicBitset &other) { // and complement + assert(size() == other.size()); + for (int i = 0; i < data.size(); ++i) { + data[i] &= ~(other.blocks[i]); + } +} +void BitsetView::update_orc(const dynamic_bitset::DynamicBitset &other) { // or complement + assert(size() == other.size()); + for (int i = 0; i < data.size(); ++i) { + data[i] |= ~(other.blocks[i]); + } +} +void BitsetView::update_xor(const dynamic_bitset::DynamicBitset &other) { + assert(size() == other.size()); + for (int i = 0; i < data.size(); ++i) { + data[i] ^= other.blocks[i]; + } +} + +template +BitsetView& BitsetView::operator&=(const T &other){ + update_and(other); + return *this; +} +template +BitsetView& BitsetView::operator|=(const T &other){ + update_or(other); + return *this; +} +template +BitsetView& BitsetView::operator^=(const T &other){ + update_xor(other); + return *this; +} + +BitsetView operator~(BitsetView copy){ + copy.update_not(); + return copy; +} +template +BitsetView operator&&(BitsetView copy, const T &other){ + copy &= other; + return copy; +} +template +BitsetView operator||(BitsetView copy, const T &other){ + copy |= other; + return copy; +} +template +BitsetView operator^(BitsetView copy, const T &other){ + copy ^= other; + return copy; +} static vector pack_bit_vector(const vector &bits) { int num_bits = bits.size(); diff --git a/src/search/per_state_bitset.h b/src/search/per_state_bitset.h index 21c12d8eb4..a283673b5a 100644 --- a/src/search/per_state_bitset.h +++ b/src/search/per_state_bitset.h @@ -2,13 +2,14 @@ #define PER_STATE_BITSET_H #include "per_state_array.h" +#include "algorithms/dynamic_bitset.h" #include class BitsetMath { public: - using Block = unsigned int; + using Block = unsigned long int; static_assert( !std::numeric_limits::is_signed, "Block type must be unsigned"); @@ -42,6 +43,9 @@ class ConstBitsetView { class BitsetView { + + friend class dynamic_bitset::DynamicBitset; + ArrayView data; int num_bits; public: @@ -62,8 +66,37 @@ class BitsetView { bool test(int index) const; void intersect(const BitsetView &other); int size() const; + int count() const; + bool any() const; + void copy_from(const BitsetView& other); + void update_not(); + void update_and(const BitsetView &other); + void update_or(const BitsetView &other); + void update_andc(const BitsetView &other); + void update_orc(const BitsetView &other); + void update_xor(const BitsetView &other); + void copy_from(const dynamic_bitset::DynamicBitset& other); + void update_and(const dynamic_bitset::DynamicBitset &other); + void update_or(const dynamic_bitset::DynamicBitset &other); + void update_andc(const dynamic_bitset::DynamicBitset &other); + void update_orc(const dynamic_bitset::DynamicBitset &other); + void update_xor(const dynamic_bitset::DynamicBitset &other); + template + BitsetView& operator&=(const T &other); + template + BitsetView& operator|=(const T &other); + template + BitsetView& operator^=(const T &other); }; +BitsetView operator~(BitsetView copy); +template +BitsetView operator&&(BitsetView copy, const T &other); +template +BitsetView operator||(BitsetView copy, const T &other); +template +BitsetView operator^(BitsetView copy, const T &other); + class PerStateBitset { int num_bits_per_entry;