ref: 2257b8ac4a218ec0babba308f5a19adc17718f8f
parent: 0ce6791400f1db6585ec089570b7f015d6c034ce
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Oct 27 16:02:03 EDT 2023
tree: fix scans in subtle edge case if the value was the last value in a block, and there were mulitple queued messages to a value, and we did a btenter that touched these, then we might not walk past all the messages we wanted to; fix this, and clean up the code a bit.
--- a/tree.c
+++ b/tree.c
@@ -1390,9 +1390,9 @@
{
int i, same;
Scanp *p;
+ Msg m, c;
Bptr bp;
Blk *b;
- Msg m;
Kvp v;
if(s->done)
@@ -1414,8 +1414,8 @@
p[i].bi++;
/* scan past repeated messages */
while(p[i].bi < p[i].b->nbuf){
- getmsg(p[i].b, p[i].bi, &m);
- if(keycmp(&m, &s->kv) >= 0)
+ getmsg(p[i].b, p[i].bi, &c);
+ if(keycmp(&m, &c) != 0)
break;
p[i].bi++;
}
@@ -1434,20 +1434,20 @@
char *
btnext(Scan *s, Kvp *r)
{
- int i, j, h, ok, start, srcbuf;
+ int i, j, h, ok, start, bufsrc;
Scanp *p;
Msg m, n;
Bptr bp;
Kvp kv;
- /* load up the correct blocks for the scan */
Again:
p = s->path;
h = s->ht;
start = h;
- srcbuf = -1;
+ bufsrc = -1;
if(s->done)
return nil;
+ /* load up the correct blocks for the scan */
for(i = h-1; i >= 0; i--){
if(p[i].b != nil
&&(p[i].vi < p[i].b->nval || p[i].bi < p[i].b->nbuf))
@@ -1474,12 +1474,12 @@
}
/* find the minimum key along the path up */
- m.op = Onop;
+ m.op = Oinsert;
getval(p[h-1].b, p[h-1].vi, &m);
}else{
getmsg(p[start-1].b, p[start-1].bi, &m);
assert(m.op == Oinsert);
- srcbuf = start-1;
+ bufsrc = start-1;
}
for(i = h-2; i >= 0; i--){
@@ -1487,7 +1487,7 @@
continue;
getmsg(p[i].b, p[i].bi, &n);
if(keycmp(&n, &m) < 0){
- srcbuf = i;
+ bufsrc = i;
m = n;
}
}
@@ -1499,10 +1499,10 @@
/* scan all messages applying to the message */
ok = 1;
cpkvp(r, &m, s->kvbuf, sizeof(s->kvbuf));
- if(srcbuf == -1)
+ if(bufsrc == -1)
p[h-1].vi++;
else
- p[srcbuf].bi++;
+ p[bufsrc].bi++;
for(i = h-2; i >= 0; i--){
for(j = p[i].bi; j < p[i].b->nbuf; j++){
getmsg(p[i].b, j, &m);