Significant cleanup of lfs_rbyd_append, simplified pruning rules

This commit is contained in:
Christopher Haster
2023-01-06 13:34:44 -06:00
parent 17a043f4b8
commit d8540974d4
4 changed files with 587 additions and 861 deletions
+320 -830
View File
File diff suppressed because it is too large Load Diff
+7
View File
@@ -114,6 +114,13 @@ static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
return (a < b) ? a : b;
}
// Swap two 32-bit numbers
static inline void lfs_swap(uint32_t *a, uint32_t *b) {
uint32_t t = *a;
*a = *b;
*b = t;
}
// Align to nearest multiple of a size
static inline uint32_t lfs_aligndown(uint32_t a, uint32_t alignment) {
return a - (a % alignment);
+5 -8
View File
@@ -240,7 +240,6 @@ def main(disk, block_size, block1, block2=None, *,
lifetimes = {}
ids = []
ids_i = 0
deleted_id = ''
j = 4
while j < (block_size if args.get('all') else off):
j_ = j
@@ -266,7 +265,8 @@ def main(disk, block_size, block1, block2=None, *,
for id in range(count))
+ ' ',
count)
elif (tag & 0x7f) == 0x41:
elif ((tag & 0x7f) == 0x41
and ((tag >> 15) & 0xffff)-1 < len(ids)):
lifetimes[j_] = (
''.join(
'%s%s%s' % (
@@ -279,7 +279,7 @@ def main(disk, block_size, block1, block2=None, *,
+ ' ',
count)
count -= 1
deleted_id = ids.pop(((tag >> 15) & 0xffff)-1)
ids.pop(((tag >> 15) & 0xffff)-1)
else:
lifetimes[j_] = (
''.join(
@@ -338,12 +338,9 @@ def main(disk, block_size, block1, block2=None, *,
if args.get('lifetimes'):
if (tag & 0x7f) == 0x40:
count += 1
ids.insert(((tag >> 15) & 0xffff)-1,
COLORS[ids_i % len(COLORS)])
ids_i += 1
elif (tag & 0x7f) == 0x41:
elif ((tag & 0x7f) == 0x41
and ((tag >> 15) & 0xffff)-1 < len(ids)):
count -= 1
deleted_id = ids.pop(((tag >> 15) & 0xffff)-1)
if not args.get('in_tree') or (tag & 0x6) != 2:
if args.get('raw'):
+255 -23
View File
@@ -1876,29 +1876,29 @@ code = '''
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_ERR_NOENT;
// // commit with two attributes, remove the second one
// rbyd = init_rbyd;
// lfs_bd_erase(&lfs, rbyd.block) => 0;
// lfs_rbyd_commit(&lfs, &rbyd,
// LFS_MKRATTR(UATTR, 1, 0, "\xaa\xaa\xaa\xaa", 4,
// LFS_MKRATTR(UATTR, 2, 0, "\xbb\xbb\xbb\xbb", 4, NULL))) => 0;
// lfs_rbyd_commit(&lfs, &rbyd,
// LFS_MKRRMATTR(UATTR, 2, 0, NULL)) => 0;
//
// lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
// => LFS_MKRTAG(UATTR, 1, 0);
// lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
// => LFS_ERR_NOENT;
// lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
// => LFS_ERR_NOENT;
//
// lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
// lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
// => LFS_MKRTAG(UATTR, 1, 0);
// lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
// => LFS_ERR_NOENT;
// lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
// => LFS_ERR_NOENT;
// commit with two attributes, remove the second one
rbyd = init_rbyd;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, "\xaa\xaa\xaa\xaa", 4,
LFS_MKRATTR(UATTR, 2, 0, "\xbb\xbb\xbb\xbb", 4, NULL))) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRRMATTR(UATTR, 2, 0, NULL)) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 1, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_ERR_NOENT;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_ERR_NOENT;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 1, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_ERR_NOENT;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_ERR_NOENT;
'''
[cases.test_rbyd_remove_permutations]
@@ -2021,6 +2021,238 @@ code = '''
assert(worst_size / n <= 8*(2*lfs_nlog2(n)+1));
'''
[cases.test_rbyd_remove_missing]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t init_rbyd = {
.block = 0,
.trunk = 0,
.off = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// create a tree two attributes
rbyd = init_rbyd;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 2, 0, "\xbb\xbb\xbb\xbb", 4,
LFS_MKRATTR(UATTR, 4, 0, "\xdd\xdd\xdd\xdd", 4,
NULL))) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 5, 0), &off, &size)
=> LFS_ERR_NOENT;
// try to remove tags that aren't there, this should do nothing
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRRMATTR(UATTR, 1, 0, NULL)) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 5, 0), &off, &size)
=> LFS_ERR_NOENT;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRRMATTR(UATTR, 3, 0, NULL)) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 5, 0), &off, &size)
=> LFS_ERR_NOENT;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRRMATTR(UATTR, 5, 0, NULL)) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 5, 0), &off, &size)
=> LFS_ERR_NOENT;
// one last fetch to make sure nothing was broken
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 5, 0), &off, &size)
=> LFS_ERR_NOENT;
'''
[cases.test_rbyd_remove_again]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t init_rbyd = {
.block = 0,
.trunk = 0,
.off = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// create a tree
rbyd = init_rbyd;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, "\xaa\xaa\xaa\xaa", 4,
LFS_MKRATTR(UATTR, 2, 0, "\xbb\xbb\xbb\xbb", 4,
LFS_MKRATTR(UATTR, 3, 0, "\xcc\xcc\xcc\xcc", 4,
LFS_MKRATTR(UATTR, 4, 0, "\xdd\xdd\xdd\xdd", 4,
LFS_MKRATTR(UATTR, 5, 0, "\xee\xee\xee\xee", 4,
NULL)))))) => 0;
// remove several attributes
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRRMATTR(UATTR, 1, 0,
LFS_MKRRMATTR(UATTR, 3, 0,
LFS_MKRRMATTR(UATTR, 5, 0, NULL)))) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 5, 0), &off, &size)
=> LFS_ERR_NOENT;
// try to remove tags that aren't there, this should do nothing
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRRMATTR(UATTR, 1, 0, NULL)) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 5, 0), &off, &size)
=> LFS_ERR_NOENT;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRRMATTR(UATTR, 3, 0, NULL)) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 5, 0), &off, &size)
=> LFS_ERR_NOENT;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRRMATTR(UATTR, 5, 0, NULL)) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 5, 0), &off, &size)
=> LFS_ERR_NOENT;
// try to remove the tags again, just to make sure (keep in mind
// these removes still commit to the rbyd)
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRRMATTR(UATTR, 1, 0, NULL)) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 5, 0), &off, &size)
=> LFS_ERR_NOENT;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRRMATTR(UATTR, 3, 0, NULL)) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 5, 0), &off, &size)
=> LFS_ERR_NOENT;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRRMATTR(UATTR, 5, 0, NULL)) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 5, 0), &off, &size)
=> LFS_ERR_NOENT;
// one last fetch to make sure nothing was broken
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 5, 0), &off, &size)
=> LFS_ERR_NOENT;
'''
[cases.test_rbyd_remove_all]
in = 'lfs.c'
code = '''