engine: look dictionaries up synchronously

The dictionary thread ran in imthread's own proc, so a lookup could
only start once the engine blocked, and it was a trie probe anyway; the
emoji and Hanja searches already called dictlookup directly. The
request/result channels, sequence numbers, staleness checks and the
second draw per Japanese key are gone; dictqjp fills the candidates
in place. Emit.dict and Lang.dictq only ever triggered lookups for
Vietnamese, which has no dictionary. dictlookup(Lang*, key, out, max)
returns the count. The Hanja lookup no longer pre-checks for a single
syllable; a reading either has an entry or it does not.
This commit is contained in:
2026-08-16 16:02:09 +09:00
parent ebcec3af6b
commit abaea77248
10 changed files with 123 additions and 473 deletions

View File

@@ -5,33 +5,22 @@ dictionary_candidates(struct ct *t)
{
char many[512], item[8];
char *p;
Dictreq req;
Dictres res;
Str kouho[Maxkouho], key;
Trie *saved;
Lang *lang;
Str key;
int i;
int i, n;
lang = getlang(LangJP);
saved = lang->dict;
lang->dict = trienew();
key = mkstr("かな");
trieput(lang->dict, "かな", strlen("かな"), " 候補1 かな 候補2 ",
strlen(" 候補1 かな 候補2 "));
memset(&req, 0, sizeof req);
req.key = key;
req.pre = mkstr("preedit-one");
req.lang = LangJP;
req.seq = 17;
dictlookup(&req, &res);
if(!CT_EQ_INT(t, 2, res.nkouho))
goto cleanup;
CT_EQ_INT(t, LangJP, res.lang);
CT_EQ_UINT(t, 17, res.seq);
CT_EQ_INT(t, 0, scmp(&req.pre, &res.key));
checkstr(t, "candidate 1", "候補1", &res.kouho[0]);
checkstr(t, "candidate 2", "候補2", &res.kouho[1]);
key = mkstr("key");
key = mkstr("かな");
n = dictlookup(lang, &key, kouho, Maxkouho);
if(CT_EQ_INT(t, 2, n)){
checkstr(t, "candidate 1", "候補1", &kouho[0]);
checkstr(t, "candidate 2", "候補2", &kouho[1]);
}
p = many;
for(i = 0; i < Maxkouho+1; i++){
snprint(item, sizeof item, "c%02d", i);
@@ -42,56 +31,32 @@ dictionary_candidates(struct ct *t)
}
*p = '\0';
trieput(lang->dict, "key", 3, many, strlen(many));
req.key = key;
req.pre = mkstr("preedit-two");
req.seq = 29;
dictlookup(&req, &res);
if(!CT_EQ_INT(t, Maxkouho, res.nkouho))
goto cleanup;
CT_EQ_INT(t, LangJP, res.lang);
CT_EQ_UINT(t, 29, res.seq);
CT_EQ_INT(t, 0, scmp(&req.pre, &res.key));
checkstr(t, "first capped candidate", "c00", &res.kouho[0]);
checkstr(t, "last capped candidate", "c31", &res.kouho[31]);
cleanup:
key = mkstr("key");
n = dictlookup(lang, &key, kouho, Maxkouho);
if(CT_EQ_INT(t, Maxkouho, n)){
checkstr(t, "first capped candidate", "c00", &kouho[0]);
checkstr(t, "last capped candidate", "c31", &kouho[31]);
}
CT_EQ_INT(t, 3, dictlookup(lang, &key, kouho, 3));
trieclose(lang->dict);
lang->dict = saved;
}
void
dictionary_misses_clear_result(struct ct *t)
dictionary_misses(struct ct *t)
{
static const struct {
char *name;
char *key;
char *pre;
} cases[] = {
{ "empty key", "", "empty-preedit" },
{ "missing key", "missing", "missing-preedit" },
};
Dictreq req;
Dictres res;
Str kouho[Maxkouho], key;
Trie *saved;
Lang *lang;
int i;
lang = getlang(LangJP);
saved = lang->dict;
lang->dict = trienew();
for(i = 0; i < nelem(cases); i++){
memset(&res, 0xa5, sizeof res);
req.key = mkstr(cases[i].key);
req.pre = mkstr(cases[i].pre);
req.lang = LangJP;
req.seq = 0xf00d0000U + i;
dictlookup(&req, &res);
if(res.nkouho != 0)
CT_ERRORF(t, "%s: want 0 candidates, got %d",
cases[i].name, res.nkouho);
CT_EQ_INT(t, LangJP, res.lang);
CT_EQ_UINT(t, 0xf00d0000U + i, res.seq);
checkstr(t, cases[i].name, cases[i].pre, &res.key);
}
key = mkstr("");
CT_EQ_INT(t, 0, dictlookup(lang, &key, kouho, Maxkouho));
key = mkstr("missing");
CT_EQ_INT(t, 0, dictlookup(lang, &key, kouho, Maxkouho));
CT_EQ_INT(t, 0, dictlookup(getlang(LangKO), &key, kouho, Maxkouho));
trieclose(lang->dict);
lang->dict = saved;
}
@@ -99,25 +64,17 @@ dictionary_misses_clear_result(struct ct *t)
void
dictionary_emoji_identity(struct ct *t)
{
Dictreq req;
Dictres res;
Str kouho[Maxkouho], key;
Trie *saved;
Lang *lang;
Str key;
lang = getlang(LangEMOJI);
saved = lang->dict;
lang->dict = trienew();
key = mkstr("é");
trieput(lang->dict, "é", strlen("é"), "é", strlen("é"));
memset(&req, 0, sizeof req);
req.key = key;
req.pre = key;
req.lang = LangEMOJI;
req.seq = 0;
dictlookup(&req, &res);
if(CT_EQ_INT(t, 1, res.nkouho))
checkstr(t, "emoji identity candidate", "é", &res.kouho[0]);
key = mkstr("é");
if(CT_EQ_INT(t, 1, dictlookup(lang, &key, kouho, Maxkouho)))
checkstr(t, "emoji identity candidate", "é", &kouho[0]);
trieclose(lang->dict);
lang->dict = saved;
}