rbyd: Progress towards rbyd balance, separated y-pruning, hacky goto

The main idea here is we need to unconditionally descend down red/yellow
alts to check if they're post-split yellow nodes before pruning, since
yellow nodes should be recolored to maintain the color balance of our
tree.

To make this work:

- Added separate y-pruning logic before our diverged logic, this starts
  to look a bit like previous incarnations of this function.

- Our non-y-pruning logic is all now gated behind the if-diverging
  check, so we shouldn't be non-y-pruning at all unless we've diverged.

  It may be worth rewriting this to use the trimming logic directly,
  instead of reachability.

- Moving non-y-pruning logic behind the if-diverging check ended up
  causing problems for the stitching node, which is still a bit of a
  special case. A hacky goto solves this for now at the risk of
  velociraptors... https://xkcd.com/292

It's hacky, but the goal right now is to just get something working.

This may seem like a lot of changes for only a couple more tests
passing, but progress is progress:

  test_rbyd+balance before: 306/385878 failed
  test_rbyd+balance after:  300/385878 failed (-2.0%)

Code changes:

           code          stack          ctx
  before: 38528           2624          640
  after:  38644 (+0.3%)   2624 (+0.0%)  640 (+0.0%)
This commit is contained in:
Christopher Haster
2025-01-25 13:20:21 -06:00
parent 192779ae84
commit ee3a1374eb
+164 -94
View File
@@ -3619,6 +3619,52 @@ trunk:;
LFS_SWAP(lfs_size_t, &jump, &branch_); LFS_SWAP(lfs_size_t, &jump, &branch_);
} }
// TODO redoc?
// prune?
if (lfsr_tag_isred(p[0].alt)) {
// prune unreachable red alts
// <b >b
// .-'| .-'|
// <y | | |
// .-------'| | | |
// | <r | => | >b
// | .----' | .--------|-'|
// | | <b | <b |
// | | .----'| | .----'| |
// 1 2 3 4 4 1 2 3 4 4 1
if (lfsr_tag_unreachable(
p[0].alt, p[0].weight,
lower_rid, upper_rid,
lower_tag, upper_tag)) {
LFS_DEBUG("%04x->%04x: yprune",
branch, lfsr_rbyd_eoff(rbyd));
alt &= ~LFSR_TAG_R;
lfsr_rbyd_p_pop(p);
// prune other unreachable alts
// <b >b
// .-'| .-'|
// <y | | <b
// .-------'| | .-----------|-'|
// | <r | => | | |
// | .----' | | | |
// | | <b | <b |
// | | .----'| | .----'| |
// 1 2 3 4 4 1 2 3 4 4 2
} else if (lfsr_tag_unreachable2(
alt, weight,
p[0].alt, p[0].weight,
lower_rid, upper_rid,
lower_tag, upper_tag)) {
LFS_DEBUG("%04x->%04x: rprune",
branch, lfsr_rbyd_eoff(rbyd));
alt = p[0].alt & ~LFSR_TAG_R;
weight = p[0].weight;
jump = p[0].jump;
lfsr_rbyd_p_pop(p);
}
}
// TODO need this? does this ever get triggered? // TODO need this? does this ever get triggered?
// both diverging? collapse // both diverging? collapse
// <r >b // <r >b
@@ -3638,7 +3684,7 @@ trunk:;
lower_rid, upper_rid, lower_rid, upper_rid,
a_rid, a_tag, a_rid, a_tag,
b_rid, b_tag); b_rid, b_tag);
if (diverging && diverging_red) { if (!diverged && diverging && diverging_red) {
LFS_DEBUG("%04x->%04x: both diverging", LFS_DEBUG("%04x->%04x: both diverging",
branch, lfsr_rbyd_eoff(rbyd)); branch, lfsr_rbyd_eoff(rbyd));
LFS_ASSERT(a_rid < b_rid || a_tag < b_tag); LFS_ASSERT(a_rid < b_rid || a_tag < b_tag);
@@ -3705,7 +3751,7 @@ trunk:;
&& (diverging || diverging_red)) { && (diverging || diverging_red)) {
LFS_DEBUG("%04x->%04x: diverging", LFS_DEBUG("%04x->%04x: diverging",
branch, lfsr_rbyd_eoff(rbyd)); branch, lfsr_rbyd_eoff(rbyd));
if (lfsr_tag_isred(p[0].alt)) { if (lfsr_tag_isred(alt)) {
LFS_DEBUG("%04x->%04x: wouldnt've diverged", LFS_DEBUG("%04x->%04x: wouldnt've diverged",
branch, lfsr_rbyd_eoff(rbyd)); branch, lfsr_rbyd_eoff(rbyd));
} }
@@ -3758,6 +3804,8 @@ trunk:;
// TODO should we assert we're only diverging here? // TODO should we assert we're only diverging here?
// not diverging_red? // not diverging_red?
// TODO can this be red? can we assert it's black?
// TODO is this uh, how much of this is already in // TODO is this uh, how much of this is already in
// the diverging alt? // the diverging alt?
@@ -3809,110 +3857,132 @@ trunk:;
// // continue to next alt // // continue to next alt
// branch = branch_; // branch = branch_;
// continue; // continue;
goto maybetrim;
} }
// diverged? // diverged?
// : : // : :
// <b => nb // <b => nb
// .-'| .--' // .-'| .--'
// 3 4 3 4 x // 3 4 3 4 x
} else if (diverged && diverging) { } else if (diverged) {
LFS_DEBUG("%04x->%04x: div pruning", // diverging = lfsr_tag_diverging2(
branch, lfsr_rbyd_eoff(rbyd)); // alt, weight,
// trim so alt is pruned // p[0].alt, p[0].weight,
lfsr_tag_trim( // lower_rid, upper_rid,
alt, weight, // a_rid, a_tag,
&lower_rid, &upper_rid, // b_rid, b_tag);
&lower_tag, &upper_tag); // diverging_red = lfsr_tag_isred(p[0].alt)
weight = 0; // && lfsr_tag_diverging(
} // p[0].alt, p[0].weight,
// lower_rid, upper_rid,
// a_rid, a_tag,
// b_rid, b_tag);
// if (diverging_red) {
// LFS_DEBUG("%04x->%04x: div r pruning",
// branch, lfsr_rbyd_eoff(rbyd));
// // trim so alt is pruned
// lfsr_tag_trim(
// p[0].alt, p[0].weight,
// &lower_rid, &upper_rid,
// &lower_tag, &upper_tag);
// p[0].weight = 0;
//
// lfsr_rbyd_p_pop(p);
//
// // TODO prune? (trim?)
// }
// prune? diverging = lfsr_tag_diverging2(
//
// note if only yellow pruning this could be much simpler
// prune unreachable red alts
// <b >b
// .-'| .-'|
// <y | | |
// .-------'| | | |
// | <r | => | >b
// | .----' | .--------|-'|
// | | <b | <b |
// | | .----'| | .----'| |
// 1 2 3 4 4 1 2 3 4 4 1
if (lfsr_tag_isred(p[0].alt)
&& lfsr_tag_unreachable(
p[0].alt, p[0].weight,
lower_rid, upper_rid,
lower_tag, upper_tag)) {
LFS_DEBUG("%04x->%04x: yprune",
branch, lfsr_rbyd_eoff(rbyd));
alt &= ~LFSR_TAG_R;
lfsr_rbyd_p_pop(p);
}
// prune other unreachable alts
// <b >b
// .-'| .-'|
// <y | | <b
// .-------'| | .-----------|-'|
// | <r | => | | |
// | .----' | | | |
// | | <b | <b |
// | | .----'| | .----'| |
// 1 2 3 4 4 1 2 3 4 4 2
if (lfsr_tag_unreachable2(
alt, weight, alt, weight,
p[0].alt, p[0].weight, p[0].alt, p[0].weight,
lower_rid, upper_rid, lower_rid, upper_rid,
lower_tag, upper_tag)) { a_rid, a_tag,
// prune unreachable recolorable alts b_rid, b_tag);
// : : if (diverging) {
// <r => <b // && (!lfsr_tag_isred(alt)
// .----'| .-------'| // || lfsr_tag_isred(p[0].alt))) {
// | <b | | LFS_DEBUG("%04x->%04x: div b pruning",
// | .-'| | .-----' branch, lfsr_rbyd_eoff(rbyd));
// 1 2 3 1 2 3 x // trim so alt is pruned
if (lfsr_tag_isred(p[0].alt)) { lfsr_tag_trim(
alt = p[0].alt & ~LFSR_TAG_R; alt, weight,
weight = p[0].weight; &lower_rid, &upper_rid,
jump = p[0].jump; &lower_tag, &upper_tag);
lfsr_rbyd_p_pop(p); weight = 0;
// TODO redoc maybetrim:;
// prune unreachable root alts and red alts // prune other unreachable alts
// : : // <b >b
// <r => <b // .-'| .-'|
// .----'| .----'| // <y | | <b
// | <b | | // .-------'| | .-----------|-'|
// | .-'| | .--' // | <r | => | | |
// 3 4 5 3 4 5 x // | .----' | | | |
} else if (!p[0].alt) { //|| lfsr_tag_isred(alt)) { // | | <b | <b |
branch = branch_; // | | .----'| | .----'| |
continue; // 1 2 3 4 4 1 2 3 4 4 2
if (lfsr_tag_unreachable2(
alt, weight,
p[0].alt, p[0].weight,
lower_rid, upper_rid,
lower_tag, upper_tag)) {
// prune unreachable recolorable alts
// : :
// <r => <b
// .----'| .-------'|
// | <b | |
// | .-'| | .-----'
// 1 2 3 1 2 3 x
if (lfsr_tag_isred(p[0].alt)) {
LFS_DEBUG("%04x->%04x: rprune",
branch, lfsr_rbyd_eoff(rbyd));
alt = p[0].alt & ~LFSR_TAG_R;
weight = p[0].weight;
jump = p[0].jump;
lfsr_rbyd_p_pop(p);
// mark unreachable non-root black alts as unreachable, // TODO redoc
// we can't prune these or we risk breaking the color // TODO does this ever get hit?
// balance of our tree, but if we push a red up later we // prune unreachable root alts and red alts
// can get rid of them // : :
// : : // <r => <b
// <b => nb // .----'| .----'|
// .-'| .--' // | <b | |
// 3 4 3 4 x // | .-'| | .--'
} else { // 3 4 5 3 4 5 x
alt = LFSR_TAG_ALT( } else if (!p[0].alt) { //|| lfsr_tag_isred(alt)) {
LFSR_TAG_B, LFS_DEBUG("%04x->%04x: zprune",
LFSR_TAG_LE, branch, lfsr_rbyd_eoff(rbyd));
(diverged && !(a_rid < b_rid || a_tag < b_tag)) branch = branch_;
? d_tag continue;
: lower_tag);
// TODO hmmmmm? // mark unreachable non-root black alts as unreachable,
LFS_ASSERT(weight == 0); // we can't prune these or we risk breaking the color
//weight = 0; // balance of our tree, but if we push a red up later we
// we don't need to, but setting jump=0 asserts this // can get rid of them
// alt is unreachable while also minimizing the the // : :
// encoding // <b => nb
jump = 0; // .-'| .--'
// 3 4 3 4 x
} else if (!lfsr_tag_isred(alt)) {
LFS_DEBUG("%04x->%04x: bprune",
branch, lfsr_rbyd_eoff(rbyd));
alt = LFSR_TAG_ALT(
LFSR_TAG_B,
LFSR_TAG_LE,
(diverged && !(a_rid < b_rid || a_tag < b_tag))
? d_tag
: lower_tag);
// TODO hmmmmm?
LFS_ASSERT(weight == 0);
//weight = 0;
// we don't need to, but setting jump=0 asserts this
// alt is unreachable while also minimizing the the
// encoding
jump = 0;
}
}
} }
} }