rbyd-rr: Adopted a struct-based p-alt fifo representation
So instead of:
lfsr_tag_t p_alts[3];
lfsr_rid_t p_weights[3];
lfs_size_t p_jumps[3];
We now have:
lfsr_alt_t p[3];
Note this is the only place where we use the new lfsr_alt_t type,
hopefully using such a general name doesn't create confusion down the
road...
I was mostly just curious which representation the compiler
(GCC 11.4 -mthumb) would handle better. In theory a struct
representation will result in more efficient memmoves, since we usually
operate on entire alts at a time when manipulting our fifo.
The original motivation for the separate arrays was to avoid alignment
issues with the 16-bit lfsr_tag_t, but this was apparently premature:
code stack
before: 34644 2864
after: 34480 (-0.5%) 2864 (+0.0%)
code frame stack
appendattr before: 2452 216 568
appendattr after: 2404 (-2.0%) 216 (+0.0%) 568 (+0.0%)
Actually, it's a bit strange that lfsr_rbyd_appendattr showed _no_ stack
changes... I wonder why that is?
This commit is contained in:
@@ -2657,18 +2657,22 @@ static int lfsr_rbyd_prepareappend(lfs_t *lfs, lfsr_rbyd_t *rbyd) {
|
|||||||
|
|
||||||
// helper functions for managing the 3-element fifo used in
|
// helper functions for managing the 3-element fifo used in
|
||||||
// lfsr_rbyd_appendattr
|
// lfsr_rbyd_appendattr
|
||||||
|
typedef struct lfsr_alt {
|
||||||
|
lfsr_tag_t alt;
|
||||||
|
lfsr_rid_t weight;
|
||||||
|
lfs_size_t jump;
|
||||||
|
} lfsr_alt_t;
|
||||||
|
|
||||||
static int lfsr_rbyd_p_flush(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
static int lfsr_rbyd_p_flush(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
||||||
lfsr_tag_t p_alts[static 3],
|
lfsr_alt_t p[static 3],
|
||||||
lfsr_rid_t p_weights[static 3],
|
|
||||||
lfs_size_t p_jumps[static 3],
|
|
||||||
int count) {
|
int count) {
|
||||||
// write out some number of alt pointers in our queue
|
// write out some number of alt pointers in our queue
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
if (p_alts[3-1-i]) {
|
if (p[3-1-i].alt) {
|
||||||
// change to a relative jump at the last minute
|
// change to a relative jump at the last minute
|
||||||
lfsr_tag_t alt = p_alts[3-1-i];
|
lfsr_tag_t alt = p[3-1-i].alt;
|
||||||
lfsr_rid_t weight = p_weights[3-1-i];
|
lfsr_rid_t weight = p[3-1-i].weight;
|
||||||
lfs_size_t jump = rbyd->eoff - p_jumps[3-1-i];
|
lfs_size_t jump = rbyd->eoff - p[3-1-i].jump;
|
||||||
|
|
||||||
int err = lfsr_rbyd_appendtag(lfs, rbyd, alt, weight, jump);
|
int err = lfsr_rbyd_appendtag(lfs, rbyd, alt, weight, jump);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -2681,83 +2685,66 @@ static int lfsr_rbyd_p_flush(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline int lfsr_rbyd_p_push(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
static inline int lfsr_rbyd_p_push(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
||||||
lfsr_tag_t p_alts[static 3],
|
lfsr_alt_t p[static 3],
|
||||||
lfsr_rid_t p_weights[static 3],
|
|
||||||
lfs_size_t p_jumps[static 3],
|
|
||||||
lfsr_tag_t alt, lfsr_srid_t weight, lfs_size_t jump) {
|
lfsr_tag_t alt, lfsr_srid_t weight, lfs_size_t jump) {
|
||||||
int err = lfsr_rbyd_p_flush(lfs, rbyd, p_alts, p_weights, p_jumps, 1);
|
int err = lfsr_rbyd_p_flush(lfs, rbyd, p, 1);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
memmove(p_alts+1, p_alts, 2*sizeof(lfsr_tag_t));
|
memmove(p+1, p, 2*sizeof(lfsr_alt_t));
|
||||||
memmove(p_weights+1, p_weights, 2*sizeof(lfsr_rid_t));
|
p[0].alt = alt;
|
||||||
memmove(p_jumps+1, p_jumps, 2*sizeof(lfs_size_t));
|
p[0].weight = weight;
|
||||||
p_alts[0] = alt;
|
p[0].jump = jump;
|
||||||
p_weights[0] = weight;
|
|
||||||
p_jumps[0] = jump;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void lfsr_rbyd_p_pop(
|
static inline void lfsr_rbyd_p_pop(
|
||||||
lfsr_tag_t p_alts[static 3],
|
lfsr_alt_t p[static 3]) {
|
||||||
lfsr_rid_t p_weights[static 3],
|
memmove(p, p+1, 2*sizeof(lfsr_alt_t));
|
||||||
lfs_size_t p_jumps[static 3]) {
|
p[2].alt = 0;
|
||||||
memmove(p_alts, p_alts+1, 2*sizeof(lfsr_tag_t));
|
|
||||||
memmove(p_weights, p_weights+1, 2*sizeof(lfsr_rid_t));
|
|
||||||
memmove(p_jumps, p_jumps+1, 2*sizeof(lfs_size_t));
|
|
||||||
p_alts[2] = 0;
|
|
||||||
p_weights[2] = 0;
|
|
||||||
p_jumps[2] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lfsr_rbyd_p_recolor(
|
static void lfsr_rbyd_p_recolor(
|
||||||
lfsr_tag_t p_alts[static 3],
|
lfsr_alt_t p[static 3]) {
|
||||||
lfsr_rid_t p_weights[static 3],
|
|
||||||
lfs_size_t p_jumps[static 3]) {
|
|
||||||
// propagate a red edge upwards
|
// propagate a red edge upwards
|
||||||
p_alts[0] &= ~LFSR_TAG_R;
|
p[0].alt &= ~LFSR_TAG_R;
|
||||||
|
|
||||||
if (p_alts[1]) {
|
if (p[1].alt) {
|
||||||
p_alts[1] |= LFSR_TAG_R;
|
p[1].alt |= LFSR_TAG_R;
|
||||||
|
|
||||||
// alt-never? we can prune this now
|
// alt-never? we can prune this now
|
||||||
if (lfsr_tag_isn(p_alts[1])) {
|
if (lfsr_tag_isn(p[1].alt)) {
|
||||||
p_alts[1] = p_alts[2];
|
p[1] = p[2];
|
||||||
p_weights[1] = p_weights[2];
|
p[2].alt = 0;
|
||||||
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
|
||||||
} else if (lfsr_tag_isred(p_alts[2])) {
|
} else if (lfsr_tag_isred(p[2].alt)) {
|
||||||
if (lfsr_tag_isparallel(p_alts[1], p_alts[2])) {
|
if (lfsr_tag_isparallel(p[1].alt, p[2].alt)) {
|
||||||
// no reorder needed
|
// no reorder needed
|
||||||
} else if (lfsr_tag_isparallel(p_alts[0], p_alts[2])) {
|
} else if (lfsr_tag_isparallel(p[0].alt, p[2].alt)) {
|
||||||
lfsr_tag_t alt_ = p_alts[1];
|
lfsr_tag_t alt_ = p[1].alt;
|
||||||
lfsr_rid_t weight_ = p_weights[1];
|
lfsr_rid_t weight_ = p[1].weight;
|
||||||
lfs_size_t jump_ = p_jumps[1];
|
lfs_size_t jump_ = p[1].jump;
|
||||||
p_alts[1] = p_alts[0] | LFSR_TAG_R;
|
p[1].alt = p[0].alt | LFSR_TAG_R;
|
||||||
p_weights[1] = p_weights[0];
|
p[1].weight = p[0].weight;
|
||||||
p_jumps[1] = p_jumps[0];
|
p[1].jump = p[0].jump;
|
||||||
p_alts[0] = alt_ & ~LFSR_TAG_R;
|
p[0].alt = alt_ & ~LFSR_TAG_R;
|
||||||
p_weights[0] = weight_;
|
p[0].weight = weight_;
|
||||||
p_jumps[0] = jump_;
|
p[0].jump = jump_;
|
||||||
} else if (lfsr_tag_isparallel(p_alts[0], p_alts[1])) {
|
} else if (lfsr_tag_isparallel(p[0].alt, p[1].alt)) {
|
||||||
lfsr_tag_t alt_ = p_alts[2];
|
lfsr_tag_t alt_ = p[2].alt;
|
||||||
lfsr_rid_t weight_ = p_weights[2];
|
lfsr_rid_t weight_ = p[2].weight;
|
||||||
lfs_size_t jump_ = p_jumps[2];
|
lfs_size_t jump_ = p[2].jump;
|
||||||
p_alts[2] = p_alts[1] | LFSR_TAG_R;
|
p[2].alt = p[1].alt | LFSR_TAG_R;
|
||||||
p_weights[2] = p_weights[1];
|
p[2].weight = p[1].weight;
|
||||||
p_jumps[2] = p_jumps[1];
|
p[2].jump = p[1].jump;
|
||||||
p_alts[1] = p_alts[0] | LFSR_TAG_R;
|
p[1].alt = p[0].alt | LFSR_TAG_R;
|
||||||
p_weights[1] = p_weights[0];
|
p[1].weight = p[0].weight;
|
||||||
p_jumps[1] = p_jumps[0];
|
p[1].jump = p[0].jump;
|
||||||
p_alts[0] = alt_ & ~LFSR_TAG_R;
|
p[0].alt = alt_ & ~LFSR_TAG_R;
|
||||||
p_weights[0] = weight_;
|
p[0].weight = weight_;
|
||||||
p_jumps[0] = jump_;
|
p[0].jump = jump_;
|
||||||
} else {
|
} else {
|
||||||
LFS_UNREACHABLE();
|
LFS_UNREACHABLE();
|
||||||
}
|
}
|
||||||
@@ -2905,9 +2892,7 @@ again:;
|
|||||||
lfsr_tag_t tag_ = 0;
|
lfsr_tag_t tag_ = 0;
|
||||||
|
|
||||||
// queue of pending alts we can emulate rotations with
|
// queue of pending alts we can emulate rotations with
|
||||||
lfsr_tag_t p_alts[3] = {0, 0, 0};
|
lfsr_alt_t p[3] = {{0}, {0}, {0}};
|
||||||
lfsr_rid_t p_weights[3] = {0, 0, 0};
|
|
||||||
lfs_size_t p_jumps[3] = {0, 0, 0};
|
|
||||||
|
|
||||||
// keep track of the last incoming branch for yellow splits
|
// keep track of the last incoming branch for yellow splits
|
||||||
lfs_size_t y_branch = 0;
|
lfs_size_t y_branch = 0;
|
||||||
@@ -2915,7 +2900,7 @@ again:;
|
|||||||
// descend down tree, building alt pointers
|
// descend down tree, building alt pointers
|
||||||
while (true) {
|
while (true) {
|
||||||
// keep track of incoming branch
|
// keep track of incoming branch
|
||||||
if (lfsr_tag_isblack(p_alts[0])) {
|
if (lfsr_tag_isblack(p[0].alt)) {
|
||||||
y_branch = branch;
|
y_branch = branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2941,70 +2926,70 @@ again:;
|
|||||||
// diverging black?
|
// diverging black?
|
||||||
&& (((lfsr_tag_isblack(alt)
|
&& (((lfsr_tag_isblack(alt)
|
||||||
// give up if we find a yellow alt
|
// give up if we find a yellow alt
|
||||||
|| lfsr_tag_isred(p_alts[0]))
|
|| lfsr_tag_isred(p[0].alt))
|
||||||
&& lfsr_tag_follow2(
|
&& lfsr_tag_follow2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
a_rid, a_tag)
|
a_rid, a_tag)
|
||||||
^ lfsr_tag_follow2(
|
^ lfsr_tag_follow2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
b_rid, b_tag))
|
b_rid, b_tag))
|
||||||
// diverging red?
|
// diverging red?
|
||||||
|| (lfsr_tag_isred(p_alts[0])
|
|| (lfsr_tag_isred(p[0].alt)
|
||||||
&& lfsr_tag_follow(
|
&& lfsr_tag_follow(
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
a_rid, a_tag)
|
a_rid, a_tag)
|
||||||
^ lfsr_tag_follow(
|
^ lfsr_tag_follow(
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
b_rid, b_tag)))) {
|
b_rid, b_tag)))) {
|
||||||
d_state = lfsr_d_diverge(d_state);
|
d_state = lfsr_d_diverge(d_state);
|
||||||
|
|
||||||
// diverged red? flip
|
// diverged red? flip
|
||||||
if (lfsr_tag_isred(p_alts[0])
|
if (lfsr_tag_isred(p[0].alt)
|
||||||
&& (lfsr_tag_follow(
|
&& (lfsr_tag_follow(
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
a_rid, a_tag)
|
a_rid, a_tag)
|
||||||
^ lfsr_tag_follow(
|
^ lfsr_tag_follow(
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
b_rid, b_tag))) {
|
b_rid, b_tag))) {
|
||||||
if (lfsr_tag_isparallel(alt, p_alts[0])) {
|
if (lfsr_tag_isparallel(alt, p[0].alt)) {
|
||||||
lfsr_tag_flip2(&alt, &weight,
|
lfsr_tag_flip2(&alt, &weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid);
|
lower_rid, upper_rid);
|
||||||
lfs_swap32(&jump, &branch_);
|
lfs_swap32(&jump, &branch_);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfs_swap16(&p_alts[0], &alt);
|
lfs_swap16(&p[0].alt, &alt);
|
||||||
lfs_swap32(&p_weights[0], &weight);
|
lfs_swap32(&p[0].weight, &weight);
|
||||||
lfs_swap32(&p_jumps[0], &jump);
|
lfs_swap32(&p[0].jump, &jump);
|
||||||
p_alts[0] |= LFSR_TAG_R;
|
p[0].alt |= LFSR_TAG_R;
|
||||||
alt &= ~LFSR_TAG_R;
|
alt &= ~LFSR_TAG_R;
|
||||||
|
|
||||||
// both diverging? collapse
|
// both diverging? collapse
|
||||||
if (lfsr_tag_follow(
|
if (lfsr_tag_follow(
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
a_rid, a_tag)
|
a_rid, a_tag)
|
||||||
^ lfsr_tag_follow(
|
^ lfsr_tag_follow(
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
b_rid, b_tag)) {
|
b_rid, b_tag)) {
|
||||||
LFS_ASSERT(!lfsr_tag_isparallel(alt, p_alts[0]));
|
LFS_ASSERT(!lfsr_tag_isparallel(alt, p[0].alt));
|
||||||
lfsr_tag_flip2(&alt, &weight,
|
lfsr_tag_flip2(&alt, &weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid);
|
lower_rid, upper_rid);
|
||||||
lfs_swap32(&jump, &branch_);
|
lfs_swap32(&jump, &branch_);
|
||||||
|
|
||||||
weight += p_weights[0];
|
weight += p[0].weight;
|
||||||
jump = p_jumps[0];
|
jump = p[0].jump;
|
||||||
lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps);
|
lfsr_rbyd_p_pop(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3014,7 +2999,7 @@ again:;
|
|||||||
if (lfsr_tag_isgt(alt)) {
|
if (lfsr_tag_isgt(alt)) {
|
||||||
lfsr_tag_flip2(
|
lfsr_tag_flip2(
|
||||||
&alt, &weight,
|
&alt, &weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid);
|
lower_rid, upper_rid);
|
||||||
lfs_swap32(&jump, &branch_);
|
lfs_swap32(&jump, &branch_);
|
||||||
}
|
}
|
||||||
@@ -3022,13 +3007,12 @@ again:;
|
|||||||
// trim
|
// trim
|
||||||
lfsr_tag_trim2(
|
lfsr_tag_trim2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
&lower_rid, &upper_rid,
|
&lower_rid, &upper_rid,
|
||||||
&lower_tag, &upper_tag);
|
&lower_tag, &upper_tag);
|
||||||
|
|
||||||
// stitch together both trunks
|
// stitch together both trunks
|
||||||
err = lfsr_rbyd_p_push(lfs, rbyd,
|
err = lfsr_rbyd_p_push(lfs, rbyd, p,
|
||||||
p_alts, p_weights, p_jumps,
|
|
||||||
LFSR_TAG_ALT(LFSR_TAG_LE, LFSR_TAG_B, d_tag),
|
LFSR_TAG_ALT(LFSR_TAG_LE, LFSR_TAG_B, d_tag),
|
||||||
d_rid - (lower_rid - weight),
|
d_rid - (lower_rid - weight),
|
||||||
jump);
|
jump);
|
||||||
@@ -3047,17 +3031,17 @@ again:;
|
|||||||
^ lfsr_tag_isgt(alt)
|
^ lfsr_tag_isgt(alt)
|
||||||
^ lfsr_tag_follow2(
|
^ lfsr_tag_follow2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
a_rid, a_tag))) {
|
a_rid, a_tag))) {
|
||||||
if (lfsr_tag_follow2(
|
if (lfsr_tag_follow2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
a_rid, a_tag)) {
|
a_rid, a_tag)) {
|
||||||
lfsr_tag_flip2(
|
lfsr_tag_flip2(
|
||||||
&alt, &weight,
|
&alt, &weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid);
|
lower_rid, upper_rid);
|
||||||
lfs_swap32(&jump, &branch_);
|
lfs_swap32(&jump, &branch_);
|
||||||
}
|
}
|
||||||
@@ -3081,32 +3065,32 @@ again:;
|
|||||||
// 1 2 3 4 4 1 2 3 4 4 2
|
// 1 2 3 4 4 1 2 3 4 4 2
|
||||||
if (lfsr_tag_unavoidable2(
|
if (lfsr_tag_unavoidable2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
lower_tag, upper_tag)
|
lower_tag, upper_tag)
|
||||||
|| lfsr_tag_unreachable2(
|
|| lfsr_tag_unreachable2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
lower_tag, upper_tag)) {
|
lower_tag, upper_tag)) {
|
||||||
// note if only yellow pruning this could be much simpler
|
// note if only yellow pruning this could be much simpler
|
||||||
if (lfsr_tag_unavoidable2(
|
if (lfsr_tag_unavoidable2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
lower_tag, upper_tag)) {
|
lower_tag, upper_tag)) {
|
||||||
lfs_swap32(&jump, &branch_);
|
lfs_swap32(&jump, &branch_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// prune unreachable red-black alts
|
// prune unreachable red-black alts
|
||||||
if (lfsr_tag_isred(p_alts[0])) {
|
if (lfsr_tag_isred(p[0].alt)) {
|
||||||
alt = p_alts[0] & ~LFSR_TAG_R;
|
alt = p[0].alt & ~LFSR_TAG_R;
|
||||||
weight = p_weights[0];
|
weight = p[0].weight;
|
||||||
jump = p_jumps[0];
|
jump = p[0].jump;
|
||||||
lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps);
|
lfsr_rbyd_p_pop(p);
|
||||||
|
|
||||||
// prune unreachable root alts and red alts
|
// prune unreachable root alts and red alts
|
||||||
} else if (!p_alts[0] || lfsr_tag_isred(alt)) {
|
} else if (!p[0].alt || lfsr_tag_isred(alt)) {
|
||||||
branch = branch_;
|
branch = branch_;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -3120,8 +3104,8 @@ again:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// two reds makes a yellow, split?
|
// two reds makes a yellow, split?
|
||||||
if (lfsr_tag_isred(alt) && lfsr_tag_isred(p_alts[0])) {
|
if (lfsr_tag_isred(alt) && lfsr_tag_isred(p[0].alt)) {
|
||||||
LFS_ASSERT(lfsr_tag_isparallel(alt, p_alts[0]));
|
LFS_ASSERT(lfsr_tag_isparallel(alt, p[0].alt));
|
||||||
|
|
||||||
// if we take the red or yellow alt we can just point
|
// if we take the red or yellow alt we can just point
|
||||||
// to the black alt
|
// to the black alt
|
||||||
@@ -3134,24 +3118,24 @@ again:;
|
|||||||
// 1 2 3 4 1 2 3 4 1
|
// 1 2 3 4 1 2 3 4 1
|
||||||
if (lfsr_tag_follow2(
|
if (lfsr_tag_follow2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
a_rid, a_tag)) {
|
a_rid, a_tag)) {
|
||||||
lfsr_tag_flip2(&alt, &weight,
|
lfsr_tag_flip2(&alt, &weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid);
|
lower_rid, upper_rid);
|
||||||
lfs_swap32(&jump, &branch_);
|
lfs_swap32(&jump, &branch_);
|
||||||
|
|
||||||
lfs_swap16(&p_alts[0], &alt);
|
lfs_swap16(&p[0].alt, &alt);
|
||||||
lfs_swap32(&p_weights[0], &weight);
|
lfs_swap32(&p[0].weight, &weight);
|
||||||
lfs_swap32(&p_jumps[0], &jump);
|
lfs_swap32(&p[0].jump, &jump);
|
||||||
alt &= ~LFSR_TAG_R;
|
alt &= ~LFSR_TAG_R;
|
||||||
|
|
||||||
lfsr_tag_trim(
|
lfsr_tag_trim(
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
&lower_rid, &upper_rid,
|
&lower_rid, &upper_rid,
|
||||||
&lower_tag, &upper_tag);
|
&lower_tag, &upper_tag);
|
||||||
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps);
|
lfsr_rbyd_p_recolor(p);
|
||||||
|
|
||||||
// otherwise we need to point to the yellow alt and
|
// otherwise we need to point to the yellow alt and
|
||||||
// prune later
|
// prune later
|
||||||
@@ -3166,15 +3150,15 @@ again:;
|
|||||||
// 1 2 3 4 1 2 3 4 4
|
// 1 2 3 4 1 2 3 4 4
|
||||||
} else {
|
} else {
|
||||||
LFS_ASSERT(y_branch != 0);
|
LFS_ASSERT(y_branch != 0);
|
||||||
p_alts[0] = alt;
|
p[0].alt = alt;
|
||||||
p_weights[0] += weight;
|
p[0].weight += weight;
|
||||||
p_jumps[0] = y_branch;
|
p[0].jump = y_branch;
|
||||||
|
|
||||||
lfsr_tag_trim(
|
lfsr_tag_trim(
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
&lower_rid, &upper_rid,
|
&lower_rid, &upper_rid,
|
||||||
&lower_tag, &upper_tag);
|
&lower_tag, &upper_tag);
|
||||||
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps);
|
lfsr_rbyd_p_recolor(p);
|
||||||
|
|
||||||
branch = branch_;
|
branch = branch_;
|
||||||
continue;
|
continue;
|
||||||
@@ -3189,11 +3173,11 @@ again:;
|
|||||||
// 1 2 1 2 1
|
// 1 2 1 2 1
|
||||||
if (lfsr_tag_follow2(
|
if (lfsr_tag_follow2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
a_rid, a_tag)) {
|
a_rid, a_tag)) {
|
||||||
lfsr_tag_flip2(&alt, &weight,
|
lfsr_tag_flip2(&alt, &weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid);
|
lower_rid, upper_rid);
|
||||||
lfs_swap32(&jump, &branch_);
|
lfs_swap32(&jump, &branch_);
|
||||||
}
|
}
|
||||||
@@ -3204,18 +3188,18 @@ again:;
|
|||||||
// | <b => | >b
|
// | <b => | >b
|
||||||
// | .-'| .--|-'|
|
// | .-'| .--|-'|
|
||||||
// 1 2 3 1 2 3 1
|
// 1 2 3 1 2 3 1
|
||||||
if (lfsr_tag_isred(p_alts[0])
|
if (lfsr_tag_isred(p[0].alt)
|
||||||
&& lfsr_tag_follow(p_alts[0], p_weights[0],
|
&& lfsr_tag_follow(p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid,
|
lower_rid, upper_rid,
|
||||||
a_rid, a_tag)) {
|
a_rid, a_tag)) {
|
||||||
lfs_swap16(&p_alts[0], &alt);
|
lfs_swap16(&p[0].alt, &alt);
|
||||||
lfs_swap32(&p_weights[0], &weight);
|
lfs_swap32(&p[0].weight, &weight);
|
||||||
lfs_swap32(&p_jumps[0], &jump);
|
lfs_swap32(&p[0].jump, &jump);
|
||||||
p_alts[0] |= LFSR_TAG_R;
|
p[0].alt |= LFSR_TAG_R;
|
||||||
alt &= ~LFSR_TAG_R;
|
alt &= ~LFSR_TAG_R;
|
||||||
|
|
||||||
lfsr_tag_flip2(&alt, &weight,
|
lfsr_tag_flip2(&alt, &weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
lower_rid, upper_rid);
|
lower_rid, upper_rid);
|
||||||
lfs_swap32(&jump, &branch_);
|
lfs_swap32(&jump, &branch_);
|
||||||
}
|
}
|
||||||
@@ -3223,14 +3207,13 @@ again:;
|
|||||||
// trim alts from our current bounds
|
// trim alts from our current bounds
|
||||||
lfsr_tag_trim2(
|
lfsr_tag_trim2(
|
||||||
alt, weight,
|
alt, weight,
|
||||||
p_alts[0], p_weights[0],
|
p[0].alt, p[0].weight,
|
||||||
&lower_rid, &upper_rid,
|
&lower_rid, &upper_rid,
|
||||||
&lower_tag, &upper_tag);
|
&lower_tag, &upper_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// push alt onto our queue
|
// push alt onto our queue
|
||||||
err = lfsr_rbyd_p_push(lfs, rbyd,
|
err = lfsr_rbyd_p_push(lfs, rbyd, p,
|
||||||
p_alts, p_weights, p_jumps,
|
|
||||||
alt, weight, jump);
|
alt, weight, jump);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
@@ -3249,7 +3232,7 @@ again:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the last alt should always end up black
|
// the last alt should always end up black
|
||||||
LFS_ASSERT(lfsr_tag_isblack(p_alts[0]));
|
LFS_ASSERT(lfsr_tag_isblack(p[0].alt));
|
||||||
|
|
||||||
// diverged lower trunk? move on to upper trunk
|
// diverged lower trunk? move on to upper trunk
|
||||||
if (d_state == LFSR_D_DIVERGEDLOWER) {
|
if (d_state == LFSR_D_DIVERGEDLOWER) {
|
||||||
@@ -3259,8 +3242,7 @@ again:;
|
|||||||
d_tag = lower_tag;
|
d_tag = lower_tag;
|
||||||
|
|
||||||
// flush any pending alts
|
// flush any pending alts
|
||||||
err = lfsr_rbyd_p_flush(lfs, rbyd,
|
err = lfsr_rbyd_p_flush(lfs, rbyd, p, 3);
|
||||||
p_alts, p_weights, p_jumps, 3);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -3349,20 +3331,18 @@ again:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (alt) {
|
if (alt) {
|
||||||
err = lfsr_rbyd_p_push(lfs, rbyd,
|
err = lfsr_rbyd_p_push(lfs, rbyd, p,
|
||||||
p_alts, p_weights, p_jumps,
|
|
||||||
alt, weight, branch);
|
alt, weight, branch);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// introduce a red edge
|
// introduce a red edge
|
||||||
lfsr_rbyd_p_recolor(p_alts, p_weights, p_jumps);
|
lfsr_rbyd_p_recolor(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// flush any pending alts
|
// flush any pending alts
|
||||||
err = lfsr_rbyd_p_flush(lfs, rbyd,
|
err = lfsr_rbyd_p_flush(lfs, rbyd, p, 3);
|
||||||
p_alts, p_weights, p_jumps, 3);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user