1 #include "marisa/stdio.h"
2 #include "marisa/iostream.h"
3 #include "marisa/trie.h"
4 #include "marisa/grimoire/trie.h"
5
6 namespace marisa {
7
Trie()8 Trie::Trie() : trie_() {}
9
~Trie()10 Trie::~Trie() {}
11
build(Keyset & keyset,int config_flags)12 void Trie::build(Keyset &keyset, int config_flags) {
13 scoped_ptr<grimoire::LoudsTrie> temp(new (std::nothrow) grimoire::LoudsTrie);
14 MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
15
16 temp->build(keyset, config_flags);
17 trie_.swap(temp);
18 }
19
mmap(const char * filename)20 void Trie::mmap(const char *filename) {
21 MARISA_THROW_IF(filename == NULL, MARISA_NULL_ERROR);
22
23 scoped_ptr<grimoire::LoudsTrie> temp(new (std::nothrow) grimoire::LoudsTrie);
24 MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
25
26 grimoire::Mapper mapper;
27 mapper.open(filename);
28 temp->map(mapper);
29 trie_.swap(temp);
30 }
31
map(const void * ptr,std::size_t size)32 void Trie::map(const void *ptr, std::size_t size) {
33 MARISA_THROW_IF((ptr == NULL) && (size != 0), MARISA_NULL_ERROR);
34
35 scoped_ptr<grimoire::LoudsTrie> temp(new (std::nothrow) grimoire::LoudsTrie);
36 MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
37
38 grimoire::Mapper mapper;
39 mapper.open(ptr, size);
40 temp->map(mapper);
41 trie_.swap(temp);
42 }
43
load(const char * filename)44 void Trie::load(const char *filename) {
45 MARISA_THROW_IF(filename == NULL, MARISA_NULL_ERROR);
46
47 scoped_ptr<grimoire::LoudsTrie> temp(new (std::nothrow) grimoire::LoudsTrie);
48 MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
49
50 grimoire::Reader reader;
51 reader.open(filename);
52 temp->read(reader);
53 trie_.swap(temp);
54 }
55
read(int fd)56 void Trie::read(int fd) {
57 MARISA_THROW_IF(fd == -1, MARISA_CODE_ERROR);
58
59 scoped_ptr<grimoire::LoudsTrie> temp(new (std::nothrow) grimoire::LoudsTrie);
60 MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
61
62 grimoire::Reader reader;
63 reader.open(fd);
64 temp->read(reader);
65 trie_.swap(temp);
66 }
67
save(const char * filename) const68 void Trie::save(const char *filename) const {
69 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
70 MARISA_THROW_IF(filename == NULL, MARISA_NULL_ERROR);
71
72 grimoire::Writer writer;
73 writer.open(filename);
74 trie_->write(writer);
75 }
76
write(int fd) const77 void Trie::write(int fd) const {
78 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
79 MARISA_THROW_IF(fd == -1, MARISA_CODE_ERROR);
80
81 grimoire::Writer writer;
82 writer.open(fd);
83 trie_->write(writer);
84 }
85
lookup(Agent & agent) const86 bool Trie::lookup(Agent &agent) const {
87 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
88 if (!agent.has_state()) {
89 agent.init_state();
90 }
91 return trie_->lookup(agent);
92 }
93
reverse_lookup(Agent & agent) const94 void Trie::reverse_lookup(Agent &agent) const {
95 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
96 if (!agent.has_state()) {
97 agent.init_state();
98 }
99 trie_->reverse_lookup(agent);
100 }
101
common_prefix_search(Agent & agent) const102 bool Trie::common_prefix_search(Agent &agent) const {
103 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
104 if (!agent.has_state()) {
105 agent.init_state();
106 }
107 return trie_->common_prefix_search(agent);
108 }
109
predictive_search(Agent & agent) const110 bool Trie::predictive_search(Agent &agent) const {
111 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
112 if (!agent.has_state()) {
113 agent.init_state();
114 }
115 return trie_->predictive_search(agent);
116 }
117
num_tries() const118 std::size_t Trie::num_tries() const {
119 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
120 return trie_->num_tries();
121 }
122
num_keys() const123 std::size_t Trie::num_keys() const {
124 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
125 return trie_->num_keys();
126 }
127
num_nodes() const128 std::size_t Trie::num_nodes() const {
129 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
130 return trie_->num_nodes();
131 }
132
tail_mode() const133 TailMode Trie::tail_mode() const {
134 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
135 return trie_->tail_mode();
136 }
137
node_order() const138 NodeOrder Trie::node_order() const {
139 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
140 return trie_->node_order();
141 }
142
empty() const143 bool Trie::empty() const {
144 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
145 return trie_->empty();
146 }
147
size() const148 std::size_t Trie::size() const {
149 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
150 return trie_->size();
151 }
152
total_size() const153 std::size_t Trie::total_size() const {
154 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
155 return trie_->total_size();
156 }
157
io_size() const158 std::size_t Trie::io_size() const {
159 MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
160 return trie_->io_size();
161 }
162
clear()163 void Trie::clear() {
164 Trie().swap(*this);
165 }
166
swap(Trie & rhs)167 void Trie::swap(Trie &rhs) {
168 trie_.swap(rhs.trie_);
169 }
170
171 } // namespace marisa
172
173 #include <iostream>
174
175 namespace marisa {
176
177 class TrieIO {
178 public:
fread(std::FILE * file,Trie * trie)179 static void fread(std::FILE *file, Trie *trie) {
180 MARISA_THROW_IF(trie == NULL, MARISA_NULL_ERROR);
181
182 scoped_ptr<grimoire::LoudsTrie> temp(
183 new (std::nothrow) grimoire::LoudsTrie);
184 MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
185
186 grimoire::Reader reader;
187 reader.open(file);
188 temp->read(reader);
189 trie->trie_.swap(temp);
190 }
fwrite(std::FILE * file,const Trie & trie)191 static void fwrite(std::FILE *file, const Trie &trie) {
192 MARISA_THROW_IF(file == NULL, MARISA_NULL_ERROR);
193 MARISA_THROW_IF(trie.trie_.get() == NULL, MARISA_STATE_ERROR);
194 grimoire::Writer writer;
195 writer.open(file);
196 trie.trie_->write(writer);
197 }
198
read(std::istream & stream,Trie * trie)199 static std::istream &read(std::istream &stream, Trie *trie) {
200 MARISA_THROW_IF(trie == NULL, MARISA_NULL_ERROR);
201
202 scoped_ptr<grimoire::LoudsTrie> temp(
203 new (std::nothrow) grimoire::LoudsTrie);
204 MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
205
206 grimoire::Reader reader;
207 reader.open(stream);
208 temp->read(reader);
209 trie->trie_.swap(temp);
210 return stream;
211 }
write(std::ostream & stream,const Trie & trie)212 static std::ostream &write(std::ostream &stream, const Trie &trie) {
213 MARISA_THROW_IF(trie.trie_.get() == NULL, MARISA_STATE_ERROR);
214 grimoire::Writer writer;
215 writer.open(stream);
216 trie.trie_->write(writer);
217 return stream;
218 }
219 };
220
fread(std::FILE * file,Trie * trie)221 void fread(std::FILE *file, Trie *trie) {
222 MARISA_THROW_IF(file == NULL, MARISA_NULL_ERROR);
223 MARISA_THROW_IF(trie == NULL, MARISA_NULL_ERROR);
224 TrieIO::fread(file, trie);
225 }
226
fwrite(std::FILE * file,const Trie & trie)227 void fwrite(std::FILE *file, const Trie &trie) {
228 MARISA_THROW_IF(file == NULL, MARISA_NULL_ERROR);
229 TrieIO::fwrite(file, trie);
230 }
231
read(std::istream & stream,Trie * trie)232 std::istream &read(std::istream &stream, Trie *trie) {
233 MARISA_THROW_IF(trie == NULL, MARISA_NULL_ERROR);
234 return TrieIO::read(stream, trie);
235 }
236
write(std::ostream & stream,const Trie & trie)237 std::ostream &write(std::ostream &stream, const Trie &trie) {
238 return TrieIO::write(stream, trie);
239 }
240
operator >>(std::istream & stream,Trie & trie)241 std::istream &operator>>(std::istream &stream, Trie &trie) {
242 return read(stream, &trie);
243 }
244
operator <<(std::ostream & stream,const Trie & trie)245 std::ostream &operator<<(std::ostream &stream, const Trie &trie) {
246 return write(stream, trie);
247 }
248
249 } // namespace marisa
250