ref: 32de1f7a58b7b3a8476d1ceb3532e3317004a95c
parent: 62391489c0ccd5bb01a860b50523eb99905241d1
author: Ori Bernstein <[email protected]>
date: Thu Jan 4 13:16:04 EST 2024
tree: clean up code
--- a/tree.c
+++ b/tree.c
@@ -463,7 +463,7 @@
updateleaf(Tree *t, Path *up, Path *p)
{
char buf[Msgmax];
- int i, j, ok, full, spc;
+ int i, j, c, ok, full, spc;
Blk *b, *n;
Bptr bp;
Msg m;
@@ -484,50 +484,62 @@
spc = Leafspc - blkfill(b);
n = newblk(t, b->type, 0);
assert(i >= 0 && j >= 0);
- while(i < b->nval){
- ok = 1;
- getval(p->b, i, &v);
- switch(pullmsg(up, j, &v, &m, &full, spc)){
+ while(i < b->nval || j < up->hi){
+ if(i >= b->nval)
+ c = 1;
+ else{
+ c = -1;
+ getval(p->b, i, &v);
+ if(j < up->hi){
+ if(up->ins != nil)
+ m = up->ins[j];
+ else
+ getmsg(up->b, j, &m);
+ if(msgsz(&m) <= spc)
+ c = keycmp(&v, &m);
+ else
+ full = 1;
+ }
+ }
+ switch(c){
+ /* Value before message: just copy value */
case -1:
- setval(n, &v);
i++;
+ setval(n, &v);
break;
- case 1:
- /*
- * new values must always start as
- * an insertion, mutations come after.
- */
- if(m.op == Oclearb || m.op == Oclobber)
- ok = 0;
- else if(m.op != Oinsert)
- fatal("%d(/%d), %d: %M not insert\n", i, b->nval, j, &m);
- cpkvp(&v, &m, buf, sizeof(buf));
- spc -= valsz(&m);
- goto Copy;
+ /* Value merges with message sequence */
case 0:
i++;
- if(m.op != Oinsert)
- cpkvp(&v, &v, buf, sizeof(buf));
+ j++;
+ cpkvp(&v, &v, buf, sizeof(buf));
+ ok = apply(&v, &m, buf, sizeof(buf));
+ if(ok && m.op == Oclearb){
+ bp = unpackbp(v.v, v.nv);
+ freeblk(t, nil, bp);
+ }
+ goto Copyloop;
+ /* Message before value: Insert message sequence */
+ case 1:
+ j++;
+ cpkvp(&v, &m, buf, sizeof(buf));
+ ok = 0;
+ if(m.op != Oclearb && m.op != Oclobber){
+ spc -= valsz(&m);
+ p->pullsz += msgsz(&m);
+ ok = 1;
+ }
+ goto Copyloop;
+ Copyloop:
while(j < up->hi){
- /*
- * If a file is truncated multiple times,
- * we can end up with duplicate Oclearb
- * messages in the buffer.
- *
- * These Oclearb doublings will leave
- * v.nv with a length of 0, so we can
- * and should skip those
- */
- if(m.op == Oclearb && v.nv != 0){
+ if(pullmsg(up, j, &v, &m, &full, spc) != 0)
+ break;
+ if(ok && m.op == Oclearb){
bp = unpackbp(v.v, v.nv);
freeblk(t, nil, bp);
}
+ p->pullsz += msgsz(&m);
ok = apply(&v, &m, buf, sizeof(buf));
- Copy:
j++;
- p->pullsz += msgsz(&m);
- if(j >= up->hi || pullmsg(up, j, &v, &m, &full, spc) != 0)
- break;
}
if(ok)
setval(n, &v);
@@ -534,24 +546,6 @@
break;
}
}
- while(j < up->hi) {
- /* can't fail */
- pullmsg(up, j++, nil, &m, &full, spc);
- ok = 1;
- cpkvp(&v, &m, buf, sizeof(buf));
- p->pullsz += msgsz(&m);
- if(m.op == Oclearb || m.op == Oclobber)
- continue;
- if(m.op != Oinsert)
- fatal("%d(/%d), %d: %M not insert\n", i, b->nval, j, &m);
- while(pullmsg(up, j, &v, &m, &full, spc) == 0){
- ok = apply(&v, &m, buf, sizeof(buf));
- p->pullsz += msgsz(&m);
- j++;
- }
- if(ok)
- setval(n, &v);
- }
p->npull = (j - up->lo);
p->nl = n;
}
@@ -637,9 +631,10 @@
splitleaf(Tree *t, Path *up, Path *p, Kvp *mid)
{
char buf[Msgmax];
+ Blk *b, *d, *l, *r;
int full, copied, spc, ok, halfsz;
int i, j, c;
- Blk *b, *d, *l, *r;
+ Bptr bp;
Msg m;
Kvp v;
@@ -682,38 +677,47 @@
spc = Leafspc - (halfsz + Msgmax);
getval(b, i, mid);
}
- ok = 1;
getval(b, i, &v);
c = pullmsg(up, j, &v, &m, &full, spc);
switch(c){
case -1:
+ i++;
setval(d, &v);
copied += valsz(&v);
- i++;
break;
- case 1:
- /*
- * new values must always start as
- * an insertion, mutations come after.
- */
- if(m.op == Oclearb || m.op == Oclobber)
- ok = 0;
- else if(m.op != Oinsert)
- fatal("%d(/%d), %d: expected insert, got %M\n", i, b->nval, j, &m);
- cpkvp(&v, &m, buf, sizeof(buf));
- spc -= valsz(&m);
- goto Copy;
case 0:
i++;
- if(m.op != Oinsert)
- cpkvp(&v, &v, buf, sizeof(buf));
+ j++;
+ cpkvp(&v, &v, buf, sizeof(buf));
+ copied += valsz(&v);
+ ok = apply(&v, &m, buf, sizeof(buf));
+ if(ok && m.op == Oclearb){
+ bp = unpackbp(v.v, v.nv);
+ freeblk(t, nil, bp);
+ }
+ goto Copyloop;
+ case 1:
+ j++;
+ cpkvp(&v, &m, buf, sizeof(buf));
+ copied += valsz(&v);
+ ok = 0;
+ if(m.op != Oclearb && m.op != Oclobber){
+ spc -= valsz(&m);
+ p->pullsz += msgsz(&m);
+ ok = 1;
+ }
+ goto Copyloop;
+ Copyloop:
while(j < up->hi){
- ok = apply(&v, &m, buf, sizeof(buf));
- Copy:
+ if(pullmsg(up, j, &v, &m, &full, spc) != 0)
+ break;
+ if(ok && m.op == Oclearb){
+ bp = unpackbp(v.v, v.nv);
+ freeblk(t, nil, bp);
+ }
p->pullsz += msgsz(&m);
+ ok = apply(&v, &m, buf, sizeof(buf));
j++;
- if(j == up->hi || pullmsg(up, j, &v, &m, &full, spc) != 0)
- break;
}
if(ok)
setval(d, &v);