From b6b16099fcae3e63bbdb79d649f7fd9b53ceaa9b Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 26 Jan 2025 16:31:43 -0600 Subject: [PATCH] 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%) --- lfs.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/lfs.c b/lfs.c index c29dd43c..e6d8c845 100644 --- a/lfs.c +++ b/lfs.c @@ -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 + // b + // .-'| .-'| + // | >b + // | .----' | .--------|-'| + // | | %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 + // b + // .-'| .-'| + // | | | + // | .----' | | | | + // | | %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 // %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,