ref: 57a0e2453cc74df81d1e2ed2ecd256e7ab1f322f
parent: dfd53a7c1835c5caa8a56bbe74f8f9977bb08add
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Jan 9 19:39:57 EST 2022
tree: fix directory listing by fixing prefix scans on values We were doing prefix scans on values with a binary search that didn't return the first value. Now our binary search returns the first value, so we grab the right prefix.
--- a/blk.c
+++ b/blk.c
@@ -322,6 +322,8 @@
p = a->tail->data + a->tail->logsz;
PBIT64(p, o);
finalize(a->tail);
+ if(a->tail->bp.addr == a->head.addr)
+ a->head = a->tail->bp;
if(syncblk(a->tail) == -1)
return -1;
putblk(a->tail);
--- a/tree.c
+++ b/tree.c
@@ -178,20 +178,30 @@
static int
bufsearch(Blk *b, Key *k, Msg *m, int *same)
{
- int lo, hi, mid, r;
+ int lo, hi, ri, mid, r;
Msg cmp;
- r = -1;
+ ri = -1;
lo = 0;
- hi = b->nbuf;
- while(lo < hi){
+ hi = b->nbuf-1;
+ while(lo <= hi){
mid = (hi + lo) / 2;
getmsg(b, mid, &cmp);
r = keycmp(k, &cmp);
- if(r < 0)
- hi = mid;
- else
- lo = mid + 1;
+ switch(r){
+ case -1:
+ hi = mid-1;
+ break;
+ case 0:
+ if(same != nil)
+ *same = 1;
+ ri = mid;
+ hi = mid-1;
+ break;
+ case 1:
+ lo = mid+1;
+ break;
+ }
}
/*
* we can have duplicate messages, and we
@@ -198,47 +208,52 @@
* want to point to the first of them:
* scan backwards.
*/
- lo--;
- for(; lo > 0; lo--){
- getmsg(b, lo-1, &cmp);
- if(keycmp(k, &cmp) != 0)
- break;
- }
- if(lo >= 0){
- getmsg(b, lo, m);
- r = keycmp(k, m);
- }
- if(same != nil)
- *same = (r == 0);
- return lo;
+ *same = 0;
+ if(ri == -1)
+ ri = lo-1;
+ else
+ *same = 1;
+ if(ri >= 0)
+ getmsg(b, ri, m);
+ return ri;
}
int
blksearch(Blk *b, Key *k, Kvp *rp, int *same)
{
- int lo, hi, mid, r;
+ int lo, hi, ri, mid, r;
Kvp cmp;
- r = -1;
+ ri = -1;
lo = 0;
- hi = b->nval;
- while(lo < hi){
+ hi = b->nval-1;
+ while(lo <= hi){
mid = (hi + lo) / 2;
getval(b, mid, &cmp);
r = keycmp(k, &cmp);
- if(r < 0)
- hi = mid;
- else
- lo = mid + 1;
+ switch(r){
+ case -1:
+ hi = mid-1;
+ break;
+ case 0:
+ if(same != nil)
+ *same = 1;
+ ri = mid;
+ hi = mid-1;
+ break;
+ case 1:
+ lo = mid+1;
+ break;
+ }
}
- lo--;
- if(lo >= 0){
- getval(b, lo, rp);
- r = keycmp(k, rp);
- }
- if(same != nil)
- *same = (r == 0);
- return lo;
+ *same = 0;
+ if(ri == -1)
+ ri = lo-1;
+ else
+ *same = 1;
+ if(ri >= 0)
+ getval(b, ri, rp);
+ return ri;
}
int
@@ -1265,7 +1280,7 @@
ok = 0;
p[0] = refblk(b);
for(i = 1; i < h; i++){
- if(blksearch(p[i-1], k, r, nil) == -1)
+ if(blksearch(p[i-1], k, r, &same) == -1)
break;
bp = getptr(r, nil);
if((p[i] = getblk(bp, 0)) == nil){
@@ -1351,9 +1366,6 @@
p[0].b = b;
for(i = 0; i < s->root.ht; i++){
p[i].vi = blksearch(b, &s->kv, &v, &same);
- if(p[i].vi == -1 || (p[i].vi+1 < b->nval && !same && b->type == Tleaf)){
- getval(b, ++p[i].vi, &v);
- }
if(b->type == Tpivot){
p[i].bi = bufsearch(b, &s->kv, &m, &same);
if(p[i].bi == -1 || !same)
@@ -1362,9 +1374,9 @@
if((b = getblk(bp, 0)) == nil)
return Eio;
p[i+1].b = b;
- }
+ }else if(p[i].vi == -1 || !same)
+ p[i].vi++;
}
- assert(i == s->root.ht);
return nil;
}