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:
@@ -5,26 +5,26 @@ trie_exact_prefix_and_duplicate(struct ct *t)
|
||||
{
|
||||
static const struct {
|
||||
char *key;
|
||||
int klen;
|
||||
int match;
|
||||
char *want;
|
||||
} cases[] = {
|
||||
{ "a", 1, TrieExact, "alpha" },
|
||||
{ "dupli", 5, TriePrefix, nil },
|
||||
{ "duplicate", 9, TrieExact, "second" },
|
||||
{ "missing", 7, TrieMiss, nil },
|
||||
{ nil, 1, TrieMiss, nil },
|
||||
{ "a", -1, TrieMiss, nil },
|
||||
{ "a", TrieExact, "alpha" },
|
||||
{ "ab", TrieExact, "beta" },
|
||||
{ "한", TrieExact, "값" },
|
||||
{ "dupli", TriePrefix, nil },
|
||||
{ "duplicate", TrieExact, "second" },
|
||||
{ "missing", TrieMiss, nil },
|
||||
{ "", TriePrefix, nil },
|
||||
};
|
||||
char *v;
|
||||
Trie *trie;
|
||||
Str key;
|
||||
int i, match, n;
|
||||
|
||||
trie = trieopen("data/trie.map");
|
||||
for(i = 0; i < nelem(cases); i++){
|
||||
v = "unchanged";
|
||||
n = 77;
|
||||
match = trielookup(trie, cases[i].key, cases[i].klen, &v, &n);
|
||||
key = mkstr(cases[i].key);
|
||||
match = trielookup(trie, &key, &v, &n);
|
||||
if(match != cases[i].match){
|
||||
CT_ERRORF(t, "case %d: want match %d, got %d",
|
||||
i, cases[i].match, match);
|
||||
@@ -42,22 +42,28 @@ trie_exact_prefix_and_duplicate(struct ct *t)
|
||||
}
|
||||
|
||||
void
|
||||
trie_optional_outputs_and_invalid_lengths(struct ct *t)
|
||||
trie_put_and_unloaded(struct ct *t)
|
||||
{
|
||||
char *v;
|
||||
Trie *trie;
|
||||
Str key;
|
||||
int n;
|
||||
|
||||
trie = trieopen("data/trie.map");
|
||||
CT_EQ_INT(t, TrieExact, trielookup(trie, "a", 1, &v, nil));
|
||||
CT_CHECK(t, v != nil);
|
||||
CT_EQ_INT(t, TrieExact, trielookup(trie, "a", 1, nil, &n));
|
||||
CT_EQ_INT(t, 5, n);
|
||||
CT_EQ_INT(t, TriePrefix,
|
||||
trielookup(trie, "dupli", 5, nil, nil));
|
||||
CT_EQ_INT(t, TriePrefix, trielookup(trie, nil, 0, &v, &n));
|
||||
CT_EQ_PTR(t, nil, v);
|
||||
CT_EQ_INT(t, 0, n);
|
||||
key = mkstr("k");
|
||||
CT_EQ_INT(t, TrieMiss, trielookup(nil, &key, &v, &n));
|
||||
trie = trienew();
|
||||
CT_EQ_INT(t, TrieMiss, trielookup(trie, &key, &v, &n));
|
||||
trieput(trie, "k", 1, "one two", 7);
|
||||
trieput(trie, "ka", 2, "", 0);
|
||||
if(CT_EQ_INT(t, TrieExact, trielookup(trie, &key, &v, &n)))
|
||||
CT_EQ_MEM(t, "one two", v, 7);
|
||||
key = mkstr("ka");
|
||||
if(CT_EQ_INT(t, TrieExact, trielookup(trie, &key, &v, &n)))
|
||||
CT_EQ_INT(t, 0, n);
|
||||
trieput(trie, "k", 1, "three", 5);
|
||||
key = mkstr("k");
|
||||
if(CT_EQ_INT(t, TrieExact, trielookup(trie, &key, &v, &n)))
|
||||
CT_EQ_MEM(t, "three", v, 5);
|
||||
trieclose(trie);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user