rbyd-rr: More cleanup around diverged pruning, common goto, no more d_prune

- Dropped d_prune cludge!

  Thanks to d_tag being properly derived from lower_tag, it can no
  longer be null (though it may point to null and become an altn). This
  means we will always have something to replace the diverging-alt with.

  So no more concerns about a following yellow node splitting and
  pushing up a red into who-knows-what. The diverged-replacement-alt
  will always be able to eat this.

- Bluntly deduplicated the common pruning logic into its own goto
  destination.

  It's interesting to note this should probably be a separate function
  (yes yes, gotos bad, blablabla), but the amount of appendattr specific
  context that is needed makes this a bit difficult.

  To make this work without the previous fallthrough this needed a way
  to continue appendattr without fetching a new alt. The "lingering"
  goto destination accomplishes this.

  Though this is starting to look like goto soup again...
This commit is contained in:
Christopher Haster
2024-03-26 11:19:04 -05:00
parent 6b3730723e
commit 74f4ad8669
+50 -107
View File
@@ -2805,7 +2805,6 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
uint8_t d_state = (a_rid != b_rid || a_tag != b_tag)
? LFSR_D_DIVERGINGLOWER
: LFSR_D_NOTDIVERGING;
bool d_pruned = false;
lfs_size_t d_branch = rbyd->eoff;
lfsr_tag_t d_tag = 0;
lfsr_srid_t d_rid = 0;
@@ -2866,6 +2865,7 @@ again:;
// make jump absolute
jump = branch - jump;
lfs_size_t branch_ = branch + d;
lingering:;
// do bounds want to take different paths? begin diverging
if (!lfsr_d_isdiverged(d_state)
@@ -2881,11 +2881,7 @@ again:;
// take care of any lingering red alts before diverging
if (lfsr_tag_isred(p_alts[0])) {
alt = p_alts[0] & ~LFSR_TAG_R;
weight = p_weights[0];
jump = p_jumps[0];
branch_ = branch;
lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps);
goto prune;
// begin diverging
} else {
@@ -2914,72 +2910,12 @@ again:;
}
}
if (lfsr_tag_follow2(
alt, weight,
p_alts[0], p_weights[0],
lower_rid, upper_rid,
a_rid, a_tag)) {
lfsr_tag_flip2(
&alt, &weight,
p_alts[0], p_weights[0],
lower_rid, upper_rid);
lfs_swap32(&jump, &branch_);
}
lfsr_tag_trim(
alt, weight,
&lower_rid, &upper_rid,
&lower_tag, &upper_tag);
printf("%04x->%04x: dprune 0x%x w%d\n",
branch,
rbyd->eoff,
alt,
weight);
// TODO need this?
// propagate pruning to yellow splits to avoid issues
// with tail-recursive recoloring
// if (lfsr_d_isdiverged(d_state)) {
// d_pruned = true;
// }
// TODO can we move y_branch updates to beginning of loop?
y_branch = branch;
branch = branch_;
continue;
goto prune;
}
// don't write diverging lower alts
} else if (d_state == LFSR_D_DIVERGINGLOWER) {
if (lfsr_tag_follow2(
alt, weight,
p_alts[0], p_weights[0],
lower_rid, upper_rid,
a_rid, a_tag)) {
lfsr_tag_flip2(
&alt, &weight,
p_alts[0], p_weights[0],
lower_rid, upper_rid);
lfs_swap32(&jump, &branch_);
}
lfsr_tag_trim(
alt, weight,
&lower_rid, &upper_rid,
&lower_tag, &upper_tag);
printf("%04x->%04x: dprune 0x%x w%d\n",
branch,
rbyd->eoff,
alt,
weight);
// TODO need this?
// propagate pruning to yellow splits to avoid issues
// with tail-recursive recoloring
// if (lfsr_d_isdiverged(d_state)) {
// d_pruned = true;
// }
// TODO can we move y_branch updates to beginning of loop?
y_branch = branch;
branch = branch_;
continue;
goto prune;
}
// if (lfsr_d_isdiverged(d_state)) {
@@ -3002,9 +2938,6 @@ again:;
lower_rid, upper_rid,
lower_tag, upper_tag)
// prune because of diverged paths?
// || d_state == LFSR_D_DIVERGINGLOWER
// TODO can we adjust lower/upper rid/tag to make this
// happen implicitly?
|| (lfsr_d_isdiverged(d_state)
&& (d_state == LFSR_D_DIVERGEDUPPER)
^ lfsr_tag_isgt(alt)
@@ -3038,38 +2971,19 @@ again:;
rbyd->eoff,
alt,
weight);
alt = p_alts[0] & ~LFSR_TAG_R;
weight = p_weights[0];
jump = p_jumps[0];
lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps);
goto prune;
// black alts just become unreachable, if we pruned these
// it would break the coloring of our tree
} else {
// if (d_state == LFSR_D_DIVERGINGLOWER) {
// printf("%04x->%04x: dprune 0x%x w%d\n",
// branch,
// rbyd->eoff,
// alt,
// weight);
// // propagate pruning to yellow splits to avoid issues
// // with tail-recursive recoloring
// if (lfsr_d_isdiverged(d_state)) {
// d_pruned = true;
// }
// y_branch = branch;
// branch = branch_;
// continue;
// } else {
printf("%04x->%04x: bprune 0x%x w%d\n",
branch,
rbyd->eoff,
alt,
weight);
alt = LFSR_TAG_ALT(LFSR_TAG_LE, LFSR_TAG_B, 0);
weight = 0;
// jump = 0;
// }
printf("%04x->%04x: bprune 0x%x w%d\n",
branch,
rbyd->eoff,
alt,
weight);
alt = LFSR_TAG_ALT(LFSR_TAG_LE, LFSR_TAG_B, 0);
weight = 0;
// jump = 0;
}
}
@@ -3112,9 +3026,7 @@ again:;
&lower_rid, &upper_rid,
&lower_tag, &upper_tag);
p_alts[0] &= ~LFSR_TAG_R;
if (!d_pruned) {
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps);
}
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps);
// otherwise we need to point to the yellow alt and
// prune later
@@ -3138,9 +3050,7 @@ again:;
&lower_rid, &upper_rid,
&lower_tag, &upper_tag);
p_alts[0] &= ~LFSR_TAG_R;
if (!d_pruned) {
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps);
}
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps);
// keep track of last alt on diverged trunk to stitch the
// trunks together with
@@ -3200,8 +3110,6 @@ again:;
p_alts[0], p_weights[0],
&lower_rid, &upper_rid,
&lower_tag, &upper_tag);
// no longer pruned
d_pruned = false;
// keep track of last alt on diverged trunk to stitch the
// trunks together with
@@ -3223,6 +3131,41 @@ again:;
// continue to next alt
y_branch = branch;
branch = branch_;
continue;
prune:;
// handle any lingering red alts
if (lfsr_tag_isred(p_alts[0])) {
alt = p_alts[0] & ~LFSR_TAG_R;
weight = p_weights[0];
jump = p_jumps[0];
branch_ = branch;
lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps);
goto lingering;
// prune black alts
} else {
if (lfsr_tag_follow2(
alt, weight,
p_alts[0], p_weights[0],
lower_rid, upper_rid,
a_rid, a_tag)) {
lfsr_tag_flip2(
&alt, &weight,
p_alts[0], p_weights[0],
lower_rid, upper_rid);
lfs_swap32(&jump, &branch_);
}
lfsr_tag_trim(
alt, weight,
&lower_rid, &upper_rid,
&lower_tag, &upper_tag);
// TODO can we move y_branch updates to beginning of loop?
y_branch = branch;
branch = branch_;
continue;
}
// found end of tree?
} else {