Home | History | Annotate | Download | only in marisa_alpha
      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