From 5269f79431f7a36cebe1c2f5501981fe2a7e13e0 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 26 Mar 2024 15:41:56 -0500 Subject: [PATCH] rbyd-rr: Preliminary altn collapsing is working This is the important part of the new range-removal algorithm: reclaiming altns on yellow splits. This is what allows new alts to reuse the old tree structure, otherwise we're just adding useless alts for no reason: .-----> a .---> a .-> a | .---> b .-y-r-> b .-b-> b | | | .-> c | | .-> c | | .-> c b-b-y-r-b-> d => b-b---b-> d => b-b-b-> d ysplit rprune reclaim altn (eventually) A few more corner cases need to be hammered out, but balance already shows a noticable improvement. --- lfs.c | 53 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/lfs.c b/lfs.c index 0aa36a18..91219b5b 100644 --- a/lfs.c +++ b/lfs.c @@ -873,6 +873,14 @@ static inline bool lfsr_tag_isgt(lfsr_tag_t tag) { return tag & LFSR_TAG_GT; } +static inline bool lfsr_tag_isa(lfsr_tag_t tag) { + return (tag & 0x2fff) == (LFSR_TAG_GT | 0); +} + +static inline bool lfsr_tag_isn(lfsr_tag_t tag) { + return (tag & 0x2fff) == (LFSR_TAG_LE | 0); +} + static inline lfsr_tag_t lfsr_tag_isparallel(lfsr_tag_t a, lfsr_tag_t b) { return (a & LFSR_TAG_GT) == (b & LFSR_TAG_GT); } @@ -884,12 +892,12 @@ static inline bool lfsr_tag_follow( if (lfsr_tag_isgt(alt)) { return rid > upper - (lfsr_srid_t)weight - 1 || (rid == upper - (lfsr_srid_t)weight - 1 - && (lfsr_tag_key(alt) == 0 + && (lfsr_tag_isa(alt) || lfsr_tag_key(tag) > lfsr_tag_key(alt))); } else { return rid < lower + (lfsr_srid_t)weight - 1 || (rid == lower + (lfsr_srid_t)weight - 1 - && (lfsr_tag_key(alt) != 0 + && (!lfsr_tag_isn(alt) && lfsr_tag_key(tag) <= lfsr_tag_key(alt))); } } @@ -951,12 +959,12 @@ static inline void lfsr_tag_trim( LFS_ASSERT((lfsr_srid_t)weight >= 0); if (lfsr_tag_isgt(alt)) { *upper_rid -= weight; - if (upper_tag && lfsr_tag_key(alt) != 0) { + if (upper_tag && !lfsr_tag_isn(alt)) { *upper_tag = alt + 1; } } else { *lower_rid += weight; - if (lower_tag && lfsr_tag_key(alt) != 0) { + if (lower_tag && !lfsr_tag_isn(alt)) { *lower_tag = alt + 1; } } @@ -2660,8 +2668,17 @@ static void lfsr_rbyd_p_recolor( if (p_alts[1]) { p_alts[1] |= LFSR_TAG_R; + // alt-never? we can prune this now + if (lfsr_tag_isn(p_alts[1])) { + p_alts[1] = p_alts[2]; + p_weights[1] = p_weights[2]; + p_jumps[1] = p_jumps[2]; + p_alts[2] = 0; + p_weights[2] = 0; + p_jumps[2] = 0; + // reorder so that top two edges always go in the same direction - if (lfsr_tag_isred(p_alts[2])) { + } else if (lfsr_tag_isred(p_alts[2])) { if (lfsr_tag_isparallel(p_alts[1], p_alts[2])) { // no reorder needed } else if (lfsr_tag_isparallel(p_alts[0], p_alts[2])) { @@ -2908,6 +2925,8 @@ again:; if (err) { return err; } + + //lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps); } goto prune; @@ -2922,6 +2941,12 @@ again:; // alt &= ~LFSR_TAG_R; // } + // TODO better solution? + // always prune alt-always tags + if (lfsr_tag_isa(alt)) { + goto prune; + } + // prune? // b // .-'| .-'| @@ -3055,7 +3080,7 @@ again:; // keep track of last alt on diverged trunk to stitch the // trunks together with if (d_state == LFSR_D_DIVERGEDLOWER - && lfsr_tag_key(p_alts[0]) != 0) { + && !lfsr_tag_isn(p_alts[0])) { d_tag = p_alts[0]; // d_rid = lower_rid; } @@ -3114,7 +3139,7 @@ again:; // keep track of last alt on diverged trunk to stitch the // trunks together with if (d_state == LFSR_D_DIVERGEDLOWER - && lfsr_tag_key(alt) != 0) { + && !lfsr_tag_isn(alt)) { d_tag = alt; // d_rid = lower_rid; } @@ -3257,9 +3282,10 @@ again:; // split less than alt = LFSR_TAG_ALT( LFSR_TAG_LE, - (!lfsr_d_isdiverged(d_state)) - ? LFSR_TAG_R - : LFSR_TAG_B, + LFSR_TAG_R, +// (!lfsr_d_isdiverged(d_state)) +// ? LFSR_TAG_R +// : LFSR_TAG_B, tag_); weight = upper_rid - lower_rid; lower_rid += weight; @@ -3283,9 +3309,10 @@ again:; // split greater than alt = LFSR_TAG_ALT( LFSR_TAG_GT, - (!lfsr_d_isdiverged(d_state)) - ? LFSR_TAG_R - : LFSR_TAG_B, + LFSR_TAG_R, +// (!lfsr_d_isdiverged(d_state)) +// ? LFSR_TAG_R +// : LFSR_TAG_B, tag); weight = upper_rid - (rid+1); upper_rid -= weight;