Files
strans/dict.c
Hojun-Cho c7718ece52 data: one trie for maps and dictionaries, one loader
The hash map served a single exact-match lookup that the trie already
answers, at the price of a second container, a second file loader with
its own drift, and a Str-to-UTF-8 conversion on every chain probe. The
files are small (kanji.dict is 7.5k lines), so the trie holds both.
trieopen validates keys and each space-separated value word against Str
and reports path:line; trielookup takes the Str every caller holds and
treats a nil trie as an unloaded map; trienew/trieput exist for tests.
The overflow guards on growth, Trie.root (always 0) and the per-language
init loop written twice are gone.
2026-08-16 15:56:32 +09:00

78 lines
1.4 KiB
C

#include "dat.h"
#include "fn.h"
/* Candidates are the space-separated words of the value; the reading itself
* is a candidate only for the emoji dictionary. */
void
dictlookup(Dictreq *req, Dictres *res)
{
Lang *l;
char *p, *e, *sp;
Str tmp;
int vlen;
res->key = req->pre;
res->nkouho = 0;
res->lang = req->lang;
res->seq = req->seq;
l = getlang(req->lang);
if(req->key.n == 0 || l == nil ||
trielookup(l->dict, &req->key, &p, &vlen) != TrieExact)
return;
e = p + vlen;
while(res->nkouho < Maxkouho && p < e){
while(p < e && *p == ' ')
p++;
sp = p;
while(p < e && *p != ' ')
p++;
if(sinit(&tmp, sp, p - sp) && tmp.n > 0 &&
(req->lang == LangEMOJI || scmp(&tmp, &req->key) != 0))
res->kouho[res->nkouho++] = tmp;
}
}
void
dictthread(void*)
{
Dictreq req;
static Dictres res;
threadsetname("dict");
for(;;){
if(chanrecv(dictreqc, &req) < 0)
break;
while(channbrecv(dictreqc, &req) > 0)
;
dictlookup(&req, &res);
chansend(dictresc, &res);
}
}
static Trie*
langopen(char *dir, char *name, char *ext)
{
char *path;
Trie *t;
path = smprint("%s/%s.%s", dir, name, ext);
if(path == nil)
die("out of memory");
t = trieopen(path);
free(path);
return t;
}
void
langinit(char *dir)
{
Lang *l;
for(l = langs; l < langs + nlang; l++){
if(l->mapname != nil)
l->map = langopen(dir, l->mapname, "map");
if(l->dictname != nil)
l->dict = langopen(dir, l->dictname, "dict");
}
}