1f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#ifndef MARISA_BITVECTOR_H_
2f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_BITVECTOR_H_
3f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
4f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#include "rank.h"
5f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#include "vector.h"
6f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
7f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathnamespace marisa {
8f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
9f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathclass BitVector {
10f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath public:
11f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  BitVector();
12f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
13f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void build();
14f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
15f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void clear_select0s() {
16f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    select0s_.clear();
17f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
18f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void clear_select1s() {
19f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    select1s_.clear();
20f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
21f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
22f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void mmap(Mapper *mapper, const char *filename,
23f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath      long offset = 0, int whence = SEEK_SET);
24f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void map(const void *ptr, std::size_t size);
25f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void map(Mapper &mapper);
26f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
27f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void load(const char *filename,
28f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath      long offset = 0, int whence = SEEK_SET);
29f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void fread(std::FILE *file);
30f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void read(int fd);
31f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void read(std::istream &stream);
32f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void read(Reader &reader);
33f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
34f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void save(const char *filename, bool trunc_flag = true,
35f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath      long offset = 0, int whence = SEEK_SET) const;
36f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void fwrite(std::FILE *file) const;
37f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void write(int fd) const;
38f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void write(std::ostream &stream) const;
39f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void write(Writer &writer) const;
40f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
41f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void push_back(bool bit) {
42f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    MARISA_THROW_IF(size_ == max_size(), MARISA_SIZE_ERROR);
43f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    if ((size_ % 32) == 0) {
44f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath      blocks_.push_back(0);
45f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    }
46f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    if (bit) {
47f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath      blocks_.back() |= 1U << (size_ % 32);
48f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    }
49f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    ++size_;
50f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
51f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
52f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  bool operator[](std::size_t i) const {
53f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    MARISA_DEBUG_IF(i >= size_, MARISA_PARAM_ERROR);
54f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    return (blocks_[i / 32] & (1U << (i % 32))) != 0;
55f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
56f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
57f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  UInt32 rank0(UInt32 i) const {
58f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    MARISA_DEBUG_IF(i > size_, MARISA_PARAM_ERROR);
59f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    return i - rank1(i);
60f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
61f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  UInt32 rank1(UInt32 i) const;
62f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
63f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  UInt32 select0(UInt32 i) const;
64f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  UInt32 select1(UInt32 i) const;
65f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
66f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  std::size_t size() const {
67f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    return size_;
68f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
69f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  bool empty() const {
70f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    return blocks_.empty();
71f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
72f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  std::size_t max_size() const {
73f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    return MARISA_UINT32_MAX;
74f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
75f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  std::size_t total_size() const {
76f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    return blocks_.total_size() + sizeof(size_) + ranks_.total_size()
77f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath        + select0s_.total_size() + select1s_.total_size();
78f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
79f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
80f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void clear();
81f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  void swap(BitVector *rhs);
82f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
83f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath private:
84f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  Vector<UInt32> blocks_;
85f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  UInt32 size_;
86f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  Vector<Rank> ranks_;
87f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  Vector<UInt32> select0s_;
88f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  Vector<UInt32> select1s_;
89f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
90f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // Disallows copy and assignment.
91f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  BitVector(const BitVector &);
92f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  BitVector &operator=(const BitVector &);
93f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath};
94f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
95f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath}  // namespace marisa
96f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
97f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#endif  // MARISA_BITVECTOR_H_
98