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