(linenum→info "unix/slp.c:2238")

anthy/9100e/src-worddic/mem_dic.c

    1: /*
    2:  * mem_dic 辞書のキャッシュを行う
    3:  *
    4:  * キャッシュは読みの文字列と逆変換用かのフラグ(is_reverse)の
    5:  * 二つをキーとして操作される。
    6:  *
    7:  * Copyright (C) 2000-2007 TABATA Yusuke
    8:  */
    9: /*
   10:   This library is free software; you can redistribute it and/or
   11:   modify it under the terms of the GNU Lesser General Public
   12:   License as published by the Free Software Foundation; either
   13:   version 2 of the License, or (at your option) any later version.
   14: 
   15:   This library is distributed in the hope that it will be useful,
   16:   but WITHOUT ANY WARRANTY; without even the implied warranty of
   17:   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   18:   Lesser General Public License for more details.
   19: 
   20:   You should have received a copy of the GNU Lesser General Public
   21:   License along with this library; if not, write to the Free Software
   22:   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
   23:  */
   24: #include <stdlib.h>
   25: 
   26: #include <anthy/alloc.h>
   27: #include "dic_main.h"
   28: #include "mem_dic.h"
   29: 
   30: static allocator mem_dic_ator;
   31: 
   32: static void
   33: dic_ent_dtor(void *p)
   34: {
   35:   struct dic_ent *de = p;
   36:   if (de->str.str) {
   37:     free(de->str.str);
   38:   }
   39: }
   40: 
   41: static void
   42: seq_ent_dtor(void *p)
   43: {
   44:   struct seq_ent *seq = p;
   45:   int i;
   46:   /**/
   47:   for (i = 0; i < seq->nr_dic_ents; i++) {
   48:     anthy_sfree(seq->md->dic_ent_allocator, seq->dic_ents[i]);
   49:   }
   50:   if (seq->nr_dic_ents) {
   51:     free(seq->dic_ents);
   52:   }
   53:   /**/
   54:   free(seq->str.str);
   55: }
   56: 
   57: static void
   58: mem_dic_dtor(void *p)
   59: {
   60:   struct mem_dic * md = p;
   61:   anthy_free_allocator(md->seq_ent_allocator);
   62:   anthy_free_allocator(md->dic_ent_allocator);
   63: }
   64: 
   65: /** xstrに対応するseq_entを確保する */
   66: static struct seq_ent *
   67: alloc_seq_ent_by_xstr(struct mem_dic * md, xstr *x, int is_reverse)
   68: {
   69:   struct seq_ent *se;
   70:   se = (struct seq_ent *)anthy_smalloc(md->seq_ent_allocator);
   71:   if (is_reverse) {
   72:     se->seq_type = ST_REVERSE;
   73:   } else {
   74:     se->seq_type = ST_NONE;
   75:   }
   76:   se->md = md;
   77:   se->str.len = x->len;
   78:   /**/
   79:   se->nr_dic_ents = 0;
   80:   se->dic_ents = NULL;
   81:   /**/
   82:   se->nr_compound_ents = 0;
   83: 
   84:   se->str.str = anthy_xstr_dup_str(x);
   85:   return se;
   86: }
   87: 
   88: /* ハッシュ関数。とりあえずてきとー */
   89: static int
   90: hash_function(xstr *xs)
   91: {
   92:   if (xs->len) {
   93:     return xs->str[0]% HASH_SIZE;
   94:   }
   95:   return 0;
   96: }
   97: 
   98: /** xstrに対応するseq_entを返す */
   99: struct seq_ent *
  100: anthy_mem_dic_alloc_seq_ent_by_xstr(struct mem_dic * md, xstr *xs,
  101:                                     int is_reverse)
  102: {
  103:   struct seq_ent *se;
  104:   int h;
  105:   /* キャッシュにあればそれを返す */
  106:   se = anthy_mem_dic_find_seq_ent_by_xstr(md, xs, is_reverse);
  107:   if (se) {
  108:     return se;
  109:   }
  110:   /* キャッシュには無いので作る */
  111:   se = alloc_seq_ent_by_xstr(md, xs, is_reverse);
  112: 
  113:   /* mem_dic中につなぐ */
  114:   h = hash_function(xs);
  115:   se->next = md->seq_ent_hash[h];
  116:   md->seq_ent_hash[h] = se;
  117: 
  118:   return se;
  119: }
  120: 
  121: static int
  122: compare_seq_ent(struct seq_ent *seq, xstr *xs, int is_reverse)
  123: {
  124:   /* まず、どちらかが逆変換用のエントリかをチェック */
  125:   if (seq->seq_type & ST_REVERSE) {
  126:     if (!is_reverse) {
  127:       return 1;
  128:     }
  129:   } else {
  130:     if (is_reverse) {
  131:       return 1;
  132:     }
  133:   }
  134:   /* 次に文字列の比較 */
  135:   return anthy_xstrcmp(&seq->str, xs);
  136: }
  137: 
  138: /*** mem_dicの中から文字列に対応するseq_ent*を取得する
  139:  * */
  140: struct seq_ent *
  141: anthy_mem_dic_find_seq_ent_by_xstr(struct mem_dic * md, xstr *xs,
  142:                                    int is_reverse)
  143: {
  144:   struct seq_ent *sn;
  145:   int h;
  146:   h = hash_function(xs);
  147:   for (sn = md->seq_ent_hash[h]; sn; sn = sn->next) {
  148:     if (!compare_seq_ent(sn, xs, is_reverse)){
  149:       return sn;
  150:     }
  151:   }
  152:   return 0;
  153: }
  154: 
  155: void
  156: anthy_mem_dic_release_seq_ent(struct mem_dic * md, xstr *xs, int is_reverse)
  157: {
  158:   struct seq_ent *sn;
  159:   struct seq_ent **sn_prev_p;
  160:   int h;
  161: 
  162:   h = hash_function(xs);
  163:   sn_prev_p = &md->seq_ent_hash[h];
  164:   for (sn = md->seq_ent_hash[h]; sn; sn = sn->next) {
  165:     if (!compare_seq_ent(sn, xs, is_reverse)){
  166:       *sn_prev_p = sn->next;
  167:       anthy_sfree(md->seq_ent_allocator, sn);
  168:       return;
  169:     } else {
  170:       sn_prev_p = &sn->next;
  171:     }
  172:   }
  173: }
  174: 
  175: /** seq_entにdic_entを追加する */
  176: void
  177: anthy_mem_dic_push_back_dic_ent(struct seq_ent *se, int is_compound,
  178:                                 xstr *xs, wtype_t wt,
  179:                                 const char *wt_name, int freq, int feature)
  180: {
  181:   struct dic_ent *de;
  182:   de = anthy_smalloc(se->md->dic_ent_allocator);
  183:   de->type = wt;
  184:   de->wt_name = wt_name;
  185:   de->freq = freq;
  186:   de->feature = feature;
  187:   de->order = 0;
  188:   de->is_compound = is_compound;
  189:   de->str.len = xs->len;
  190:   de->str.str = anthy_xstr_dup_str(xs);
  191: 
  192:   if (is_compound) {
  193:     se->nr_compound_ents ++;
  194:   }
  195: 
  196:   /* orderを計算する */
  197:   if (se->nr_dic_ents > 0) {
  198:     struct dic_ent *prev_de = se->dic_ents[se->nr_dic_ents-1];
  199:     if (anthy_wtype_equal(prev_de->type, de->type) &&
  200:         prev_de->freq > de->freq) {
  201:       de->order = prev_de->order + 1;
  202:     }
  203:   }
  204: 
  205:   /* 配列に追加する */
  206:   se->nr_dic_ents ++;
  207:   se->dic_ents = realloc(se->dic_ents,
  208:                          sizeof(struct dic_ent *)*se->nr_dic_ents);
  209:   se->dic_ents[se->nr_dic_ents-1] = de;
  210: }
  211: 
  212: struct mem_dic *
  213: anthy_create_mem_dic(void)
  214: {
  215:   int i;
  216:   struct mem_dic *md;
  217: 
  218:   md = anthy_smalloc(mem_dic_ator);
  219:   for (i = 0; i < HASH_SIZE; i++) {
  220:     md->seq_ent_hash[i] = NULL;
  221:   }
  222:   
  223:   md->seq_ent_allocator = 
  224:     anthy_create_allocator(sizeof(struct seq_ent),
  225:                            seq_ent_dtor);
  226:   md->dic_ent_allocator =
  227:     anthy_create_allocator(sizeof(struct dic_ent),
  228:                            dic_ent_dtor);
  229: 
  230:   return md;
  231: }
  232: 
  233: void
  234: anthy_release_mem_dic(struct mem_dic * d)
  235: {
  236:   anthy_sfree(mem_dic_ator, d);
  237: }
  238: 
  239: void
  240: anthy_init_mem_dic(void)
  241: {
  242:   mem_dic_ator = anthy_create_allocator(sizeof(struct mem_dic),
  243:                                         mem_dic_dtor);
  244: }
  245: 
  246: void
  247: anthy_quit_mem_dic(void)
  248: {
  249:   anthy_free_allocator(mem_dic_ator);
  250: }
Syntax (Markdown)