180 lines
4.2 KiB
C++
180 lines
4.2 KiB
C++
#ifndef MARISA_GRIMOIRE_VECTOR_BIT_VECTOR_H_
|
|
#define MARISA_GRIMOIRE_VECTOR_BIT_VECTOR_H_
|
|
|
|
#include "marisa/grimoire/vector/rank-index.h"
|
|
#include "marisa/grimoire/vector/vector.h"
|
|
|
|
namespace marisa {
|
|
namespace grimoire {
|
|
namespace vector {
|
|
|
|
class BitVector {
|
|
public:
|
|
#if MARISA_WORD_SIZE == 64
|
|
typedef UInt64 Unit;
|
|
#else // MARISA_WORD_SIZE == 64
|
|
typedef UInt32 Unit;
|
|
#endif // MARISA_WORD_SIZE == 64
|
|
|
|
BitVector()
|
|
: units_(), size_(0), num_1s_(0), ranks_(), select0s_(), select1s_() {}
|
|
|
|
void build(bool enables_select0, bool enables_select1) {
|
|
BitVector temp;
|
|
temp.build_index(*this, enables_select0, enables_select1);
|
|
units_.shrink();
|
|
temp.units_.swap(units_);
|
|
swap(temp);
|
|
}
|
|
|
|
void map(Mapper &mapper) {
|
|
BitVector temp;
|
|
temp.map_(mapper);
|
|
swap(temp);
|
|
}
|
|
void read(Reader &reader) {
|
|
BitVector temp;
|
|
temp.read_(reader);
|
|
swap(temp);
|
|
}
|
|
void write(Writer &writer) const {
|
|
write_(writer);
|
|
}
|
|
|
|
void disable_select0() {
|
|
select0s_.clear();
|
|
}
|
|
void disable_select1() {
|
|
select1s_.clear();
|
|
}
|
|
|
|
void push_back(bool bit) {
|
|
MARISA_THROW_IF(size_ == MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
|
|
if (size_ == (MARISA_WORD_SIZE * units_.size())) {
|
|
units_.resize(units_.size() + (64 / MARISA_WORD_SIZE), 0);
|
|
}
|
|
if (bit) {
|
|
units_[size_ / MARISA_WORD_SIZE] |=
|
|
(Unit)1 << (size_ % MARISA_WORD_SIZE);
|
|
++num_1s_;
|
|
}
|
|
++size_;
|
|
}
|
|
|
|
bool operator[](std::size_t i) const {
|
|
MARISA_DEBUG_IF(i >= size_, MARISA_BOUND_ERROR);
|
|
return (units_[i / MARISA_WORD_SIZE]
|
|
& ((Unit)1 << (i % MARISA_WORD_SIZE))) != 0;
|
|
}
|
|
|
|
std::size_t rank0(std::size_t i) const {
|
|
MARISA_DEBUG_IF(ranks_.empty(), MARISA_STATE_ERROR);
|
|
MARISA_DEBUG_IF(i > size_, MARISA_BOUND_ERROR);
|
|
return i - rank1(i);
|
|
}
|
|
std::size_t rank1(std::size_t i) const;
|
|
|
|
std::size_t select0(std::size_t i) const;
|
|
std::size_t select1(std::size_t i) const;
|
|
|
|
std::size_t num_0s() const {
|
|
return size_ - num_1s_;
|
|
}
|
|
std::size_t num_1s() const {
|
|
return num_1s_;
|
|
}
|
|
|
|
bool empty() const {
|
|
return size_ == 0;
|
|
}
|
|
std::size_t size() const {
|
|
return size_;
|
|
}
|
|
std::size_t total_size() const {
|
|
return units_.total_size() + ranks_.total_size()
|
|
+ select0s_.total_size() + select1s_.total_size();
|
|
}
|
|
std::size_t io_size() const {
|
|
return units_.io_size() + (sizeof(UInt32) * 2) + ranks_.io_size()
|
|
+ select0s_.io_size() + select1s_.io_size();
|
|
}
|
|
|
|
void clear() {
|
|
BitVector().swap(*this);
|
|
}
|
|
void swap(BitVector &rhs) {
|
|
units_.swap(rhs.units_);
|
|
marisa::swap(size_, rhs.size_);
|
|
marisa::swap(num_1s_, rhs.num_1s_);
|
|
ranks_.swap(rhs.ranks_);
|
|
select0s_.swap(rhs.select0s_);
|
|
select1s_.swap(rhs.select1s_);
|
|
}
|
|
|
|
private:
|
|
Vector<Unit> units_;
|
|
std::size_t size_;
|
|
std::size_t num_1s_;
|
|
Vector<RankIndex> ranks_;
|
|
Vector<UInt32> select0s_;
|
|
Vector<UInt32> select1s_;
|
|
|
|
void build_index(const BitVector &bv,
|
|
bool enables_select0, bool enables_select1);
|
|
|
|
void map_(Mapper &mapper) {
|
|
units_.map(mapper);
|
|
{
|
|
UInt32 temp_size;
|
|
mapper.map(&temp_size);
|
|
size_ = temp_size;
|
|
}
|
|
{
|
|
UInt32 temp_num_1s;
|
|
mapper.map(&temp_num_1s);
|
|
MARISA_THROW_IF(temp_num_1s > size_, MARISA_FORMAT_ERROR);
|
|
num_1s_ = temp_num_1s;
|
|
}
|
|
ranks_.map(mapper);
|
|
select0s_.map(mapper);
|
|
select1s_.map(mapper);
|
|
}
|
|
|
|
void read_(Reader &reader) {
|
|
units_.read(reader);
|
|
{
|
|
UInt32 temp_size;
|
|
reader.read(&temp_size);
|
|
size_ = temp_size;
|
|
}
|
|
{
|
|
UInt32 temp_num_1s;
|
|
reader.read(&temp_num_1s);
|
|
MARISA_THROW_IF(temp_num_1s > size_, MARISA_FORMAT_ERROR);
|
|
num_1s_ = temp_num_1s;
|
|
}
|
|
ranks_.read(reader);
|
|
select0s_.read(reader);
|
|
select1s_.read(reader);
|
|
}
|
|
|
|
void write_(Writer &writer) const {
|
|
units_.write(writer);
|
|
writer.write((UInt32)size_);
|
|
writer.write((UInt32)num_1s_);
|
|
ranks_.write(writer);
|
|
select0s_.write(writer);
|
|
select1s_.write(writer);
|
|
}
|
|
|
|
// Disallows copy and assignment.
|
|
BitVector(const BitVector &);
|
|
BitVector &operator=(const BitVector &);
|
|
};
|
|
|
|
} // namespace vector
|
|
} // namespace grimoire
|
|
} // namespace marisa
|
|
|
|
#endif // MARISA_GRIMOIRE_VECTOR_BIT_VECTOR_H_
|