Switched back to altgt 0 for unreachable tags, made btree tests pass again

This fixed two notable bugs:

1. Using "altle 0xfff0" to terminate unreachable rbyd trunks threw off
   id calculations in lfsr_rbyd_fetch searches. We derive the tag's
   id+weight from the lower bound calculated as the sum of all "altle"s
   and an always-followed "altle 0xfff0" throws this off.

   We _could_ derive the tag's id+weight from the upper bound, inverting
   this relationship, but decided to revert back to using "altgt 0" to
   terminate unreachable rbyd trunks.

   Using the lower bound is more intuitive, and "altgt 0" has the
   benifit of supporting variable-length tags if we ever need to adopt
   those.

   To avoid the previous issues around 0-tag holes (which was the original
   motivation for altle 0xfff0), 0-tags are now automatically adjusted
   in lfsr_rbyd_lookup, and avoided in lfsr_rbyd_append.

   But note! if any implemention tries to look up 0-tags, this will
   eventually break! See previous commits for more info.

2. Unfortunately, we can't combine branch updates and weight updates in
   lfsr_btree_commit in the general case.

   If our btree contains bname tags, the weight is attached to the
   bname tag, separately from the branch tag.

   Branch updates in lfsr_btree_commit need two separate attrs for the
   weight and branch struct for this reason, which is unfortunate.

   The amount of extra conditions to make bname+branch pairs work makes
   me want to redesign the inner-nodes of the btrees, but I can't think
   of a better way to approach the problem.
This commit is contained in:
Christopher Haster
2023-04-02 03:02:45 -05:00
parent e5ad09b380
commit 13852df071
3 changed files with 36 additions and 27 deletions
+3 -6
View File
@@ -275,7 +275,7 @@ def show_log(block_size, data, rev, off, *,
# note we ignore out-of-bounds here for debugging
if delta > 0:
# grow lifetimes
i, id_ = index(weights, id-(delta-1))
i, id_ = index(weights, lower_)
if id_ > 0:
weights[i:i+1] = [id_, delta, weights[i]-id_]
lifetimes[i:i+1] = [
@@ -288,21 +288,18 @@ def show_log(block_size, data, rev, off, *,
elif delta < 0:
# shrink lifetimes
i, id_ = index(weights, id+1)
i, id_ = index(weights, lower_)
delta_ = -delta
weights_ = weights.copy()
lifetimes_ = lifetimes.copy()
shrinks = set()
while delta_ > 0 and i < len(weights_):
if id_ > 0:
if weights_[i] > delta_:
delta__ = min(delta_, weights_[i]-id_)
delta_ -= delta__
weights_[i] -= delta__
i += 1
id_ = 0
elif weights_[i] > delta_:
weights_[i] -= delta_
size_ = 0
else:
delta_ -= weights_[i]
weights_[i:i+1] = []