rbyd: Prioritized y-split prunes, fixed remaining balance issues!
The issue with relying solely on the jump > branch hack to disambiguate
recolorable prunes is that suddenly we're back in ambiguous territory
when we encounter post-split yellow nodes. We need to prioritize yellow
prunes or else post-split weights can become ambiguous.
This was the whole reason we added a 3rd color!
Fortunately we can still prioritize yellow nodes by trying both
recolorable prunes first, and only falling back to non-recolorable
prunes if we still have unreachable alts.
Ends up with a bit of code duplication, but gets things working again.
---
Turns out this was all we needed to get our rbyd operations perfectly
balanced! Now all test_rbyd tests are passing:
test_rbyd+balance before: 1671/385878 failed
test_rbyd+balance after: 0/385878 failed (-100.0%)
And after running the full test suite, can confirm _all_ tests are
passing with LFS_ASSERTRBYDBALANCE. So I think we have some pretty
decent confidence our rbyd algorithm maintains balance, even with range
removals:
test+balance before: 20614/631541 failed
test+balance after: 0/631541 failed (-100.0%)
It was an open question if this was even possible, so it's nice to see
some evidence balanced range removals are not a problem.
---
The current implementation is a bit hacky, so we do take a hit to code
size. Though we may be able to claw this back after cleaning things up:
code stack ctx
before: 38580 2624 640
after: 38784 (+0.5%) 2624 (+0.0%) 640 (+0.0%)
This commit is contained in:
@@ -3872,6 +3872,66 @@ trunk:;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO hmmmm
|
||||||
|
if (lfsr_tag_isred(p[0].alt)
|
||||||
|
&& lfsr_tag_unreachable(
|
||||||
|
p[0].alt, p[0].weight,
|
||||||
|
lower_rid, upper_rid,
|
||||||
|
lower_tag, upper_tag)
|
||||||
|
&& p[0].jump > branch) {
|
||||||
|
// prune unreachable recolorable alts
|
||||||
|
// <r => <b
|
||||||
|
// .----'| .----'|
|
||||||
|
// | <b | |
|
||||||
|
// | .-'| | .--'
|
||||||
|
// 1 2 3 1 2 3 x
|
||||||
|
// this includes unreachable yellow alts in yellow splits
|
||||||
|
// <b >b
|
||||||
|
// .-'| .-'|
|
||||||
|
// <y | | |
|
||||||
|
// .-------'| | | |
|
||||||
|
// | <r | => | >b
|
||||||
|
// | .----' | .--------|-'|
|
||||||
|
// | | <b | <b |
|
||||||
|
// | | .----'| | .----'| |
|
||||||
|
// 1 2 3 4 4 1 2 3 4 4 1
|
||||||
|
LFS_DEBUG("%04x->%04x: yprune",
|
||||||
|
branch, lfsr_rbyd_eoff(rbyd));
|
||||||
|
alt &= ~LFSR_TAG_R;
|
||||||
|
lfsr_rbyd_p_pop(p);
|
||||||
|
}
|
||||||
|
if (lfsr_tag_unreachable2(
|
||||||
|
alt, weight,
|
||||||
|
p[0].alt, p[0].weight,
|
||||||
|
lower_rid, upper_rid,
|
||||||
|
lower_tag, upper_tag)
|
||||||
|
&& lfsr_tag_isred(p[0].alt)
|
||||||
|
&& jump > branch) {
|
||||||
|
// prune unreachable recolorable alts
|
||||||
|
// <r => <b
|
||||||
|
// .----'| .-------'|
|
||||||
|
// | <b | |
|
||||||
|
// | .-'| | .-----'
|
||||||
|
// 1 2 3 1 2 3 x
|
||||||
|
// this includes unreachable red alts in yellow splits
|
||||||
|
// <b >b
|
||||||
|
// .-'| .-'|
|
||||||
|
// <y | | <b
|
||||||
|
// .-------'| | .-----------|-'|
|
||||||
|
// | <r | => | | |
|
||||||
|
// | .----' | | | |
|
||||||
|
// | | <b | <b |
|
||||||
|
// | | .----'| | .----'| |
|
||||||
|
// 1 2 3 4 4 1 2 3 4 4 2
|
||||||
|
LFS_DEBUG("%04x->%04x: rprune",
|
||||||
|
branch, lfsr_rbyd_eoff(rbyd));
|
||||||
|
alt = (p[0].alt & ~LFSR_TAG_R) | (alt & LFSR_TAG_R);
|
||||||
|
alt &= ~LFSR_TAG_R;
|
||||||
|
weight = p[0].weight;
|
||||||
|
jump = p[0].jump;
|
||||||
|
lfsr_rbyd_p_pop(p);
|
||||||
|
}
|
||||||
|
|
||||||
// prune red alts
|
// prune red alts
|
||||||
if (lfsr_tag_isred(p[0].alt)
|
if (lfsr_tag_isred(p[0].alt)
|
||||||
&& lfsr_tag_unreachable(
|
&& lfsr_tag_unreachable(
|
||||||
@@ -3908,6 +3968,12 @@ trunk:;
|
|||||||
p[0].alt, p[0].weight,
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
lower_tag, upper_tag)) {
|
lower_tag, upper_tag)) {
|
||||||
|
if (!lfsr_tag_isred(p[0].alt)
|
||||||
|
&& lfsr_tag_isred(alt)) {
|
||||||
|
LFS_DEBUG("%04x->%04x: would've zpruned",
|
||||||
|
branch, lfsr_rbyd_eoff(rbyd));
|
||||||
|
}
|
||||||
|
|
||||||
// prune unreachable recolorable alts
|
// prune unreachable recolorable alts
|
||||||
// <r => <b
|
// <r => <b
|
||||||
// .----'| .-------'|
|
// .----'| .-------'|
|
||||||
@@ -3943,8 +4009,8 @@ trunk:;
|
|||||||
// | <b | |
|
// | <b | |
|
||||||
// | .-'| | .--'
|
// | .-'| | .--'
|
||||||
// 3 4 5 3 4 5 x
|
// 3 4 5 3 4 5 x
|
||||||
} else if (!p[0].alt) { //|| lfsr_tag_isred(alt)) {
|
} else if (!p[0].alt) {
|
||||||
LFS_DEBUG("%04x->%04x: ztrim",
|
LFS_DEBUG("%04x->%04x: zprune",
|
||||||
branch, lfsr_rbyd_eoff(rbyd));
|
branch, lfsr_rbyd_eoff(rbyd));
|
||||||
branch = branch_;
|
branch = branch_;
|
||||||
continue;
|
continue;
|
||||||
@@ -3957,7 +4023,7 @@ trunk:;
|
|||||||
// .-'| .--'
|
// .-'| .--'
|
||||||
// 3 4 3 4 x
|
// 3 4 3 4 x
|
||||||
} else if (!lfsr_tag_isred(alt)) {
|
} else if (!lfsr_tag_isred(alt)) {
|
||||||
LFS_DEBUG("%04x->%04x: btrim",
|
LFS_DEBUG("%04x->%04x: bprune",
|
||||||
branch, lfsr_rbyd_eoff(rbyd));
|
branch, lfsr_rbyd_eoff(rbyd));
|
||||||
alt = LFSR_TAG_ALT(
|
alt = LFSR_TAG_ALT(
|
||||||
LFSR_TAG_B,
|
LFSR_TAG_B,
|
||||||
|
|||||||
Reference in New Issue
Block a user