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:
@@ -3,21 +3,20 @@
|
||||
void
|
||||
dictionary_candidates(struct ct *t)
|
||||
{
|
||||
static char malformed[] = { 'o', 'k', ' ', (char)0x80 };
|
||||
char many[512], item[8];
|
||||
char *p;
|
||||
Dictreq req;
|
||||
Dictres res;
|
||||
Hmap *saved;
|
||||
Trie *saved;
|
||||
Lang *lang;
|
||||
Str key;
|
||||
int i;
|
||||
|
||||
lang = getlang(LangJP);
|
||||
saved = lang->dict;
|
||||
lang->dict = hmapalloc(1);
|
||||
lang->dict = trienew();
|
||||
key = mkstr("かな");
|
||||
hmapset(&lang->dict, &key, " 候補1 かな 候補2 ",
|
||||
trieput(lang->dict, "かな", strlen("かな"), " 候補1 かな 候補2 ",
|
||||
strlen(" 候補1 かな 候補2 "));
|
||||
memset(&req, 0, sizeof req);
|
||||
req.key = key;
|
||||
@@ -42,7 +41,7 @@ dictionary_candidates(struct ct *t)
|
||||
p += strlen(item);
|
||||
}
|
||||
*p = '\0';
|
||||
hmapset(&lang->dict, &key, many, strlen(many));
|
||||
trieput(lang->dict, "key", 3, many, strlen(many));
|
||||
req.key = key;
|
||||
req.pre = mkstr("preedit-two");
|
||||
req.seq = 29;
|
||||
@@ -54,13 +53,8 @@ dictionary_candidates(struct ct *t)
|
||||
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]);
|
||||
key = mkstr("malformed");
|
||||
hmapset(&lang->dict, &key, malformed, sizeof malformed);
|
||||
req.key = key;
|
||||
dictlookup(&req, &res);
|
||||
CT_EQ_INT(t, 0, res.nkouho);
|
||||
cleanup:
|
||||
hmapfree(lang->dict);
|
||||
trieclose(lang->dict);
|
||||
lang->dict = saved;
|
||||
}
|
||||
|
||||
@@ -77,13 +71,13 @@ dictionary_misses_clear_result(struct ct *t)
|
||||
};
|
||||
Dictreq req;
|
||||
Dictres res;
|
||||
Hmap *saved;
|
||||
Trie *saved;
|
||||
Lang *lang;
|
||||
int i;
|
||||
|
||||
lang = getlang(LangJP);
|
||||
saved = lang->dict;
|
||||
lang->dict = hmapalloc(1);
|
||||
lang->dict = trienew();
|
||||
for(i = 0; i < nelem(cases); i++){
|
||||
memset(&res, 0xa5, sizeof res);
|
||||
req.key = mkstr(cases[i].key);
|
||||
@@ -98,7 +92,7 @@ dictionary_misses_clear_result(struct ct *t)
|
||||
CT_EQ_UINT(t, 0xf00d0000U + i, res.seq);
|
||||
checkstr(t, cases[i].name, cases[i].pre, &res.key);
|
||||
}
|
||||
hmapfree(lang->dict);
|
||||
trieclose(lang->dict);
|
||||
lang->dict = saved;
|
||||
}
|
||||
|
||||
@@ -107,15 +101,15 @@ dictionary_emoji_identity(struct ct *t)
|
||||
{
|
||||
Dictreq req;
|
||||
Dictres res;
|
||||
Hmap *saved;
|
||||
Trie *saved;
|
||||
Lang *lang;
|
||||
Str key;
|
||||
|
||||
lang = getlang(LangEMOJI);
|
||||
saved = lang->dict;
|
||||
lang->dict = hmapalloc(2);
|
||||
lang->dict = trienew();
|
||||
key = mkstr("é");
|
||||
hmapset(&lang->dict, &key, "é", strlen("é"));
|
||||
trieput(lang->dict, "é", strlen("é"), "é", strlen("é"));
|
||||
memset(&req, 0, sizeof req);
|
||||
req.key = key;
|
||||
req.pre = key;
|
||||
@@ -124,6 +118,6 @@ dictionary_emoji_identity(struct ct *t)
|
||||
dictlookup(&req, &res);
|
||||
if(CT_EQ_INT(t, 1, res.nkouho))
|
||||
checkstr(t, "emoji identity candidate", "é", &res.kouho[0]);
|
||||
hmapfree(lang->dict);
|
||||
trieclose(lang->dict);
|
||||
lang->dict = saved;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user