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
|
||||
if (lfsr_tag_isred(p[0].alt)
|
||||
&& lfsr_tag_unreachable(
|
||||
@@ -3908,6 +3968,12 @@ trunk:;
|
||||
p[0].alt, p[0].weight,
|
||||
lower_rid, upper_rid,
|
||||
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
|
||||
// <r => <b
|
||||
// .----'| .-------'|
|
||||
@@ -3943,8 +4009,8 @@ trunk:;
|
||||
// | <b | |
|
||||
// | .-'| | .--'
|
||||
// 3 4 5 3 4 5 x
|
||||
} else if (!p[0].alt) { //|| lfsr_tag_isred(alt)) {
|
||||
LFS_DEBUG("%04x->%04x: ztrim",
|
||||
} else if (!p[0].alt) {
|
||||
LFS_DEBUG("%04x->%04x: zprune",
|
||||
branch, lfsr_rbyd_eoff(rbyd));
|
||||
branch = branch_;
|
||||
continue;
|
||||
@@ -3957,7 +4023,7 @@ trunk:;
|
||||
// .-'| .--'
|
||||
// 3 4 3 4 x
|
||||
} else if (!lfsr_tag_isred(alt)) {
|
||||
LFS_DEBUG("%04x->%04x: btrim",
|
||||
LFS_DEBUG("%04x->%04x: bprune",
|
||||
branch, lfsr_rbyd_eoff(rbyd));
|
||||
alt = LFSR_TAG_ALT(
|
||||
LFSR_TAG_B,
|
||||
|
||||
Reference in New Issue
Block a user