libavl: lookup can return the closest match

This commit is contained in:
spew 2017-04-22 13:59:37 -05:00
parent f2b7f24e4e
commit 9cf5198145
9 changed files with 34 additions and 25 deletions

View file

@ -22,7 +22,7 @@ mtreeisdup(Mailbox *mb, Message *m)
return 0;
memset(&t, 0, sizeof t);
t.m = m;
if(avllookup(mb->mtree, &t))
if(avllookup(mb->mtree, &t, 0))
return 1;
return 0;
}
@ -36,7 +36,7 @@ mtreefind(Mailbox *mb, uchar *digest)
m0.digest = digest;
memset(&t, 0, sizeof t);
t.m = &m0;
if(p = (Mtree*)avllookup(mb->mtree, &t))
if(p = (Mtree*)avllookup(mb->mtree, &t, 0))
return p->m;
return nil;
}
@ -65,7 +65,7 @@ mtreedelete(Mailbox *mb, Message *m)
if(m->deleted & ~Deleted){
if(m->digest == nil)
return;
p = (Mtree*)avllookup(mb->mtree, &t);
p = (Mtree*)avllookup(mb->mtree, &t, 0);
if(p == nil || p->m != m)
return;
p = (Mtree*)avldelete(mb->mtree, &t);

View file

@ -25,7 +25,7 @@ fstreefind(Box *mb, int id)
memset(&t, 0, sizeof t);
m0.id = id;
t.m = &m0;
if(p = (Fstree*)avllookup(mb->fstree, &t))
if(p = (Fstree*)avllookup(mb->fstree, &t, 0))
return p->m;
return nil;
}

View file

@ -100,7 +100,7 @@ rdimp(Biobuf *b, Box *box)
memset(&t, 0, sizeof t);
m0.info[Idigest] = f[0];
t.m = &m0;
p = (Mtree*)avllookup(mtree, &t);
p = (Mtree*)avllookup(mtree, &t, 0);
if(p){
m = p->m;
if(m->uid && m->uid != u){

View file

@ -51,7 +51,7 @@ havevisited(uchar score[VtScoreSize], int type)
return 0;
memmove(a.score, score, VtScoreSize);
a.type = type;
return avllookup(scoretree, &a) != nil;
return avllookup(scoretree, &a, 0) != nil;
}
static void

View file

@ -6,9 +6,9 @@
int extraproc = -1, throttle;
static QLock* golock;
static Rendez* gorend;
static int* go;
static QLock *golock;
static Rendez *gorend;
static int *go;
static QLock runninglock;
static Rendez runningrend;

View file

@ -413,7 +413,7 @@ sym(char *name)
Sym *s, l;
l.name = name;
s = (Sym*)avllookup(syms, &l);
s = (Sym*)avllookup(syms, &l, 0);
if(s != nil)
return s;

View file

@ -4,10 +4,6 @@
/* See Knuth Volume 3, 6.2.3 */
Avl *avllookup(Avltree*, Avl*);
Avl *avldelete(Avltree*, Avl*);
Avl *avlinsert(Avltree*, Avl*);
Avltree*
avlcreate(int (*cmp)(Avl*, Avl*))
{
@ -16,32 +12,42 @@ avlcreate(int (*cmp)(Avl*, Avl*))
t = malloc(sizeof(*t));
if(t == nil)
return nil;
return avlinit(t, cmp);
}
Avltree*
avlinit(Avltree *t, int (*cmp)(Avl*, Avl*))
{
t->cmp = cmp;
t->root = nil;
return t;
}
Avl*
avllookup(Avltree *t, Avl *k)
avllookup(Avltree *t, Avl *k, int d)
{
Avl *h;
Avl *h, *n;
int c;
n = nil;
h = t->root;
while(h != nil){
c = (t->cmp)(k, h);
if(c < 0){
if(d > 0)
n = h;
h = h->c[0];
continue;
}
if(c > 0){
if(d < 0)
n = h;
h = h->c[1];
continue;
}
return h;
}
return nil;
return n;
}
static int insert(int (*)(Avl*, Avl*), Avl*, Avl**, Avl*, Avl**);