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.
This commit is contained in:
2026-08-16 15:56:32 +09:00
parent eb0f88f764
commit c7718ece52
15 changed files with 206 additions and 609 deletions

View File

@@ -311,14 +311,14 @@ engine_rejects_stale_dictionary_results(struct ct *t)
{
Dictreq a, b;
Dictres res;
Hmap *saved;
Trie *saved;
Lang *jp;
char one, two;
int n;
jp = getlang(LangJP);
saved = jp->dict;
jp->dict = hmapalloc(1);
jp->dict = trienew();
init();
im.l = jp;
while(channbrecv(dictreqc, &a) > 0)
@@ -362,7 +362,7 @@ engine_rejects_stale_dictionary_results(struct ct *t)
cleanup:
while(channbrecv(dictreqc, &a) > 0)
;
hmapfree(jp->dict);
trieclose(jp->dict);
jp->dict = saved;
}
@@ -720,7 +720,7 @@ struct Searchfix
Im im;
Search search;
Lang *dictlang;
Hmap *dict;
Trie *dict;
int activecap;
int visible;
int candidatechosen;
@@ -939,12 +939,9 @@ engine_candidate_completion(struct ct *t)
}
static void
setdict(Hmap **dict, char *key, char *val)
setdict(Trie *dict, char *key, char *val)
{
Str s;
s = mkstr(key);
hmapset(dict, &s, val, strlen(val));
trieput(dict, key, strlen(key), val, strlen(val));
}
static void
@@ -964,22 +961,22 @@ static void
emojibegin(Searchfix *f, int showpre)
{
searchsave(f, LangEMOJI);
f->dictlang->dict = hmapalloc(32);
setdict(&f->dictlang->dict, "a", "A B");
setdict(&f->dictlang->dict, "", "B C");
setdict(&f->dictlang->dict, "alpha", "α");
setdict(&f->dictlang->dict, "smil", "😀 😄");
setdict(&f->dictlang->dict, "smile", "😀 😄");
setdict(&f->dictlang->dict, "웃음", "😀 😄 😂");
setdict(&f->dictlang->dict, "えがお", "😀 😄 😊");
setdict(&f->dictlang->dict, "エガオ", "😀 😄 😊");
setdict(&f->dictlang->dict, "heart", "❤️");
setdict(&f->dictlang->dict, "coffee", "☕️");
setdict(&f->dictlang->dict, "^", "¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁽");
setdict(&f->dictlang->dict, "^0", "");
setdict(&f->dictlang->dict, "_", "₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₍");
setdict(&f->dictlang->dict, "<", "← ≤ ♥ ≠");
setdict(&f->dictlang->dict, "many",
f->dictlang->dict = trienew();
setdict(f->dictlang->dict, "a", "A B");
setdict(f->dictlang->dict, "", "B C");
setdict(f->dictlang->dict, "alpha", "α");
setdict(f->dictlang->dict, "smil", "😀 😄");
setdict(f->dictlang->dict, "smile", "😀 😄");
setdict(f->dictlang->dict, "웃음", "😀 😄 😂");
setdict(f->dictlang->dict, "えがお", "😀 😄 😊");
setdict(f->dictlang->dict, "エガオ", "😀 😄 😊");
setdict(f->dictlang->dict, "heart", "❤️");
setdict(f->dictlang->dict, "coffee", "☕️");
setdict(f->dictlang->dict, "^", "¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁽");
setdict(f->dictlang->dict, "^0", "");
setdict(f->dictlang->dict, "_", "₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₍");
setdict(f->dictlang->dict, "<", "← ≤ ♥ ≠");
setdict(f->dictlang->dict, "many",
"c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12");
init();
im.l = getlang(LangKO);
@@ -989,11 +986,11 @@ emojibegin(Searchfix *f, int showpre)
static void
searchend(Searchfix *f)
{
Hmap *dict;
Trie *dict;
dict = f->dictlang->dict;
f->dictlang->dict = f->dict;
hmapfree(dict);
trieclose(dict);
draindraw(nil);
im = f->im;
search = f->search;
@@ -1079,12 +1076,12 @@ static void
hanjabegin(Searchfix *f, int lang)
{
searchsave(f, LangHANJA);
f->dictlang->dict = hmapalloc(8);
setdict(&f->dictlang->dict, "", "漢 韓");
setdict(&f->dictlang->dict, "", "");
setdict(&f->dictlang->dict, "", "");
setdict(&f->dictlang->dict, "한글", "");
setdict(&f->dictlang->dict, "", "");
f->dictlang->dict = trienew();
setdict(f->dictlang->dict, "", "漢 韓");
setdict(f->dictlang->dict, "", "");
setdict(f->dictlang->dict, "", "");
setdict(f->dictlang->dict, "한글", "");
setdict(f->dictlang->dict, "", "");
init();
im.l = getlang(lang);
}
@@ -1156,15 +1153,14 @@ engine_japanese_candidates(struct ct *t)
{
Dictreq req;
Dictres res;
Hmap *saved;
Trie *saved;
Lang *jp;
Str com, key, shown;
Str com, shown;
jp = getlang(LangJP);
saved = jp->dict;
jp->dict = hmapalloc(8);
key = mkstr("かんじ");
hmapset(&jp->dict, &key, "漢字 幹事", strlen("漢字 幹事"));
jp->dict = trienew();
setdict(jp->dict, "かんじ", "漢字 幹事");
init();
im.l = jp;
sclear(&com);
@@ -1189,7 +1185,7 @@ engine_japanese_candidates(struct ct *t)
checkstr(t, "selected Kanji", "幹事", &com);
cleanup:
newestrequest(&req);
hmapfree(jp->dict);
trieclose(jp->dict);
jp->dict = saved;
}