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.
This commit is contained in:
@@ -873,6 +873,14 @@ static inline bool lfsr_tag_isgt(lfsr_tag_t tag) {
|
|||||||
return tag & LFSR_TAG_GT;
|
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) {
|
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);
|
return (a & LFSR_TAG_GT) == (b & LFSR_TAG_GT);
|
||||||
}
|
}
|
||||||
@@ -884,12 +892,12 @@ static inline bool lfsr_tag_follow(
|
|||||||
if (lfsr_tag_isgt(alt)) {
|
if (lfsr_tag_isgt(alt)) {
|
||||||
return rid > upper - (lfsr_srid_t)weight - 1
|
return rid > upper - (lfsr_srid_t)weight - 1
|
||||||
|| (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)));
|
|| lfsr_tag_key(tag) > lfsr_tag_key(alt)));
|
||||||
} else {
|
} else {
|
||||||
return rid < lower + (lfsr_srid_t)weight - 1
|
return rid < lower + (lfsr_srid_t)weight - 1
|
||||||
|| (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)));
|
&& 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);
|
LFS_ASSERT((lfsr_srid_t)weight >= 0);
|
||||||
if (lfsr_tag_isgt(alt)) {
|
if (lfsr_tag_isgt(alt)) {
|
||||||
*upper_rid -= weight;
|
*upper_rid -= weight;
|
||||||
if (upper_tag && lfsr_tag_key(alt) != 0) {
|
if (upper_tag && !lfsr_tag_isn(alt)) {
|
||||||
*upper_tag = alt + 1;
|
*upper_tag = alt + 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*lower_rid += weight;
|
*lower_rid += weight;
|
||||||
if (lower_tag && lfsr_tag_key(alt) != 0) {
|
if (lower_tag && !lfsr_tag_isn(alt)) {
|
||||||
*lower_tag = alt + 1;
|
*lower_tag = alt + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2660,8 +2668,17 @@ static void lfsr_rbyd_p_recolor(
|
|||||||
if (p_alts[1]) {
|
if (p_alts[1]) {
|
||||||
p_alts[1] |= LFSR_TAG_R;
|
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
|
// 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])) {
|
if (lfsr_tag_isparallel(p_alts[1], p_alts[2])) {
|
||||||
// no reorder needed
|
// no reorder needed
|
||||||
} else if (lfsr_tag_isparallel(p_alts[0], p_alts[2])) {
|
} else if (lfsr_tag_isparallel(p_alts[0], p_alts[2])) {
|
||||||
@@ -2908,6 +2925,8 @@ again:;
|
|||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps);
|
||||||
}
|
}
|
||||||
|
|
||||||
goto prune;
|
goto prune;
|
||||||
@@ -2922,6 +2941,12 @@ again:;
|
|||||||
// alt &= ~LFSR_TAG_R;
|
// alt &= ~LFSR_TAG_R;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// TODO better solution?
|
||||||
|
// always prune alt-always tags
|
||||||
|
if (lfsr_tag_isa(alt)) {
|
||||||
|
goto prune;
|
||||||
|
}
|
||||||
|
|
||||||
// prune?
|
// prune?
|
||||||
// <b >b
|
// <b >b
|
||||||
// .-'| .-'|
|
// .-'| .-'|
|
||||||
@@ -3055,7 +3080,7 @@ again:;
|
|||||||
// keep track of last alt on diverged trunk to stitch the
|
// keep track of last alt on diverged trunk to stitch the
|
||||||
// trunks together with
|
// trunks together with
|
||||||
if (d_state == LFSR_D_DIVERGEDLOWER
|
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_tag = p_alts[0];
|
||||||
// d_rid = lower_rid;
|
// d_rid = lower_rid;
|
||||||
}
|
}
|
||||||
@@ -3114,7 +3139,7 @@ again:;
|
|||||||
// keep track of last alt on diverged trunk to stitch the
|
// keep track of last alt on diverged trunk to stitch the
|
||||||
// trunks together with
|
// trunks together with
|
||||||
if (d_state == LFSR_D_DIVERGEDLOWER
|
if (d_state == LFSR_D_DIVERGEDLOWER
|
||||||
&& lfsr_tag_key(alt) != 0) {
|
&& !lfsr_tag_isn(alt)) {
|
||||||
d_tag = alt;
|
d_tag = alt;
|
||||||
// d_rid = lower_rid;
|
// d_rid = lower_rid;
|
||||||
}
|
}
|
||||||
@@ -3257,9 +3282,10 @@ again:;
|
|||||||
// split less than
|
// split less than
|
||||||
alt = LFSR_TAG_ALT(
|
alt = LFSR_TAG_ALT(
|
||||||
LFSR_TAG_LE,
|
LFSR_TAG_LE,
|
||||||
(!lfsr_d_isdiverged(d_state))
|
LFSR_TAG_R,
|
||||||
? LFSR_TAG_R
|
// (!lfsr_d_isdiverged(d_state))
|
||||||
: LFSR_TAG_B,
|
// ? LFSR_TAG_R
|
||||||
|
// : LFSR_TAG_B,
|
||||||
tag_);
|
tag_);
|
||||||
weight = upper_rid - lower_rid;
|
weight = upper_rid - lower_rid;
|
||||||
lower_rid += weight;
|
lower_rid += weight;
|
||||||
@@ -3283,9 +3309,10 @@ again:;
|
|||||||
// split greater than
|
// split greater than
|
||||||
alt = LFSR_TAG_ALT(
|
alt = LFSR_TAG_ALT(
|
||||||
LFSR_TAG_GT,
|
LFSR_TAG_GT,
|
||||||
(!lfsr_d_isdiverged(d_state))
|
LFSR_TAG_R,
|
||||||
? LFSR_TAG_R
|
// (!lfsr_d_isdiverged(d_state))
|
||||||
: LFSR_TAG_B,
|
// ? LFSR_TAG_R
|
||||||
|
// : LFSR_TAG_B,
|
||||||
tag);
|
tag);
|
||||||
weight = upper_rid - (rid+1);
|
weight = upper_rid - (rid+1);
|
||||||
upper_rid -= weight;
|
upper_rid -= weight;
|
||||||
|
|||||||
Reference in New Issue
Block a user