shithub: gefs

Download patch

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);