Dropped alt-always as an rbyd trunk terminator

Now that tree rebalancing is implemented and needed a null terminator
anyways, I think it's clear that the benefit of the alt-always pointers
as trunk terminator has pretty limited value.

Now a null or other tag is needed for every trunk, which simplifies
checks for end-of-trunk.

Alt-always tags are still emitted for deletes, etc, but there their
behavior is implicit, so no special checks are needed. Alt-always tags
are naturally cleaned up as a part of rbyd pruning.
This commit is contained in:
Christopher Haster
2023-06-26 00:48:36 -05:00
parent f311d1102c
commit cf588ac3fa
4 changed files with 34 additions and 62 deletions
+27 -32
View File
@@ -625,7 +625,6 @@ enum lfsr_tag_type {
LFSR_TAG_ALTGT = 0x6000, LFSR_TAG_ALTGT = 0x6000,
LFSR_TAG_ALTBGT = 0x6000, LFSR_TAG_ALTBGT = 0x6000,
LFSR_TAG_ALTRGT = 0x7000, LFSR_TAG_ALTRGT = 0x7000,
LFSR_TAG_ALTA = 0x6000,
LFSR_TAG_CRC = 0x2000, LFSR_TAG_CRC = 0x2000,
LFSR_TAG_FCRC = 0x2100, LFSR_TAG_FCRC = 0x2100,
@@ -725,14 +724,10 @@ static inline bool lfsr_tag_isalt(lfsr_tag_t tag) {
return tag & 0x4000; return tag & 0x4000;
} }
static inline bool lfsr_tag_istrunkstart(lfsr_tag_t tag) { static inline bool lfsr_tag_istrunk(lfsr_tag_t tag) {
return (tag & 0x6000) != 0x2000; return (tag & 0x6000) != 0x2000;
} }
static inline bool lfsr_tag_istrunkend(lfsr_tag_t tag) {
return !lfsr_tag_isalt(tag) || tag == LFSR_TAG_ALTA;
}
static inline lfsr_tag_t lfsr_tag_next(lfsr_tag_t tag) { static inline lfsr_tag_t lfsr_tag_next(lfsr_tag_t tag) {
return tag + 0x1; return tag + 0x1;
} }
@@ -1718,7 +1713,7 @@ static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd,
} }
// found a trunk of a tree? // found a trunk of a tree?
if (lfsr_tag_istrunkstart(tag) if (lfsr_tag_istrunk(tag)
&& (!trunk || trunk >= off-d || wastrunk)) { && (!trunk || trunk >= off-d || wastrunk)) {
// start of trunk? // start of trunk?
if (!wastrunk) { if (!wastrunk) {
@@ -1738,7 +1733,7 @@ static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd,
weight_ += w; weight_ += w;
// end of trunk? // end of trunk?
if (lfsr_tag_istrunkend(tag)) { if (!lfsr_tag_isalt(tag)) {
wastrunk = false; wastrunk = false;
// update current weight // update current weight
weight = weight_; weight = weight_;
@@ -2448,7 +2443,7 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd,
< lfsr_tag_key(tag)))))) { < lfsr_tag_key(tag)))))) {
if (lfsr_tag_isrm(tag)) { if (lfsr_tag_isrm(tag)) {
// if removed, make our tag unreachable // if removed, make our tag unreachable
alt = LFSR_TAG_ALTA; alt = LFSR_TAG_ALTGT(false, 0);
weight = upper_id - lower_id - 1 + delta; weight = upper_id - lower_id - 1 + delta;
upper_id -= weight; upper_id -= weight;
} else { } else {
@@ -2471,7 +2466,7 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd,
> lfsr_tag_key(tag)))))) { > lfsr_tag_key(tag)))))) {
if (lfsr_tag_isrm(tag)) { if (lfsr_tag_isrm(tag)) {
// if removed, make our tag unreachable // if removed, make our tag unreachable
alt = LFSR_TAG_ALTA; alt = LFSR_TAG_ALTGT(false, 0);
weight = upper_id - lower_id - 1 + delta; weight = upper_id - lower_id - 1 + delta;
upper_id -= weight; upper_id -= weight;
} else { } else {
@@ -2505,30 +2500,30 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd,
goto failed; goto failed;
} }
// we don't need to write the tag if we ended with an unreachable trunk
if (alt != LFSR_TAG_ALTA) {
leaf:; leaf:;
// write the actual tag // write the actual tag
lfs_ssize_t d = lfsr_bd_progtag(lfs, rbyd->block, rbyd->off, //
// rm => null, otherwise strip off control bits // note we always need a non-alt to terminate the trunk, otherwise we
(lfsr_tag_isrm(tag) ? LFSR_TAG_NULL : lfsr_tag_key(tag)), // can't find trunks during fetch
upper_id - lower_id - 1 + delta, lfs_ssize_t d = lfsr_bd_progtag(lfs, rbyd->block, rbyd->off,
lfsr_data_size(data), // rm => null, otherwise strip off control bits
&rbyd->crc); (lfsr_tag_isrm(tag) ? LFSR_TAG_NULL : lfsr_tag_key(tag)),
if (d < 0) { upper_id - lower_id - 1 + delta,
err = d; lfsr_data_size(data),
goto failed; &rbyd->crc);
} if (d < 0) {
rbyd->off += d; err = d;
goto failed;
// don't forget the data!
err = lfsr_bd_progdata(lfs, rbyd->block, rbyd->off, data,
&rbyd->crc);
if (err) {
goto failed;
}
rbyd->off += lfsr_data_size(data);
} }
rbyd->off += d;
// don't forget the data!
err = lfsr_bd_progdata(lfs, rbyd->block, rbyd->off, data,
&rbyd->crc);
if (err) {
goto failed;
}
rbyd->off += lfsr_data_size(data);
return 0; return 0;
+1 -8
View File
@@ -25,7 +25,6 @@ TAG_MTREE = 0x0306
TAG_UATTR = 0x0400 TAG_UATTR = 0x0400
TAG_SATTR = 0x0500 TAG_SATTR = 0x0500
TAG_ALT = 0x4000 TAG_ALT = 0x4000
TAG_ALTA = 0x6000
TAG_CRC = 0x2000 TAG_CRC = 0x2000
TAG_FCRC = 0x2100 TAG_FCRC = 0x2100
@@ -164,12 +163,6 @@ def tagrepr(tag, w, size, off=None):
return 'fcrc%s %d' % ( return 'fcrc%s %d' % (
' 0x%x' % w if w > 0 else '', ' 0x%x' % w if w > 0 else '',
size) size)
elif tag == TAG_ALTA:
return 'alta w%d %s' % (
w,
'0x%x' % (0xffffffff & (off-size))
if off is not None
else '-%d' % off)
elif tag & 0x4000: elif tag & 0x4000:
return 'alt%s%s 0x%x w%d %s' % ( return 'alt%s%s 0x%x w%d %s' % (
'r' if tag & 0x1000 else 'b', 'r' if tag & 0x1000 else 'b',
@@ -290,7 +283,7 @@ class Rbyd:
weight__ += w weight__ += w
# end of trunk? # end of trunk?
if not tag & 0x4000 or tag == TAG_ALTA: if not tag & 0x4000:
wastrunk = False wastrunk = False
# update weight # update weight
weight_ = weight__ weight_ = weight__
+1 -8
View File
@@ -25,7 +25,6 @@ TAG_MTREE = 0x0306
TAG_UATTR = 0x0400 TAG_UATTR = 0x0400
TAG_SATTR = 0x0500 TAG_SATTR = 0x0500
TAG_ALT = 0x4000 TAG_ALT = 0x4000
TAG_ALTA = 0x6000
TAG_CRC = 0x2000 TAG_CRC = 0x2000
TAG_FCRC = 0x2100 TAG_FCRC = 0x2100
@@ -173,12 +172,6 @@ def tagrepr(tag, w, size, off=None):
return 'fcrc%s %d' % ( return 'fcrc%s %d' % (
' 0x%x' % w if w > 0 else '', ' 0x%x' % w if w > 0 else '',
size) size)
elif tag == TAG_ALTA:
return 'alta w%d %s' % (
w,
'0x%x' % (0xffffffff & (off-size))
if off is not None
else '-%d' % off)
elif tag & 0x4000: elif tag & 0x4000:
return 'alt%s%s 0x%x w%d %s' % ( return 'alt%s%s 0x%x w%d %s' % (
'r' if tag & 0x1000 else 'b', 'r' if tag & 0x1000 else 'b',
@@ -299,7 +292,7 @@ class Rbyd:
weight__ += w weight__ += w
# end of trunk? # end of trunk?
if not tag & 0x4000 or tag == TAG_ALTA: if not tag & 0x4000:
wastrunk = False wastrunk = False
# update weight # update weight
weight_ = weight__ weight_ = weight__
+5 -14
View File
@@ -34,7 +34,6 @@ TAG_MTREE = 0x0306
TAG_UATTR = 0x0400 TAG_UATTR = 0x0400
TAG_SATTR = 0x0500 TAG_SATTR = 0x0500
TAG_ALT = 0x4000 TAG_ALT = 0x4000
TAG_ALTA = 0x6000
TAG_CRC = 0x2000 TAG_CRC = 0x2000
TAG_FCRC = 0x2100 TAG_FCRC = 0x2100
@@ -166,12 +165,6 @@ def tagrepr(tag, w, size, off=None):
return 'fcrc%s %d' % ( return 'fcrc%s %d' % (
' 0x%x' % w if w > 0 else '', ' 0x%x' % w if w > 0 else '',
size) size)
elif tag == TAG_ALTA:
return 'alta w%d %s' % (
w,
'0x%x' % (0xffffffff & (off-size))
if off is not None
else '-%d' % off)
elif tag & 0x4000: elif tag & 0x4000:
return 'alt%s%s 0x%x w%d %s' % ( return 'alt%s%s 0x%x w%d %s' % (
'r' if tag & 0x1000 else 'b', 'r' if tag & 0x1000 else 'b',
@@ -309,15 +302,14 @@ def dbg_log(data, block_size, rev, off, weight, *,
else: else:
upper_ += w upper_ += w
if not tag & 0x4000 or tag == TAG_ALTA: if not tag & 0x4000:
wastrunk = False wastrunk = False
# derive the current tag's id from alt weights # derive the current tag's id from alt weights
delta = (lower_+upper_) - weight_ delta = (lower_+upper_) - weight_
weight_ = lower_+upper_ weight_ = lower_+upper_
id = lower_ + w-1 id = lower_ + w-1
if ((tag & 0xe000) != 0x2000 if (tag & 0xe000) != 0x2000 and not tag & 0x4000:
and (not tag & 0x4000 or tag == TAG_ALTA)):
# note we ignore out-of-bounds here for debugging # note we ignore out-of-bounds here for debugging
if delta > 0: if delta > 0:
# grow lifetimes # grow lifetimes
@@ -466,7 +458,7 @@ def dbg_log(data, block_size, rev, off, weight, *,
else: else:
upper_ += w upper_ += w
if not tag & 0x4000 or tag == TAG_ALTA: if not tag & 0x4000:
wastrunk = False wastrunk = False
# derive the current tag's id from alt weights # derive the current tag's id from alt weights
id = lower_ + w-1 id = lower_ + w-1
@@ -478,8 +470,7 @@ def dbg_log(data, block_size, rev, off, weight, *,
'\x1b[m' if color and j >= off else '', '\x1b[m' if color and j >= off else '',
lifetime_width, lifetimerepr(j) if args.get('lifetimes') else '', lifetime_width, lifetimerepr(j) if args.get('lifetimes') else '',
'\x1b[90m' if color and j >= off else '', '\x1b[90m' if color and j >= off else '',
w_width, '-' if tag == TAG_ALTA w_width, '' if (tag & 0xe000) != 0x0000
else '' if (tag & 0xe000) != 0x0000
else '%d-%d' % (id-(w-1), id) if w > 1 else '%d-%d' % (id-(w-1), id) if w > 1
else id, else id,
'%-22s%s' % ( '%-22s%s' % (
@@ -896,7 +887,7 @@ def main(disk, blocks=None, *,
weight__ += w weight__ += w
# end of trunk? # end of trunk?
if not tag & 0x4000 or tag == TAG_ALTA: if not tag & 0x4000:
wastrunk = False wastrunk = False
# update weight # update weight
weight_ = weight__ weight_ = weight__