From ef691d4cfe809a9cf772624cbbd7d25427312161 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 1 Oct 2023 14:31:54 -0500 Subject: [PATCH] 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. --- lfs.c | 30 +++++++++++++++--------------- scripts/dbgbtree.py | 10 +++++----- scripts/dbglfs.py | 10 +++++----- scripts/dbgmtree.py | 10 +++++----- scripts/dbgrbyd.py | 10 +++++----- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/lfs.c b/lfs.c index 0dcf3934..019de6b7 100644 --- a/lfs.c +++ b/lfs.c @@ -776,8 +776,8 @@ static inline bool lfsr_tag_follow( || (rid == upper - (lfsr_srid_t)weight - 1 && lfsr_tag_key(tag) > lfsr_tag_key(alt)); } else { - return rid < lower + (lfsr_srid_t)weight - || (rid == lower + (lfsr_srid_t)weight + return rid < lower + (lfsr_srid_t)weight - 1 + || (rid == lower + (lfsr_srid_t)weight - 1 && lfsr_tag_key(tag) <= lfsr_tag_key(alt)); } } @@ -804,13 +804,13 @@ static inline bool lfsr_tag_prune2( alt, weight, alt2, weight2, lower_rid, upper_rid, - lower_rid, lower_tag); + lower_rid-1, lower_tag); } else { return lfsr_tag_follow2( alt, weight, alt2, weight2, 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_srid_t lower, lfsr_srid_t upper) { *alt = *alt ^ LFSR_TAG_GT; - *weight = (upper-lower) - *weight - 1; + *weight = (upper - lower) - *weight; } static inline void lfsr_tag_flip2( @@ -839,12 +839,12 @@ static inline void lfsr_tag_trim( if (lfsr_tag_isgt(alt)) { *upper_rid -= weight; if (upper_tag) { - *upper_tag = alt + 0x1; + *upper_tag = alt + 1; } } else { *lower_rid += weight; 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 lfs_size_t branch = rbyd->trunk; - lfsr_srid_t lower = -1; + lfsr_srid_t lower = 0; lfsr_srid_t upper = rbyd->weight; // no trunk yet? @@ -2262,7 +2262,7 @@ static int lfsr_rbyd_lookupnext(lfs_t *lfs, const lfsr_rbyd_t *rbyd, *tag_ = tag__; } if (weight_) { - *weight_ = rid__ - lower; + *weight_ = upper - lower; } if (data_) { *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 // in the case of range deletions 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_tag_t lower_tag = 0; 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 removed, make our tag unreachable alt = LFSR_TAG_ALT(GT, B, 0); - weight = upper_rid - lower_rid - 1 + delta; + weight = upper_rid - lower_rid + delta; upper_rid -= weight; } else { // split less than @@ -2849,7 +2849,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd, ? LFSR_TAG_R : LFSR_TAG_B), lfsr_tag_key(tag_)); - weight = rid_ - lower_rid; + weight = (rid_+1) - lower_rid; 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 removed, make our tag unreachable alt = LFSR_TAG_ALT(GT, B, 0); - weight = upper_rid - lower_rid - 1 + delta; + weight = upper_rid - lower_rid + delta; upper_rid -= weight; } else { // split greater than @@ -2873,7 +2873,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd, ? LFSR_TAG_R : LFSR_TAG_B), lfsr_tag_key(tag)); - weight = upper_rid - rid - 1; + weight = upper_rid - (rid+1); upper_rid -= weight; } } @@ -2909,7 +2909,7 @@ leaf:; (lfsr_tag_isrm(tag) ? lfsr_tag_mode(lfsr_tag_shrubkey(tag)) : lfsr_tag_shrubkey(tag)), - upper_rid - lower_rid - 1 + delta, + upper_rid - lower_rid + delta, lfsr_data_size(&data), &rbyd->cksum); if (d < 0) { diff --git a/scripts/dbgbtree.py b/scripts/dbgbtree.py index 5fd33b95..0c81afb7 100755 --- a/scripts/dbgbtree.py +++ b/scripts/dbgbtree.py @@ -351,7 +351,7 @@ class Rbyd: if not self: return True, 0, -1, 0, 0, 0, b'', [] - lower = -1 + lower = 0 upper = self.weight path = [] @@ -366,9 +366,9 @@ class Rbyd: if ((rid, tag & 0xfff) > (upper-weight_-1, alt & 0xfff) if alt & TAG_GT else ((rid, tag & 0xfff) - <= (lower+weight_, alt & 0xfff))): - lower += upper-lower-1-weight_ if alt & TAG_GT else 0 - upper -= upper-lower-1-weight_ if not alt & TAG_GT else 0 + <= (lower+weight_-1, alt & 0xfff))): + lower += upper-lower-weight_ if alt & TAG_GT else 0 + upper -= upper-lower-weight_ if not alt & TAG_GT else 0 j = j - jump # figure out which color @@ -401,7 +401,7 @@ class Rbyd: else: rid_ = upper-1 tag_ = alt - w_ = rid_-lower + w_ = upper-lower done = not tag_ or (rid_, tag_) < (rid, tag) diff --git a/scripts/dbglfs.py b/scripts/dbglfs.py index 560f15de..dd2ed6a2 100755 --- a/scripts/dbglfs.py +++ b/scripts/dbglfs.py @@ -358,7 +358,7 @@ class Rbyd: if not self: return True, 0, -1, 0, 0, 0, b'', [] - lower = -1 + lower = 0 upper = self.weight path = [] @@ -373,9 +373,9 @@ class Rbyd: if ((rid, tag & 0xfff) > (upper-weight_-1, alt & 0xfff) if alt & TAG_GT else ((rid, tag & 0xfff) - <= (lower+weight_, alt & 0xfff))): - lower += upper-lower-1-weight_ if alt & TAG_GT else 0 - upper -= upper-lower-1-weight_ if not alt & TAG_GT else 0 + <= (lower+weight_-1, alt & 0xfff))): + lower += upper-lower-weight_ if alt & TAG_GT else 0 + upper -= upper-lower-weight_ if not alt & TAG_GT else 0 j = j - jump # figure out which color @@ -408,7 +408,7 @@ class Rbyd: else: rid_ = upper-1 tag_ = alt - w_ = rid_-lower + w_ = upper-lower done = not tag_ or (rid_, tag_) < (rid, tag) diff --git a/scripts/dbgmtree.py b/scripts/dbgmtree.py index 6bb6caa0..ff15ef8b 100755 --- a/scripts/dbgmtree.py +++ b/scripts/dbgmtree.py @@ -360,7 +360,7 @@ class Rbyd: if not self: return True, 0, -1, 0, 0, 0, b'', [] - lower = -1 + lower = 0 upper = self.weight path = [] @@ -375,9 +375,9 @@ class Rbyd: if ((rid, tag & 0xfff) > (upper-weight_-1, alt & 0xfff) if alt & TAG_GT else ((rid, tag & 0xfff) - <= (lower+weight_, alt & 0xfff))): - lower += upper-lower-1-weight_ if alt & TAG_GT else 0 - upper -= upper-lower-1-weight_ if not alt & TAG_GT else 0 + <= (lower+weight_-1, alt & 0xfff))): + lower += upper-lower-weight_ if alt & TAG_GT else 0 + upper -= upper-lower-weight_ if not alt & TAG_GT else 0 j = j - jump # figure out which color @@ -410,7 +410,7 @@ class Rbyd: else: rid_ = upper-1 tag_ = alt - w_ = rid_-lower + w_ = upper-lower done = not tag_ or (rid_, tag_) < (rid, tag) diff --git a/scripts/dbgrbyd.py b/scripts/dbgrbyd.py index af9fdc4e..2c05f820 100755 --- a/scripts/dbgrbyd.py +++ b/scripts/dbgrbyd.py @@ -602,7 +602,7 @@ def dbg_tree(data, block_size, rev, trunk, weight, *, # lookup a tag, returning also the search path for decoration # purposes def lookup(rid, tag): - lower = -1 + lower = 0 upper = weight path = [] @@ -616,9 +616,9 @@ def dbg_tree(data, block_size, rev, trunk, weight, *, # follow? if ((rid, tag & 0xfff) > (upper-w-1, alt & 0xfff) if alt & TAG_GT - else ((rid, tag & 0xfff) <= (lower+w, alt & 0xfff))): - lower += upper-lower-1-w if alt & TAG_GT else 0 - upper -= upper-lower-1-w if not alt & TAG_GT else 0 + else ((rid, tag & 0xfff) <= (lower+w-1, alt & 0xfff))): + lower += upper-lower-w if alt & TAG_GT else 0 + upper -= upper-lower-w if not alt & TAG_GT else 0 j = j - jump # figure out which color @@ -651,7 +651,7 @@ def dbg_tree(data, block_size, rev, trunk, weight, *, else: rid_ = upper-1 tag_ = alt - w_ = rid_-lower + w_ = upper-lower done = not tag_ or (rid_, tag_) < (rid, tag)