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:
@@ -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)
|
uint8_t d_state = (a_rid != b_rid || a_tag != b_tag)
|
||||||
? LFSR_D_DIVERGINGLOWER
|
? LFSR_D_DIVERGINGLOWER
|
||||||
: LFSR_D_NOTDIVERGING;
|
: LFSR_D_NOTDIVERGING;
|
||||||
bool d_pruned = false;
|
|
||||||
lfs_size_t d_branch = rbyd->eoff;
|
lfs_size_t d_branch = rbyd->eoff;
|
||||||
lfsr_tag_t d_tag = 0;
|
lfsr_tag_t d_tag = 0;
|
||||||
lfsr_srid_t d_rid = 0;
|
lfsr_srid_t d_rid = 0;
|
||||||
@@ -2866,6 +2865,7 @@ again:;
|
|||||||
// make jump absolute
|
// make jump absolute
|
||||||
jump = branch - jump;
|
jump = branch - jump;
|
||||||
lfs_size_t branch_ = branch + d;
|
lfs_size_t branch_ = branch + d;
|
||||||
|
lingering:;
|
||||||
|
|
||||||
// do bounds want to take different paths? begin diverging
|
// do bounds want to take different paths? begin diverging
|
||||||
if (!lfsr_d_isdiverged(d_state)
|
if (!lfsr_d_isdiverged(d_state)
|
||||||
@@ -2881,11 +2881,7 @@ again:;
|
|||||||
|
|
||||||
// take care of any lingering red alts before diverging
|
// take care of any lingering red alts before diverging
|
||||||
if (lfsr_tag_isred(p_alts[0])) {
|
if (lfsr_tag_isred(p_alts[0])) {
|
||||||
alt = p_alts[0] & ~LFSR_TAG_R;
|
goto prune;
|
||||||
weight = p_weights[0];
|
|
||||||
jump = p_jumps[0];
|
|
||||||
branch_ = branch;
|
|
||||||
lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps);
|
|
||||||
|
|
||||||
// begin diverging
|
// begin diverging
|
||||||
} else {
|
} else {
|
||||||
@@ -2914,72 +2910,12 @@ again:;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lfsr_tag_follow2(
|
goto prune;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't write diverging lower alts
|
// don't write diverging lower alts
|
||||||
} else if (d_state == LFSR_D_DIVERGINGLOWER) {
|
} else if (d_state == LFSR_D_DIVERGINGLOWER) {
|
||||||
if (lfsr_tag_follow2(
|
goto prune;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (lfsr_d_isdiverged(d_state)) {
|
// if (lfsr_d_isdiverged(d_state)) {
|
||||||
@@ -3002,9 +2938,6 @@ again:;
|
|||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
lower_tag, upper_tag)
|
lower_tag, upper_tag)
|
||||||
// prune because of diverged paths?
|
// 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)
|
|| (lfsr_d_isdiverged(d_state)
|
||||||
&& (d_state == LFSR_D_DIVERGEDUPPER)
|
&& (d_state == LFSR_D_DIVERGEDUPPER)
|
||||||
^ lfsr_tag_isgt(alt)
|
^ lfsr_tag_isgt(alt)
|
||||||
@@ -3038,38 +2971,19 @@ again:;
|
|||||||
rbyd->eoff,
|
rbyd->eoff,
|
||||||
alt,
|
alt,
|
||||||
weight);
|
weight);
|
||||||
alt = p_alts[0] & ~LFSR_TAG_R;
|
goto prune;
|
||||||
weight = p_weights[0];
|
|
||||||
jump = p_jumps[0];
|
|
||||||
lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps);
|
|
||||||
|
|
||||||
// black alts just become unreachable, if we pruned these
|
// black alts just become unreachable, if we pruned these
|
||||||
// it would break the coloring of our tree
|
// it would break the coloring of our tree
|
||||||
} else {
|
} else {
|
||||||
// if (d_state == LFSR_D_DIVERGINGLOWER) {
|
printf("%04x->%04x: bprune 0x%x w%d\n",
|
||||||
// printf("%04x->%04x: dprune 0x%x w%d\n",
|
branch,
|
||||||
// branch,
|
rbyd->eoff,
|
||||||
// rbyd->eoff,
|
alt,
|
||||||
// alt,
|
weight);
|
||||||
// weight);
|
alt = LFSR_TAG_ALT(LFSR_TAG_LE, LFSR_TAG_B, 0);
|
||||||
// // propagate pruning to yellow splits to avoid issues
|
weight = 0;
|
||||||
// // with tail-recursive recoloring
|
// jump = 0;
|
||||||
// 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;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3112,9 +3026,7 @@ again:;
|
|||||||
&lower_rid, &upper_rid,
|
&lower_rid, &upper_rid,
|
||||||
&lower_tag, &upper_tag);
|
&lower_tag, &upper_tag);
|
||||||
p_alts[0] &= ~LFSR_TAG_R;
|
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
|
// otherwise we need to point to the yellow alt and
|
||||||
// prune later
|
// prune later
|
||||||
@@ -3138,9 +3050,7 @@ again:;
|
|||||||
&lower_rid, &upper_rid,
|
&lower_rid, &upper_rid,
|
||||||
&lower_tag, &upper_tag);
|
&lower_tag, &upper_tag);
|
||||||
p_alts[0] &= ~LFSR_TAG_R;
|
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
|
// keep track of last alt on diverged trunk to stitch the
|
||||||
// trunks together with
|
// trunks together with
|
||||||
@@ -3200,8 +3110,6 @@ again:;
|
|||||||
p_alts[0], p_weights[0],
|
p_alts[0], p_weights[0],
|
||||||
&lower_rid, &upper_rid,
|
&lower_rid, &upper_rid,
|
||||||
&lower_tag, &upper_tag);
|
&lower_tag, &upper_tag);
|
||||||
// no longer pruned
|
|
||||||
d_pruned = false;
|
|
||||||
|
|
||||||
// keep track of last alt on diverged trunk to stitch the
|
// keep track of last alt on diverged trunk to stitch the
|
||||||
// trunks together with
|
// trunks together with
|
||||||
@@ -3223,6 +3131,41 @@ again:;
|
|||||||
// continue to next alt
|
// continue to next alt
|
||||||
y_branch = branch;
|
y_branch = branch;
|
||||||
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?
|
// found end of tree?
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user