dict: lookups take a trie; a prefix search is its own function; no self-key rule
dictlookup took a Lang for two reasons that were not its business: to know whether to walk below the key (the emoji dictionary) and to drop a candidate equal to the key except there. No dictionary lists its key among its candidates — the rule was left from a first version that put the reading first itself — so it goes, and the walk is dictprefix(), called by the emoji search alone.
This commit is contained in:
46
dict.c
46
dict.c
@@ -1,13 +1,9 @@
|
||||
#include "dat.h"
|
||||
#include "fn.h"
|
||||
|
||||
/*
|
||||
* Appends the space-separated words of a node's entry to out[], up to
|
||||
* max: its candidates, minus the key itself, except in the emoji
|
||||
* dictionary, where a query may name its own answer.
|
||||
*/
|
||||
/* Appends the space-separated words of a node's entry to out[], up to max. */
|
||||
static int
|
||||
words(Lang *l, Str *key, Tnode *nd, Str *out, int n, int max)
|
||||
words(Tnode *nd, Str *out, int n, int max)
|
||||
{
|
||||
char *p, *e, *sp;
|
||||
Str tmp;
|
||||
@@ -22,8 +18,7 @@ words(Lang *l, Str *key, Tnode *nd, Str *out, int n, int max)
|
||||
sp = p;
|
||||
while(p < e && *p != ' ')
|
||||
p++;
|
||||
if(sinit(&tmp, sp, p - sp) && tmp.n > 0 &&
|
||||
(l->lang == LangEMOJI || scmp(&tmp, key) != 0))
|
||||
if(sinit(&tmp, sp, p - sp) && tmp.n > 0)
|
||||
out[n++] = tmp;
|
||||
}
|
||||
return n;
|
||||
@@ -31,33 +26,40 @@ words(Lang *l, Str *key, Tnode *nd, Str *out, int n, int max)
|
||||
|
||||
/* The entries at and below a node, in the dictionary's order. */
|
||||
static int
|
||||
below(Lang *l, Str *key, int ni, Str *out, int n, int max)
|
||||
below(Trie *t, int ni, Str *out, int n, int max)
|
||||
{
|
||||
Tnode *nd;
|
||||
int ci;
|
||||
|
||||
nd = &l->dict->nodes[ni];
|
||||
n = words(l, key, nd, out, n, max);
|
||||
for(ci = nd->child; ci >= 0 && n < max; ci = l->dict->nodes[ci].sibling)
|
||||
n = below(l, key, ci, out, n, max);
|
||||
nd = &t->nodes[ni];
|
||||
n = words(nd, out, n, max);
|
||||
for(ci = nd->child; ci >= 0 && n < max; ci = t->nodes[ci].sibling)
|
||||
n = below(t, ci, out, n, max);
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fills out[] with up to max candidates for key. The emoji dictionary is
|
||||
* searched by prefix, the key's own entry first; the others exactly.
|
||||
*/
|
||||
/* Fills out[] with up to max candidates for key: the words of its entry. */
|
||||
int
|
||||
dictlookup(Lang *l, Str *key, Str *out, int max)
|
||||
dictlookup(Trie *t, Str *key, Str *out, int max)
|
||||
{
|
||||
int ni;
|
||||
|
||||
ni = key->n == 0 ? -1 : trienode(l->dict, key);
|
||||
ni = key->n == 0 ? -1 : trienode(t, key);
|
||||
if(ni < 0)
|
||||
return 0;
|
||||
if(l->lang == LangEMOJI)
|
||||
return below(l, key, ni, out, 0, max);
|
||||
return words(l, key, &l->dict->nodes[ni], out, 0, max);
|
||||
return words(&t->nodes[ni], out, 0, max);
|
||||
}
|
||||
|
||||
/* As dictlookup, for every entry key is a prefix of, key's own first. */
|
||||
int
|
||||
dictprefix(Trie *t, Str *key, Str *out, int max)
|
||||
{
|
||||
int ni;
|
||||
|
||||
ni = key->n == 0 ? -1 : trienode(t, key);
|
||||
if(ni < 0)
|
||||
return 0;
|
||||
return below(t, ni, out, 0, max);
|
||||
}
|
||||
|
||||
static Trie*
|
||||
|
||||
Reference in New Issue
Block a user