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:
@@ -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
@@ -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
@@ -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
@@ -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__
|
||||||
|
|||||||
Reference in New Issue
Block a user