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