• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <algorithm>
2 #include <stdexcept>
3 
4 #include "trie.h"
5 
6 namespace marisa {
7 
Trie()8 Trie::Trie()
9     : louds_(), labels_(), terminal_flags_(), link_flags_(), links_(),
10       trie_(), tail_(), num_first_branches_(0), num_keys_(0) {}
11 
mmap(Mapper * mapper,const char * filename,long offset,int whence)12 void Trie::mmap(Mapper *mapper, const char *filename,
13     long offset, int whence) {
14   MARISA_THROW_IF(mapper == NULL, MARISA_PARAM_ERROR);
15   Mapper temp_mapper;
16   temp_mapper.open(filename, offset, whence);
17   map(temp_mapper);
18   temp_mapper.swap(mapper);
19 }
20 
map(const void * ptr,std::size_t size)21 void Trie::map(const void *ptr, std::size_t size) {
22   Mapper mapper(ptr, size);
23   map(mapper);
24 }
25 
map(Mapper & mapper)26 void Trie::map(Mapper &mapper) {
27   Trie temp;
28   temp.louds_.map(mapper);
29   temp.labels_.map(mapper);
30   temp.terminal_flags_.map(mapper);
31   temp.link_flags_.map(mapper);
32   temp.links_.map(mapper);
33   temp.tail_.map(mapper);
34   mapper.map(&temp.num_first_branches_);
35   mapper.map(&temp.num_keys_);
36 
37   if (temp.has_link() && !temp.has_tail()) {
38     temp.trie_.reset(new (std::nothrow) Trie);
39     MARISA_THROW_IF(!temp.has_trie(), MARISA_MEMORY_ERROR);
40     temp.trie_->map(mapper);
41   }
42   temp.swap(this);
43 }
44 
load(const char * filename,long offset,int whence)45 void Trie::load(const char *filename,
46     long offset, int whence) {
47   Reader reader;
48   reader.open(filename, offset, whence);
49   read(reader);
50 }
51 
fread(std::FILE * file)52 void Trie::fread(std::FILE *file) {
53   Reader reader(file);
54   read(reader);
55 }
56 
read(int fd)57 void Trie::read(int fd) {
58   Reader reader(fd);
59   read(reader);
60 }
61 
read(std::istream & stream)62 void Trie::read(std::istream &stream) {
63   Reader reader(&stream);
64   read(reader);
65 }
66 
read(Reader & reader)67 void Trie::read(Reader &reader) {
68   Trie temp;
69   temp.louds_.read(reader);
70   temp.labels_.read(reader);
71   temp.terminal_flags_.read(reader);
72   temp.link_flags_.read(reader);
73   temp.links_.read(reader);
74   temp.tail_.read(reader);
75   reader.read(&temp.num_first_branches_);
76   reader.read(&temp.num_keys_);
77 
78   if (temp.has_link() && !temp.has_tail()) {
79     temp.trie_.reset(new (std::nothrow) Trie);
80     MARISA_THROW_IF(!temp.has_trie(), MARISA_MEMORY_ERROR);
81     temp.trie_->read(reader);
82   }
83   temp.swap(this);
84 }
85 
save(const char * filename,bool trunc_flag,long offset,int whence) const86 void Trie::save(const char *filename, bool trunc_flag,
87     long offset, int whence) const {
88   Writer writer;
89   writer.open(filename, trunc_flag, offset, whence);
90   write(writer);
91 }
92 
fwrite(std::FILE * file) const93 void Trie::fwrite(std::FILE *file) const {
94   Writer writer(file);
95   write(writer);
96 }
97 
write(int fd) const98 void Trie::write(int fd) const {
99   Writer writer(fd);
100   write(writer);
101 }
102 
write(std::ostream & stream) const103 void Trie::write(std::ostream &stream) const {
104   Writer writer(&stream);
105   write(writer);
106 }
107 
write(Writer & writer) const108 void Trie::write(Writer &writer) const {
109   louds_.write(writer);
110   labels_.write(writer);
111   terminal_flags_.write(writer);
112   link_flags_.write(writer);
113   links_.write(writer);
114   tail_.write(writer);
115   writer.write(num_first_branches_);
116   writer.write(num_keys_);
117   if (has_trie()) {
118     trie_->write(writer);
119   }
120 }
121 
num_tries() const122 std::size_t Trie::num_tries() const {
123   return has_trie() ? (trie_->num_tries() + 1) : (louds_.empty() ? 0 : 1);
124 }
125 
num_nodes() const126 std::size_t Trie::num_nodes() const {
127   if (louds_.empty()) {
128     return 0;
129   }
130   std::size_t num_nodes = (louds_.size() / 2) - 1;
131   if (has_trie()) {
132     num_nodes += trie_->num_nodes();
133   }
134   return num_nodes;
135 }
136 
total_size() const137 std::size_t Trie::total_size() const {
138   return louds_.total_size() + labels_.total_size()
139       + terminal_flags_.total_size() + link_flags_.total_size()
140       + links_.total_size() + (has_trie() ? trie_->total_size() : 0)
141       + tail_.total_size() + sizeof(num_first_branches_) + sizeof(num_keys_);
142 }
143 
clear()144 void Trie::clear() {
145   Trie().swap(this);
146 }
147 
swap(Trie * rhs)148 void Trie::swap(Trie *rhs) {
149   MARISA_THROW_IF(rhs == NULL, MARISA_PARAM_ERROR);
150   louds_.swap(&rhs->louds_);
151   labels_.swap(&rhs->labels_);
152   terminal_flags_.swap(&rhs->terminal_flags_);
153   link_flags_.swap(&rhs->link_flags_);
154   links_.swap(&rhs->links_);
155   Swap(&trie_, &rhs->trie_);
156   tail_.swap(&rhs->tail_);
157   Swap(&num_first_branches_, &rhs->num_first_branches_);
158   Swap(&num_keys_, &rhs->num_keys_);
159 }
160 
161 }  // namespace marisa
162