1 #include <algorithm> 2 #include <stdexcept> 3 4 #include "trie.h" 5 6 namespace marisa_alpha { 7 8 Trie::Trie() 9 : louds_(), labels_(), terminal_flags_(), link_flags_(), links_(), 10 trie_(), tail_(), num_first_branches_(0), num_keys_(0) {} 11 12 void Trie::mmap(Mapper *mapper, const char *filename, 13 long offset, int whence) { 14 MARISA_ALPHA_THROW_IF(mapper == NULL, MARISA_ALPHA_PARAM_ERROR); 15 Mapper temp_mapper; 16 temp_mapper.open(filename, offset, whence); 17 map(temp_mapper); 18 temp_mapper.swap(mapper); 19 } 20 21 void Trie::map(const void *ptr, std::size_t size) { 22 Mapper mapper(ptr, size); 23 map(mapper); 24 } 25 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_ALPHA_THROW_IF(!temp.has_trie(), MARISA_ALPHA_MEMORY_ERROR); 40 temp.trie_->map(mapper); 41 } 42 temp.swap(this); 43 } 44 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 52 void Trie::fread(std::FILE *file) { 53 Reader reader(file); 54 read(reader); 55 } 56 57 void Trie::read(int fd) { 58 Reader reader(fd); 59 read(reader); 60 } 61 62 void Trie::read(std::istream &stream) { 63 Reader reader(&stream); 64 read(reader); 65 } 66 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_ALPHA_THROW_IF(!temp.has_trie(), MARISA_ALPHA_MEMORY_ERROR); 81 temp.trie_->read(reader); 82 } 83 temp.swap(this); 84 } 85 86 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 93 void Trie::fwrite(std::FILE *file) const { 94 Writer writer(file); 95 write(writer); 96 } 97 98 void Trie::write(int fd) const { 99 Writer writer(fd); 100 write(writer); 101 } 102 103 void Trie::write(std::ostream &stream) const { 104 Writer writer(&stream); 105 write(writer); 106 } 107 108 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 122 std::size_t Trie::num_tries() const { 123 return has_trie() ? (trie_->num_tries() + 1) : (louds_.empty() ? 0 : 1); 124 } 125 126 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 137 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 144 void Trie::clear() { 145 Trie().swap(this); 146 } 147 148 void Trie::swap(Trie *rhs) { 149 MARISA_ALPHA_THROW_IF(rhs == NULL, MARISA_ALPHA_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_alpha 162