Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 117 additions & 4 deletions src/search/algorithms/dynamic_bitset.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,25 @@
#include <cassert>
#include <limits>
#include <vector>
#include <bit>

/*
Poor man's version of boost::dynamic_bitset, mostly copied from there.
*/

class BitsetView;

namespace dynamic_bitset {
template<typename Block = unsigned int>
class DynamicBitset {
static_assert(
!std::numeric_limits<Block>::is_signed,
"Block type must be unsigned");

friend class ::BitsetView; // in ../per_state_bitset.h , global namespace

std::vector<Block> blocks;
const std::size_t num_bits;
std::size_t num_bits;

static const Block zeros;
static const Block ones;
Expand Down Expand Up @@ -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.

Expand All @@ -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<int>(test(pos));
}
// for (std::size_t pos = 0; pos < num_bits; ++pos) {
// result += static_cast<int>(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);
Expand Down Expand Up @@ -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<typename Block>
DynamicBitset<Block> operator~(DynamicBitset<Block> copy){
copy.update_not();
return copy;
}
template<typename Block>
DynamicBitset<Block> operator&&(DynamicBitset<Block> copy, const DynamicBitset<Block> &other){
copy &= other;
return copy;
}
template<typename Block>
DynamicBitset<Block> operator||(DynamicBitset<Block> copy, const DynamicBitset<Block> &other){
copy |= other;
return copy;
}
template<typename Block>
DynamicBitset<Block> operator^(DynamicBitset<Block> copy, const DynamicBitset<Block> &other){
copy ^= other;
return copy;
}


template<typename Block>
const Block DynamicBitset<Block>::zeros = Block(0);

Expand Down
8 changes: 7 additions & 1 deletion src/search/per_state_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#include <cassert>
#include <unordered_map>

#include <cstring>

template<class T>
class ConstArrayView {
Expand Down Expand Up @@ -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_);
}
}
};

/*
Expand Down
134 changes: 134 additions & 0 deletions src/search/per_state_bitset.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<BitsetMath::Block>& 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<BitsetMath::Block> &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<BitsetMath::Block> &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<BitsetMath::Block> &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<BitsetMath::Block> &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<BitsetMath::Block> &other) {
assert(size() == other.size());
for (int i = 0; i < data.size(); ++i) {
data[i] ^= other.blocks[i];
}
}

template<class T>
BitsetView& BitsetView::operator&=(const T &other){
update_and(other);
return *this;
}
template<class T>
BitsetView& BitsetView::operator|=(const T &other){
update_or(other);
return *this;
}
template<class T>
BitsetView& BitsetView::operator^=(const T &other){
update_xor(other);
return *this;
}

BitsetView operator~(BitsetView copy){
copy.update_not();
return copy;
}
template<class T>
BitsetView operator&&(BitsetView copy, const T &other){
copy &= other;
return copy;
}
template<class T>
BitsetView operator||(BitsetView copy, const T &other){
copy |= other;
return copy;
}
template<class T>
BitsetView operator^(BitsetView copy, const T &other){
copy ^= other;
return copy;
}

static vector<BitsetMath::Block> pack_bit_vector(const vector<bool> &bits) {
int num_bits = bits.size();
Expand Down
Loading