Tweaked rbyd lookup/append to use 0 lower rid bias

Previously our lower/upper bounds were initialized to -1..weight. This
made a lot of the math unintuitive and confusing, and it's not really
necessary to support -1 rids (-1 rids arise naturally in order-statistic
trees the can have weight=0).

The tweak here is to use lower/upper bounds initialized to 0..weight,
which makes the math behave as expected. -1 rids naturally arise from
rid = upper-1.
This commit is contained in:
Christopher Haster
2023-10-01 14:31:54 -05:00
parent 501f8cbe10
commit ef691d4cfe
5 changed files with 35 additions and 35 deletions
+15 -15
View File
@@ -776,8 +776,8 @@ static inline bool lfsr_tag_follow(
|| (rid == upper - (lfsr_srid_t)weight - 1 || (rid == upper - (lfsr_srid_t)weight - 1
&& 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 return rid < lower + (lfsr_srid_t)weight - 1
|| (rid == lower + (lfsr_srid_t)weight || (rid == lower + (lfsr_srid_t)weight - 1
&& lfsr_tag_key(tag) <= lfsr_tag_key(alt)); && lfsr_tag_key(tag) <= lfsr_tag_key(alt));
} }
} }
@@ -804,13 +804,13 @@ static inline bool lfsr_tag_prune2(
alt, weight, alt, weight,
alt2, weight2, alt2, weight2,
lower_rid, upper_rid, lower_rid, upper_rid,
lower_rid, lower_tag); lower_rid-1, lower_tag);
} else { } else {
return lfsr_tag_follow2( return lfsr_tag_follow2(
alt, weight, alt, weight,
alt2, weight2, alt2, weight2,
lower_rid, upper_rid, lower_rid, upper_rid,
upper_rid-1, upper_tag-0x1); upper_rid-1, upper_tag-1);
} }
} }
@@ -818,7 +818,7 @@ static inline void lfsr_tag_flip(
lfsr_tag_t *alt, lfsr_rid_t *weight, lfsr_tag_t *alt, lfsr_rid_t *weight,
lfsr_srid_t lower, lfsr_srid_t upper) { lfsr_srid_t lower, lfsr_srid_t upper) {
*alt = *alt ^ LFSR_TAG_GT; *alt = *alt ^ LFSR_TAG_GT;
*weight = (upper-lower) - *weight - 1; *weight = (upper - lower) - *weight;
} }
static inline void lfsr_tag_flip2( static inline void lfsr_tag_flip2(
@@ -839,12 +839,12 @@ static inline void lfsr_tag_trim(
if (lfsr_tag_isgt(alt)) { if (lfsr_tag_isgt(alt)) {
*upper_rid -= weight; *upper_rid -= weight;
if (upper_tag) { if (upper_tag) {
*upper_tag = alt + 0x1; *upper_tag = alt + 1;
} }
} else { } else {
*lower_rid += weight; *lower_rid += weight;
if (lower_tag) { if (lower_tag) {
*lower_tag = alt + 0x1; *lower_tag = alt + 1;
} }
} }
} }
@@ -2208,7 +2208,7 @@ static int lfsr_rbyd_lookupnext(lfs_t *lfs, const lfsr_rbyd_t *rbyd,
// keep track of bounds as we descend down the tree // keep track of bounds as we descend down the tree
lfs_size_t branch = rbyd->trunk; lfs_size_t branch = rbyd->trunk;
lfsr_srid_t lower = -1; lfsr_srid_t lower = 0;
lfsr_srid_t upper = rbyd->weight; lfsr_srid_t upper = rbyd->weight;
// no trunk yet? // no trunk yet?
@@ -2262,7 +2262,7 @@ static int lfsr_rbyd_lookupnext(lfs_t *lfs, const lfsr_rbyd_t *rbyd,
*tag_ = tag__; *tag_ = tag__;
} }
if (weight_) { if (weight_) {
*weight_ = rid__ - lower; *weight_ = upper - lower;
} }
if (data_) { if (data_) {
*data_ = LFSR_DATA_DISK(rbyd->block, branch + d, jump); *data_ = LFSR_DATA_DISK(rbyd->block, branch + d, jump);
@@ -2520,7 +2520,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// track of both the lower and upper bounds of diverging paths // track of both the lower and upper bounds of diverging paths
// in the case of range deletions // in the case of range deletions
lfs_size_t branch = rbyd->trunk; lfs_size_t branch = rbyd->trunk;
lfsr_srid_t lower_rid = -1; lfsr_srid_t lower_rid = 0;
lfsr_srid_t upper_rid = rbyd->weight; lfsr_srid_t upper_rid = rbyd->weight;
lfsr_tag_t lower_tag = 0; lfsr_tag_t lower_tag = 0;
lfsr_tag_t upper_tag = 0xffff; lfsr_tag_t upper_tag = 0xffff;
@@ -2839,7 +2839,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
if (lfsr_tag_isrm(tag) || !lfsr_tag_key(tag)) { if (lfsr_tag_isrm(tag) || !lfsr_tag_key(tag)) {
// if removed, make our tag unreachable // if removed, make our tag unreachable
alt = LFSR_TAG_ALT(GT, B, 0); alt = LFSR_TAG_ALT(GT, B, 0);
weight = upper_rid - lower_rid - 1 + delta; weight = upper_rid - lower_rid + delta;
upper_rid -= weight; upper_rid -= weight;
} else { } else {
// split less than // split less than
@@ -2849,7 +2849,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
? LFSR_TAG_R ? LFSR_TAG_R
: LFSR_TAG_B), : LFSR_TAG_B),
lfsr_tag_key(tag_)); lfsr_tag_key(tag_));
weight = rid_ - lower_rid; weight = (rid_+1) - lower_rid;
lower_rid += weight; lower_rid += weight;
} }
@@ -2863,7 +2863,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
if (lfsr_tag_isrm(tag) || !lfsr_tag_key(tag)) { if (lfsr_tag_isrm(tag) || !lfsr_tag_key(tag)) {
// if removed, make our tag unreachable // if removed, make our tag unreachable
alt = LFSR_TAG_ALT(GT, B, 0); alt = LFSR_TAG_ALT(GT, B, 0);
weight = upper_rid - lower_rid - 1 + delta; weight = upper_rid - lower_rid + delta;
upper_rid -= weight; upper_rid -= weight;
} else { } else {
// split greater than // split greater than
@@ -2873,7 +2873,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
? LFSR_TAG_R ? LFSR_TAG_R
: LFSR_TAG_B), : LFSR_TAG_B),
lfsr_tag_key(tag)); lfsr_tag_key(tag));
weight = upper_rid - rid - 1; weight = upper_rid - (rid+1);
upper_rid -= weight; upper_rid -= weight;
} }
} }
@@ -2909,7 +2909,7 @@ leaf:;
(lfsr_tag_isrm(tag) (lfsr_tag_isrm(tag)
? lfsr_tag_mode(lfsr_tag_shrubkey(tag)) ? lfsr_tag_mode(lfsr_tag_shrubkey(tag))
: lfsr_tag_shrubkey(tag)), : lfsr_tag_shrubkey(tag)),
upper_rid - lower_rid - 1 + delta, upper_rid - lower_rid + delta,
lfsr_data_size(&data), lfsr_data_size(&data),
&rbyd->cksum); &rbyd->cksum);
if (d < 0) { if (d < 0) {
+5 -5
View File
@@ -351,7 +351,7 @@ class Rbyd:
if not self: if not self:
return True, 0, -1, 0, 0, 0, b'', [] return True, 0, -1, 0, 0, 0, b'', []
lower = -1 lower = 0
upper = self.weight upper = self.weight
path = [] path = []
@@ -366,9 +366,9 @@ class Rbyd:
if ((rid, tag & 0xfff) > (upper-weight_-1, alt & 0xfff) if ((rid, tag & 0xfff) > (upper-weight_-1, alt & 0xfff)
if alt & TAG_GT if alt & TAG_GT
else ((rid, tag & 0xfff) else ((rid, tag & 0xfff)
<= (lower+weight_, alt & 0xfff))): <= (lower+weight_-1, alt & 0xfff))):
lower += upper-lower-1-weight_ if alt & TAG_GT else 0 lower += upper-lower-weight_ if alt & TAG_GT else 0
upper -= upper-lower-1-weight_ if not alt & TAG_GT else 0 upper -= upper-lower-weight_ if not alt & TAG_GT else 0
j = j - jump j = j - jump
# figure out which color # figure out which color
@@ -401,7 +401,7 @@ class Rbyd:
else: else:
rid_ = upper-1 rid_ = upper-1
tag_ = alt tag_ = alt
w_ = rid_-lower w_ = upper-lower
done = not tag_ or (rid_, tag_) < (rid, tag) done = not tag_ or (rid_, tag_) < (rid, tag)
+5 -5
View File
@@ -358,7 +358,7 @@ class Rbyd:
if not self: if not self:
return True, 0, -1, 0, 0, 0, b'', [] return True, 0, -1, 0, 0, 0, b'', []
lower = -1 lower = 0
upper = self.weight upper = self.weight
path = [] path = []
@@ -373,9 +373,9 @@ class Rbyd:
if ((rid, tag & 0xfff) > (upper-weight_-1, alt & 0xfff) if ((rid, tag & 0xfff) > (upper-weight_-1, alt & 0xfff)
if alt & TAG_GT if alt & TAG_GT
else ((rid, tag & 0xfff) else ((rid, tag & 0xfff)
<= (lower+weight_, alt & 0xfff))): <= (lower+weight_-1, alt & 0xfff))):
lower += upper-lower-1-weight_ if alt & TAG_GT else 0 lower += upper-lower-weight_ if alt & TAG_GT else 0
upper -= upper-lower-1-weight_ if not alt & TAG_GT else 0 upper -= upper-lower-weight_ if not alt & TAG_GT else 0
j = j - jump j = j - jump
# figure out which color # figure out which color
@@ -408,7 +408,7 @@ class Rbyd:
else: else:
rid_ = upper-1 rid_ = upper-1
tag_ = alt tag_ = alt
w_ = rid_-lower w_ = upper-lower
done = not tag_ or (rid_, tag_) < (rid, tag) done = not tag_ or (rid_, tag_) < (rid, tag)
+5 -5
View File
@@ -360,7 +360,7 @@ class Rbyd:
if not self: if not self:
return True, 0, -1, 0, 0, 0, b'', [] return True, 0, -1, 0, 0, 0, b'', []
lower = -1 lower = 0
upper = self.weight upper = self.weight
path = [] path = []
@@ -375,9 +375,9 @@ class Rbyd:
if ((rid, tag & 0xfff) > (upper-weight_-1, alt & 0xfff) if ((rid, tag & 0xfff) > (upper-weight_-1, alt & 0xfff)
if alt & TAG_GT if alt & TAG_GT
else ((rid, tag & 0xfff) else ((rid, tag & 0xfff)
<= (lower+weight_, alt & 0xfff))): <= (lower+weight_-1, alt & 0xfff))):
lower += upper-lower-1-weight_ if alt & TAG_GT else 0 lower += upper-lower-weight_ if alt & TAG_GT else 0
upper -= upper-lower-1-weight_ if not alt & TAG_GT else 0 upper -= upper-lower-weight_ if not alt & TAG_GT else 0
j = j - jump j = j - jump
# figure out which color # figure out which color
@@ -410,7 +410,7 @@ class Rbyd:
else: else:
rid_ = upper-1 rid_ = upper-1
tag_ = alt tag_ = alt
w_ = rid_-lower w_ = upper-lower
done = not tag_ or (rid_, tag_) < (rid, tag) done = not tag_ or (rid_, tag_) < (rid, tag)
+5 -5
View File
@@ -602,7 +602,7 @@ def dbg_tree(data, block_size, rev, trunk, weight, *,
# lookup a tag, returning also the search path for decoration # lookup a tag, returning also the search path for decoration
# purposes # purposes
def lookup(rid, tag): def lookup(rid, tag):
lower = -1 lower = 0
upper = weight upper = weight
path = [] path = []
@@ -616,9 +616,9 @@ def dbg_tree(data, block_size, rev, trunk, weight, *,
# follow? # follow?
if ((rid, tag & 0xfff) > (upper-w-1, alt & 0xfff) if ((rid, tag & 0xfff) > (upper-w-1, alt & 0xfff)
if alt & TAG_GT if alt & TAG_GT
else ((rid, tag & 0xfff) <= (lower+w, alt & 0xfff))): else ((rid, tag & 0xfff) <= (lower+w-1, alt & 0xfff))):
lower += upper-lower-1-w if alt & TAG_GT else 0 lower += upper-lower-w if alt & TAG_GT else 0
upper -= upper-lower-1-w if not alt & TAG_GT else 0 upper -= upper-lower-w if not alt & TAG_GT else 0
j = j - jump j = j - jump
# figure out which color # figure out which color
@@ -651,7 +651,7 @@ def dbg_tree(data, block_size, rev, trunk, weight, *,
else: else:
rid_ = upper-1 rid_ = upper-1
tag_ = alt tag_ = alt
w_ = rid_-lower w_ = upper-lower
done = not tag_ or (rid_, tag_) < (rid, tag) done = not tag_ or (rid_, tag_) < (rid, tag)