A different thought on tracking found tags during lfs_rbyd_append

The idea here is to just use a separate variable for found tags, instead
of stealing a bit for tracking which tags were found.

I was hoping this would simplify more operations on the tags to avoid
some masking operations, but it doesn't seem like it.
This commit is contained in:
Christopher Haster
2023-01-06 17:03:49 -06:00
parent 3d008b793d
commit 209e70897c
+33 -33
View File
@@ -1518,22 +1518,22 @@ static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_,
} }
// figure out the range of tags to replace // figure out the range of tags to replace
lfs_rtag_t lower_tag_; lfs_rtag_t lower_tag;
lfs_rtag_t upper_tag_; lfs_rtag_t upper_tag;
if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) { if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) {
LFS_ASSERT(rbyd_->count < 0xffff); LFS_ASSERT(rbyd_->count < 0xffff);
lower_tag_ = tag & ~0x7fff; lower_tag = tag & ~0x7fff;
upper_tag_ = lower_tag_; upper_tag = lower_tag;
} else if (lfs_rtag_type1(tag) == LFS_TYPE1_DELETE) { } else if (lfs_rtag_type1(tag) == LFS_TYPE1_DELETE) {
LFS_ASSERT(rbyd_->count > 0); LFS_ASSERT(rbyd_->count > 0);
lower_tag_ = tag & ~0x7fff; lower_tag = tag & ~0x7fff;
upper_tag_ = lower_tag_ + 0x8000; upper_tag = lower_tag + 0x8000;
} else if (lfs_rtag_isrm(tag)) { } else if (lfs_rtag_isrm(tag)) {
lower_tag_ = tag & ~0x7; lower_tag = tag & ~0x7;
upper_tag_ = lower_tag_ + 0x8; upper_tag = lower_tag + 0x8;
} else { } else {
lower_tag_ = tag; lower_tag = tag;
upper_tag_ = lower_tag_; upper_tag = lower_tag;
} }
// keep track of bounds as we descend down the tree // keep track of bounds as we descend down the tree
@@ -1546,6 +1546,8 @@ static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_,
lfs_rtag_t lower_upper = (rbyd_->count+1) << 15; lfs_rtag_t lower_upper = (rbyd_->count+1) << 15;
lfs_rtag_t upper_lower = lower_lower; lfs_rtag_t upper_lower = lower_lower;
lfs_rtag_t upper_upper = lower_upper; lfs_rtag_t upper_upper = lower_upper;
lfs_rtag_t lower_tag_ = 0;
lfs_rtag_t upper_tag_ = 0;
// queue of pending alts we can emulate rotations with // queue of pending alts we can emulate rotations with
lfs_rtag_t p_alts[3] = {0, 0, 0}; lfs_rtag_t p_alts[3] = {0, 0, 0};
@@ -1556,8 +1558,9 @@ static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_,
while (true) { while (true) {
// do we need to flip bounds? // do we need to flip bounds?
if (diverged if (diverged
&& !(upper_tag_ & 0x2) && !upper_tag_
&& (!p_alts[0] || lfs_rtag_isblack(p_alts[0]))) { && (!p_alts[0] || lfs_rtag_isblack(p_alts[0]))) {
lfs_swap(&lower_tag, &upper_tag);
lfs_swap(&lower_tag_, &upper_tag_); lfs_swap(&lower_tag_, &upper_tag_);
lfs_swap(&lower_branch, &upper_branch); lfs_swap(&lower_branch, &upper_branch);
lfs_swap(&lower_lower, &upper_lower); lfs_swap(&lower_lower, &upper_lower);
@@ -1581,8 +1584,8 @@ static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_,
lfs_rtag_t branch_ = lower_branch + delta; lfs_rtag_t branch_ = lower_branch + delta;
// do bounds want to take different paths? begin cutting // do bounds want to take different paths? begin cutting
if (!diverged && lfs_rtag_follow_(alt, lower_lower, lower_upper, lower_tag_) if (!diverged && lfs_rtag_follow_(alt, lower_lower, lower_upper, lower_tag)
!= lfs_rtag_follow_(alt, lower_lower, lower_upper, upper_tag_)) { != lfs_rtag_follow_(alt, lower_lower, lower_upper, upper_tag)) {
diverged = true; diverged = true;
upper_branch = lower_branch; upper_branch = lower_branch;
upper_lower = lower_lower; upper_lower = lower_lower;
@@ -1604,16 +1607,16 @@ static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_,
prune = true; prune = true;
// cut while following // cut while following
} else if (diverged } else if (diverged
&& lfs_rtag_follow_(alt, lower_lower, lower_upper, lower_tag_) && lfs_rtag_follow_(alt, lower_lower, lower_upper, lower_tag)
&& (lower_tag_ < upper_tag_) == lfs_rtag_islt(alt)) { && (lower_tag < upper_tag) == lfs_rtag_islt(alt)) {
lfs_rtag_trim_( lfs_rtag_trim_(
lfs_rtag_flip_(alt, lower_lower, lower_upper), lfs_rtag_flip_(alt, lower_lower, lower_upper),
&lower_lower, &lower_upper); &lower_lower, &lower_upper);
prune = true; prune = true;
// cut while not following // cut while not following
} else if (diverged } else if (diverged
&& !lfs_rtag_follow_(alt, lower_lower, lower_upper, lower_tag_) && !lfs_rtag_follow_(alt, lower_lower, lower_upper, lower_tag)
&& (lower_tag_ < upper_tag_) != lfs_rtag_islt(alt)) { && (lower_tag < upper_tag) != lfs_rtag_islt(alt)) {
lfs_rtag_trim_(alt, &lower_lower, &lower_upper); lfs_rtag_trim_(alt, &lower_lower, &lower_upper);
lfs_swap(&jump, &branch_); lfs_swap(&jump, &branch_);
prune = true; prune = true;
@@ -1648,7 +1651,7 @@ static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_,
// | | <b | <b | // | | <b | <b |
// | | .-'| | .-'| | // | | .-'| | .-'| |
// 1 2 3 4 1 2 3 4 1 // 1 2 3 4 1 2 3 4 1
if (lfs_rtag_follow_(alt, lower_lower, lower_upper, lower_tag_)) { if (lfs_rtag_follow_(alt, lower_lower, lower_upper, lower_tag)) {
lfs_swap(&alt, &p_alts[0]); lfs_swap(&alt, &p_alts[0]);
lfs_swap(&jump, &branch_); lfs_swap(&jump, &branch_);
lfs_swap(&jump, &p_jumps[0]); lfs_swap(&jump, &p_jumps[0]);
@@ -1691,7 +1694,7 @@ static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_,
// .-'| => .-'| // .-'| => .-'|
// 1 2 1 2 1 // 1 2 1 2 1
if (lfs_rtag_isblack(alt) if (lfs_rtag_isblack(alt)
&& lfs_rtag_follow_(alt, lower_lower, lower_upper, lower_tag_)) { && lfs_rtag_follow_(alt, lower_lower, lower_upper, lower_tag)) {
alt = lfs_rtag_flip_(alt, lower_lower, lower_upper); alt = lfs_rtag_flip_(alt, lower_lower, lower_upper);
lfs_swap(&jump, &branch_); lfs_swap(&jump, &branch_);
} }
@@ -1705,9 +1708,9 @@ static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_,
// 1 2 3 1 2 3 1 // 1 2 3 1 2 3 1
if (p_alts[0] if (p_alts[0]
&& ((lfs_rtag_islt(p_alts[0]) && ((lfs_rtag_islt(p_alts[0])
&& lower_tag_ < lower_lower) && lower_tag < lower_lower)
|| (lfs_rtag_isgt(p_alts[0]) || (lfs_rtag_isgt(p_alts[0])
&& lower_tag_ >= lower_upper))) { && lower_tag >= lower_upper))) {
LFS_ASSERT(lfs_rtag_isred(p_alts[0])); LFS_ASSERT(lfs_rtag_isred(p_alts[0]));
LFS_ASSERT(lfs_rtag_isblack(alt)); LFS_ASSERT(lfs_rtag_isblack(alt));
@@ -1741,11 +1744,9 @@ static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_,
} else { } else {
// update the tag id // update the tag id
lower_tag_ = lfs_rtag_setid(alt, lfs_rtag_id(lower_upper-1)); lower_tag_ = lfs_rtag_setid(alt, lfs_rtag_id(lower_upper-1));
// mark as found
lower_tag_ |= 0x2;
// if we diverged, we also need to find the other bound // if we diverged, we also need to find the other bound
if (diverged && !(upper_tag_ & 0x2)) { if (diverged && !upper_tag_) {
continue; continue;
} }
@@ -1763,7 +1764,8 @@ stem:;
upper_lower = lower_lower; upper_lower = lower_lower;
upper_upper = lower_upper; upper_upper = lower_upper;
// unflip our bounds so lower_lower/upper_upper is correct // unflip our bounds so lower_lower/upper_upper is correct
} else if (lower_tag_ > upper_tag_) { } else if (lower_tag > upper_tag) {
lfs_swap(&lower_tag, &upper_tag);
lfs_swap(&lower_tag_, &upper_tag_); lfs_swap(&lower_tag_, &upper_tag_);
lfs_swap(&lower_branch, &upper_branch); lfs_swap(&lower_branch, &upper_branch);
lfs_swap(&lower_lower, &upper_lower); lfs_swap(&lower_lower, &upper_lower);
@@ -1781,35 +1783,33 @@ stem:;
// no split needed, prune the removed tag // no split needed, prune the removed tag
} else if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE } else if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE
&& lfs_rtag_weight_(upper_tag_) >= lfs_rtag_weight_(tag & ~0x7fff)) { && lfs_rtag_weight_(upper_tag_) >= upper_tag) {
// increase biased weight when creating // increase biased weight when creating
alt = LFS_MKRALT__(B, GT, alt = LFS_MKRALT__(B, GT,
(upper_upper+0x8000) - (lfs_rtag_weight_(tag)+0x8)); (upper_upper+0x8000) - (lfs_rtag_weight_(tag)+0x8));
jump = upper_branch; jump = upper_branch;
} else if (lfs_rtag_type1(tag) == LFS_TYPE1_DELETE } else if (lfs_rtag_type1(tag) == LFS_TYPE1_DELETE
&& lfs_rtag_weight_(upper_tag_) >= lfs_rtag_weight_(tag & ~0x7fff)+0x8000) { && lfs_rtag_weight_(upper_tag_) >= upper_tag) {
// decrease biased weight when deleting // decrease biased weight when deleting
alt = LFS_MKRALT__(B, GT, alt = LFS_MKRALT__(B, GT,
upper_upper-0x8000 - lower_lower); upper_upper-0x8000 - lower_lower);
jump = upper_branch; jump = upper_branch;
} else if (lfs_rtag_type1(tag) != LFS_TYPE1_DELETE } else if (lfs_rtag_isrm(tag)
&& lfs_rtag_isrm(tag) && lfs_rtag_weight_(upper_tag_) >= upper_tag) {
&& lfs_rtag_weight_(upper_tag_) > lfs_rtag_weight_(tag)) {
// hide our tag during removes // hide our tag during removes
alt = LFS_MKRALT__(B, GT, alt = LFS_MKRALT__(B, GT,
upper_upper - lower_lower); upper_upper - lower_lower);
jump = upper_branch; jump = upper_branch;
} else if (!lfs_rtag_isrm(tag) } else if (lfs_rtag_weight_(upper_tag_) > upper_tag) {
&& lfs_rtag_weight_(upper_tag_) > lfs_rtag_weight_(tag)) {
// split greater than // split greater than
alt = LFS_MKRALT__(B, GT, alt = LFS_MKRALT__(B, GT,
upper_upper - (lfs_rtag_weight_(tag)+0x8)); upper_upper - (lfs_rtag_weight_(tag)+0x8));
jump = upper_branch; jump = upper_branch;
} else if (lfs_rtag_weight_(lower_tag_) < lfs_rtag_weight_(tag)) { } else if (lfs_rtag_weight_(lower_tag_) < lower_tag) {
// split less than, this is consistent for all appends and only happens // split less than, this is consistent for all appends and only happens
// when appending to the end of the tree // when appending to the end of the tree
alt = LFS_MKRALT__(B, LT, alt = LFS_MKRALT__(B, LT,