rbyd: Refined jump > branch pruning hack
Now that we have this jump > branch trick in our back pocket, we can
undo most of the y-pruning/diverged-pruning separation.
In theory all we need is to conditionally recolor based on if jump is >
branch.
---
Well, in theory at least. This seems to increase the number of test
failures, but it's unclear if this is due to jump > branch being an
incorrect assumption or some other bug exposed by the change in logic:
test_rbyd+balance before: 300/385878 failed
test_rbyd+balance after: 1671/385878 failed (+457.0%)
But it does save code:
code stack ctx
before: 38880 2624 640
after: 38584 (-0.8%) 2624 (+0.0%) 640 (+0.0%)
This commit is contained in:
@@ -3624,54 +3624,6 @@ trunk:;
|
|||||||
LFS_SWAP(lfs_size_t, &jump, &branch_);
|
LFS_SWAP(lfs_size_t, &jump, &branch_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO redoc?
|
|
||||||
// prune?
|
|
||||||
if (lfsr_tag_isred(p[0].alt)) {
|
|
||||||
// prune unreachable red alts
|
|
||||||
// <b >b
|
|
||||||
// .-'| .-'|
|
|
||||||
// <y | | |
|
|
||||||
// .-------'| | | |
|
|
||||||
// | <r | => | >b
|
|
||||||
// | .----' | .--------|-'|
|
|
||||||
// | | <b | <b |
|
|
||||||
// | | .----'| | .----'| |
|
|
||||||
// 1 2 3 4 4 1 2 3 4 4 1
|
|
||||||
if (lfsr_tag_unreachable(
|
|
||||||
p[0].alt, p[0].weight,
|
|
||||||
lower_rid, upper_rid,
|
|
||||||
lower_tag, upper_tag)
|
|
||||||
&& p[0].jump >= branch_) {
|
|
||||||
LFS_DEBUG("%04x->%04x: yprune",
|
|
||||||
branch, lfsr_rbyd_eoff(rbyd));
|
|
||||||
alt &= ~LFSR_TAG_R;
|
|
||||||
lfsr_rbyd_p_pop(p);
|
|
||||||
|
|
||||||
// prune other unreachable alts
|
|
||||||
// <b >b
|
|
||||||
// .-'| .-'|
|
|
||||||
// <y | | <b
|
|
||||||
// .-------'| | .-----------|-'|
|
|
||||||
// | <r | => | | |
|
|
||||||
// | .----' | | | |
|
|
||||||
// | | <b | <b |
|
|
||||||
// | | .----'| | .----'| |
|
|
||||||
// 1 2 3 4 4 1 2 3 4 4 2
|
|
||||||
} else if (lfsr_tag_unreachable2(
|
|
||||||
alt, weight,
|
|
||||||
p[0].alt, p[0].weight,
|
|
||||||
lower_rid, upper_rid,
|
|
||||||
lower_tag, upper_tag)
|
|
||||||
&& jump >= branch_) {
|
|
||||||
LFS_DEBUG("%04x->%04x: rprune",
|
|
||||||
branch, lfsr_rbyd_eoff(rbyd));
|
|
||||||
alt = p[0].alt & ~LFSR_TAG_R;
|
|
||||||
weight = p[0].weight;
|
|
||||||
jump = p[0].jump;
|
|
||||||
lfsr_rbyd_p_pop(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO need this? does this ever get triggered?
|
// TODO need this? does this ever get triggered?
|
||||||
// both diverging? collapse
|
// both diverging? collapse
|
||||||
// <r >b
|
// <r >b
|
||||||
@@ -3865,41 +3817,40 @@ trunk:;
|
|||||||
// branch = branch_;
|
// branch = branch_;
|
||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
goto maybetrim;
|
// goto maybetrim;
|
||||||
}
|
}
|
||||||
// diverged?
|
// diverged?
|
||||||
// : :
|
|
||||||
// <b => nb
|
// <b => nb
|
||||||
// .-'| .--'
|
// .-'| .--'
|
||||||
// 3 4 3 4 x
|
// 3 4 3 4 x
|
||||||
} else if (diverged) {
|
} else if (diverged) {
|
||||||
diverging = lfsr_tag_diverging2(
|
// diverging = lfsr_tag_diverging2(
|
||||||
alt, weight,
|
// alt, weight,
|
||||||
p[0].alt, p[0].weight,
|
// p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
// lower_rid, upper_rid,
|
||||||
a_rid, a_tag,
|
// a_rid, a_tag,
|
||||||
b_rid, b_tag);
|
// b_rid, b_tag);
|
||||||
diverging_red = lfsr_tag_isred(p[0].alt)
|
// diverging_red = lfsr_tag_isred(p[0].alt)
|
||||||
&& lfsr_tag_diverging(
|
// && lfsr_tag_diverging(
|
||||||
p[0].alt, p[0].weight,
|
// p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
// lower_rid, upper_rid,
|
||||||
a_rid, a_tag,
|
// a_rid, a_tag,
|
||||||
b_rid, b_tag);
|
// b_rid, b_tag);
|
||||||
// TODO I think this logic is wrong, what's correct here?
|
// // TODO I think this logic is wrong, what's correct here?
|
||||||
if (diverging_red) {
|
// if (diverging_red) {
|
||||||
LFS_DEBUG("%04x->%04x: div r trimming",
|
// LFS_DEBUG("%04x->%04x: div r trimming",
|
||||||
branch, lfsr_rbyd_eoff(rbyd));
|
// branch, lfsr_rbyd_eoff(rbyd));
|
||||||
// trim so alt is pruned
|
// // trim so alt is pruned
|
||||||
lfsr_tag_trim(
|
// lfsr_tag_trim(
|
||||||
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);
|
||||||
p[0].weight = 0;
|
// p[0].weight = 0;
|
||||||
|
//
|
||||||
lfsr_rbyd_p_pop(p);
|
// lfsr_rbyd_p_pop(p);
|
||||||
|
//
|
||||||
// TODO prune? (trim?)
|
// // TODO prune? (trim?)
|
||||||
}
|
// }
|
||||||
|
|
||||||
diverging = lfsr_tag_diverging2(
|
diverging = lfsr_tag_diverging2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
@@ -3907,9 +3858,9 @@ trunk:;
|
|||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
a_rid, a_tag,
|
a_rid, a_tag,
|
||||||
b_rid, b_tag);
|
b_rid, b_tag);
|
||||||
if (diverging
|
if (diverging) {
|
||||||
&& (!lfsr_tag_isred(alt)
|
// && (!lfsr_tag_isred(alt)
|
||||||
|| lfsr_tag_isred(p[0].alt))) {
|
// || lfsr_tag_isred(p[0].alt))) {
|
||||||
LFS_DEBUG("%04x->%04x: div b trimming",
|
LFS_DEBUG("%04x->%04x: div b trimming",
|
||||||
branch, lfsr_rbyd_eoff(rbyd));
|
branch, lfsr_rbyd_eoff(rbyd));
|
||||||
// trim so alt is pruned
|
// trim so alt is pruned
|
||||||
@@ -3918,79 +3869,109 @@ trunk:;
|
|||||||
&lower_rid, &upper_rid,
|
&lower_rid, &upper_rid,
|
||||||
&lower_tag, &upper_tag);
|
&lower_tag, &upper_tag);
|
||||||
weight = 0;
|
weight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
maybetrim:;
|
// prune red alts
|
||||||
// prune other unreachable alts
|
if (lfsr_tag_isred(p[0].alt)
|
||||||
// <b >b
|
&& lfsr_tag_unreachable(
|
||||||
// .-'| .-'|
|
p[0].alt, p[0].weight,
|
||||||
// <y | | <b
|
lower_rid, upper_rid,
|
||||||
// .-------'| | .-----------|-'|
|
lower_tag, upper_tag)) {
|
||||||
// | <r | => | | |
|
// prune unreachable recolorable alts
|
||||||
// | .----' | | | |
|
// <r => <b
|
||||||
// | | <b | <b |
|
// .----'| .----'|
|
||||||
// | | .----'| | .----'| |
|
// | <b | |
|
||||||
// 1 2 3 4 4 1 2 3 4 4 2
|
// | .-'| | .--'
|
||||||
if (lfsr_tag_unreachable2(
|
// 1 2 3 1 2 3 x
|
||||||
alt, weight,
|
// this includes unreachable yellow alts in yellow splits
|
||||||
p[0].alt, p[0].weight,
|
// <b >b
|
||||||
lower_rid, upper_rid,
|
// .-'| .-'|
|
||||||
lower_tag, upper_tag)) {
|
// <y | | |
|
||||||
// prune unreachable recolorable alts
|
// .-------'| | | |
|
||||||
// : :
|
// | <r | => | >b
|
||||||
// <r => <b
|
// | .----' | .--------|-'|
|
||||||
// .----'| .-------'|
|
// | | <b | <b |
|
||||||
// | <b | |
|
// | | .----'| | .----'| |
|
||||||
// | .-'| | .-----'
|
// 1 2 3 4 4 1 2 3 4 4 1
|
||||||
// 1 2 3 1 2 3 x
|
LFS_DEBUG("%04x->%04x: yprune",
|
||||||
if (lfsr_tag_isred(p[0].alt)) {
|
branch, lfsr_rbyd_eoff(rbyd));
|
||||||
LFS_DEBUG("%04x->%04x: rtrim",
|
if (p[0].jump > branch) {
|
||||||
branch, lfsr_rbyd_eoff(rbyd));
|
alt &= ~LFSR_TAG_R;
|
||||||
alt = p[0].alt & ~LFSR_TAG_R;
|
}
|
||||||
weight = p[0].weight;
|
lfsr_rbyd_p_pop(p);
|
||||||
jump = p[0].jump;
|
}
|
||||||
lfsr_rbyd_p_pop(p);
|
|
||||||
|
|
||||||
// TODO redoc
|
// prune black alts
|
||||||
// TODO does this ever get hit?
|
if (lfsr_tag_unreachable2(
|
||||||
// prune unreachable root alts and red alts
|
alt, weight,
|
||||||
// : :
|
p[0].alt, p[0].weight,
|
||||||
// <r => <b
|
lower_rid, upper_rid,
|
||||||
// .----'| .----'|
|
lower_tag, upper_tag)) {
|
||||||
// | <b | |
|
// prune unreachable recolorable alts
|
||||||
// | .-'| | .--'
|
// <r => <b
|
||||||
// 3 4 5 3 4 5 x
|
// .----'| .-------'|
|
||||||
} else if (!p[0].alt) { //|| lfsr_tag_isred(alt)) {
|
// | <b | |
|
||||||
LFS_DEBUG("%04x->%04x: ztrim",
|
// | .-'| | .-----'
|
||||||
branch, lfsr_rbyd_eoff(rbyd));
|
// 1 2 3 1 2 3 x
|
||||||
branch = branch_;
|
// this includes unreachable red alts in yellow splits
|
||||||
continue;
|
// <b >b
|
||||||
|
// .-'| .-'|
|
||||||
// mark unreachable non-root black alts as unreachable,
|
// <y | | <b
|
||||||
// we can't prune these or we risk breaking the color
|
// .-------'| | .-----------|-'|
|
||||||
// balance of our tree, but if we push a red up later we
|
// | <r | => | | |
|
||||||
// can get rid of them
|
// | .----' | | | |
|
||||||
// : :
|
// | | <b | <b |
|
||||||
// <b => nb
|
// | | .----'| | .----'| |
|
||||||
// .-'| .--'
|
// 1 2 3 4 4 1 2 3 4 4 2
|
||||||
// 3 4 3 4 x
|
if (lfsr_tag_isred(p[0].alt)) {
|
||||||
} else if (!lfsr_tag_isred(alt)) {
|
LFS_DEBUG("%04x->%04x: rprune",
|
||||||
LFS_DEBUG("%04x->%04x: btrim",
|
branch, lfsr_rbyd_eoff(rbyd));
|
||||||
branch, lfsr_rbyd_eoff(rbyd));
|
alt = (p[0].alt & ~LFSR_TAG_R) | (alt & LFSR_TAG_R);
|
||||||
alt = LFSR_TAG_ALT(
|
if (jump > branch) {
|
||||||
LFSR_TAG_B,
|
alt &= ~LFSR_TAG_R;
|
||||||
LFSR_TAG_LE,
|
|
||||||
(diverged && !(a_rid < b_rid || a_tag < b_tag))
|
|
||||||
? d_tag
|
|
||||||
: lower_tag);
|
|
||||||
// TODO hmmmmm?
|
|
||||||
LFS_ASSERT(weight == 0);
|
|
||||||
//weight = 0;
|
|
||||||
// we don't need to, but setting jump=0 asserts this
|
|
||||||
// alt is unreachable while also minimizing the the
|
|
||||||
// encoding
|
|
||||||
jump = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
weight = p[0].weight;
|
||||||
|
jump = p[0].jump;
|
||||||
|
lfsr_rbyd_p_pop(p);
|
||||||
|
|
||||||
|
// TODO redoc
|
||||||
|
// TODO does this ever get hit?
|
||||||
|
// prune unreachable root alts and red alts
|
||||||
|
// <r => <b
|
||||||
|
// .----'| .----'|
|
||||||
|
// | <b | |
|
||||||
|
// | .-'| | .--'
|
||||||
|
// 3 4 5 3 4 5 x
|
||||||
|
} else if (!p[0].alt) { //|| lfsr_tag_isred(alt)) {
|
||||||
|
LFS_DEBUG("%04x->%04x: ztrim",
|
||||||
|
branch, lfsr_rbyd_eoff(rbyd));
|
||||||
|
branch = branch_;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// mark unreachable non-root black alts as unreachable (
|
||||||
|
// jump=0), we can't prune these right now or we risk
|
||||||
|
// breaking the color balance of our tree, but if we
|
||||||
|
// push up a red edge later we can get rid of these
|
||||||
|
// <b => nb
|
||||||
|
// .-'| .--'
|
||||||
|
// 3 4 3 4 x
|
||||||
|
} else if (!lfsr_tag_isred(alt)) {
|
||||||
|
LFS_DEBUG("%04x->%04x: btrim",
|
||||||
|
branch, lfsr_rbyd_eoff(rbyd));
|
||||||
|
alt = LFSR_TAG_ALT(
|
||||||
|
LFSR_TAG_B,
|
||||||
|
LFSR_TAG_LE,
|
||||||
|
(diverged && !(a_rid < b_rid || a_tag < b_tag))
|
||||||
|
? d_tag
|
||||||
|
: lower_tag);
|
||||||
|
// TODO hmmmmm?
|
||||||
|
LFS_ASSERT(weight == 0);
|
||||||
|
//weight = 0;
|
||||||
|
// we don't need to, but setting jump=0 asserts this
|
||||||
|
// alt is unreachable while also minimizing the the
|
||||||
|
// encoding
|
||||||
|
jump = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4011,6 +3992,7 @@ trunk:;
|
|||||||
if (branch_ < branch) {
|
if (branch_ < branch) {
|
||||||
LFS_DEBUG("%04x->%04x: ysplit b",
|
LFS_DEBUG("%04x->%04x: ysplit b",
|
||||||
branch, lfsr_rbyd_eoff(rbyd));
|
branch, lfsr_rbyd_eoff(rbyd));
|
||||||
|
// TODO this shouldn't happen?
|
||||||
// TODO hwat, >= solves this??
|
// TODO hwat, >= solves this??
|
||||||
if (jump == branch){
|
if (jump == branch){
|
||||||
LFS_DEBUG("%04x->%04x: ysplit b jump == branch",
|
LFS_DEBUG("%04x->%04x: ysplit b jump == branch",
|
||||||
|
|||||||
Reference in New Issue
Block a user