ref: 0ce6791400f1db6585ec089570b7f015d6c034ce
parent: 093c8160b677469b68ba957a2c1f6c9aa093e9d2
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Oct 27 10:33:53 EDT 2023
fs: make iterating a tree unaffected by mutations
--- a/check.c
+++ b/check.c
@@ -200,7 +200,7 @@
return 0;
}
while(1){
- if((e = btnext(&fs->snap, &s, &s.kv)) != nil){
+ if((e = btnext(&s, &s.kv)) != nil){
fprint(fd, "invalid snapshot tree: %s\n", e);
ok = 0;
break;
@@ -227,5 +227,6 @@
ok = 0;
dropblk(b);
}
+ btexit(&s);
return ok;
}
--- a/cons.c
+++ b/cons.c
@@ -208,9 +208,9 @@
goto Out;
}
while(1){
- if((e = btnext(t, &s, &kv)) != nil){
+ if((e = btnext(&s, &kv)) != nil){
fprint(fd, "scan failed: %s\n", e);
- btexit(t, &s);
+ btexit(&s);
goto Out;
}
if(s.done)
@@ -217,7 +217,7 @@
break;
fprint(fd, "%P\n", &kv);
}
- btexit(t, &s);
+ btexit(&s);
}
Out:
closesnap(t);
--- a/dat.h
+++ b/dat.h
@@ -665,6 +665,7 @@
char done;
char overflow;
char present;
+ int ht;
Kvp kv;
Key pfx;
char kvbuf[Kvmax];
--- a/dump.c
+++ b/dump.c
@@ -410,11 +410,11 @@
btnewscan(&s, pfx, sz);
if((e = btenter(&fs->snap, &s)) != nil){
fprint(fd, "scan: %s\n", e);
- btexit(&fs->snap, &s);
+ btexit(&s);
return;
}
while(1){
- if((e = btnext(&fs->snap, &s, &s.kv)) != nil){
+ if((e = btnext(&s, &s.kv)) != nil){
fprint(fd, "scan: %s\n", e);
break;
}
@@ -422,7 +422,7 @@
break;
fprint(fd, "label: %P\n", &s.kv);
}
- btexit(&fs->snap, &s);
+ btexit(&s);
}
/* dump the snapshots */
@@ -436,11 +436,11 @@
btnewscan(&s, pfx, sz);
if((e = btenter(&fs->snap, &s)) != nil){
fprint(fd, "scan: %s\n", e);
- btexit(&fs->snap, &s);
+ btexit(&s);
return;
}
while(1){
- if((e = btnext(&fs->snap, &s, &s.kv)) != nil){
+ if((e = btnext(&s, &s.kv)) != nil){
fprint(fd, "scan: %s\n", e);
break;
}
@@ -453,7 +453,7 @@
}
showtreeroot(fd, &t);
}
- btexit(&fs->snap, &s);
+ btexit(&s);
}
void
@@ -477,11 +477,11 @@
btnewscan(&s, pfx, sz);
if((err = btenter(&fs->snap, &s)) != nil){
fprint(fd, "scan: %s\n", err);
- btexit(&fs->snap, &s);
+ btexit(&s);
return;
}
while(1){
- if((e = btnext(&fs->snap, &s, &s.kv)) != nil){
+ if((e = btnext(&s, &s.kv)) != nil){
fprint(fd, "scan: %s\n", e);
break;
}
@@ -503,7 +503,7 @@
dropblk(b);
}
}
- btexit(&fs->snap, &s);
+ btexit(&s);
}
void
--- a/fns.h
+++ b/fns.h
@@ -66,6 +66,7 @@
char* updatesnap(Tree**, Tree*, char*);
char* labelsnap(Tree*, char*);
char* delsnap(Tree*, vlong, char*);
+char* freedl(Dlist*, int);
Tree* opensnap(char*);
vlong successor(vlong);
@@ -92,8 +93,8 @@
char* btlookup(Tree*, Key*, Kvp*, char*, int);
void btnewscan(Scan*, char*, int);
char* btenter(Tree*, Scan*);
-char* btnext(Tree*, Scan*, Kvp*);
-void btexit(Tree*, Scan*);
+char* btnext(Scan*, Kvp*);
+void btexit(Scan*);
int checkflag(Blk *b, int);
void setflag(Blk *b, int);
--- a/fs.c
+++ b/fs.c
@@ -1589,12 +1589,12 @@
btnewscan(&s, pfx, sizeof(pfx));
if((e = btenter(t, &s)) != nil)
goto Out;
- if((e = btnext(t, &s, &s.kv)) != nil)
+ if((e = btnext(&s, &s.kv)) != nil)
goto Out;
if(!s.done)
e = Enempty;
Out:
- btexit(t, &s);
+ btexit(&s);
return e;
}
@@ -1813,7 +1813,7 @@
if((e = btenter(&fs->snap, s)) != nil)
return e;
while(1){
- if((e = btnext(&fs->snap, s, &s->kv)) != nil)
+ if((e = btnext(s, &s->kv)) != nil)
return e;
if(s->done)
break;
@@ -1827,7 +1827,7 @@
p += ns;
n -= ns;
}
- btexit(&fs->snap, s);
+ btexit(s);
r->count = p - r->data;
return nil;
}
@@ -1874,7 +1874,7 @@
if((e = btenter(t, s)) != nil)
return e;
while(1){
- if((e = btnext(t, s, &s->kv)) != nil)
+ if((e = btnext(s, &s->kv)) != nil)
return e;
if(s->done)
break;
@@ -1885,7 +1885,7 @@
p += ns;
n -= ns;
}
- btexit(t, s);
+ btexit(s);
r->count = p - r->data;
return nil;
}
--- a/snap.c
+++ b/snap.c
@@ -145,7 +145,7 @@
fs->dlhead = dl;
}
-static char*
+char*
freedl(Dlist *dl, int docontents)
{
Bptr bp, fb;
@@ -242,19 +242,19 @@
btnewscan(&s, pfx, sizeof(pfx));
if((e = btenter(&fs->snap, &s)) != nil)
goto Err;
- if((e = btnext(&fs->snap, &s, &s.kv)) != nil)
+ if((e = btnext(&s, &s.kv)) != nil)
goto Err;
if(!s.done)
kv2link(&s.kv, &id, &succ);
- if((e = btnext(&fs->snap, &s, &s.kv)) != nil)
+ if((e = btnext(&s, &s.kv)) != nil)
goto Err;
if(!s.done)
sysfatal("multiple successors in cleanup");
- btexit(&fs->snap, &s);
+ btexit(&s);
return succ;
Err:
fprint(2, "error getting snap successor: %s", e);
- btexit(&fs->snap, &s);
+ btexit(&s);
return -1;
}
@@ -272,7 +272,7 @@
if((e = btenter(&fs->snap, &s)) != nil)
return e;
while(1){
- if((e = btnext(&fs->snap, &s, &s.kv)) != nil)
+ if((e = btnext(&s, &s.kv)) != nil)
break;
if(s.done)
break;
@@ -295,7 +295,7 @@
if(e != nil)
break;
}
- btexit(&fs->snap, &s);
+ btexit(&s);
return e;
}
--- a/tree.c
+++ b/tree.c
@@ -1397,6 +1397,7 @@
if(s->done)
return nil;
+ s->ht = t->ht;
if((s->path = calloc(t->ht, sizeof(Scanp))) == nil)
return Enomem;
p = s->path;
@@ -1431,7 +1432,7 @@
}
char *
-btnext(Tree *t, Scan *s, Kvp *r)
+btnext(Scan *s, Kvp *r)
{
int i, j, h, ok, start, srcbuf;
Scanp *p;
@@ -1442,7 +1443,7 @@
/* load up the correct blocks for the scan */
Again:
p = s->path;
- h = t->ht;
+ h = s->ht;
start = h;
srcbuf = -1;
if(s->done)
@@ -1517,11 +1518,11 @@
}
void
-btexit(Tree *t, Scan *s)
+btexit(Scan *s)
{
int i;
- for(i = 0; i < t->ht; i++)
+ for(i = 0; i < s->ht; i++)
dropblk(s->path[i].b);
free(s->path);
}