Files
littlefs/tests/test_rbyd.toml
T
2023-02-12 13:16:13 -06:00

1541 lines
55 KiB
TOML

# Test this inner rbyd data-structure
# test with a number of different erase values
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
[cases.test_rbyd_fetch]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
// try an empty commit
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
// commit with one attribute
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
// commit with two attributes
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
'''
[cases.test_rbyd_multi_fetch]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
// try an empty commit
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
// commit with one attribute
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
// commit with two attributes
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
'''
# [cases.test_rbyd_fetchmatch]
# [cases.test_rbyd_multi_fetchmatch]
[cases.test_rbyd_lookup]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// try an empty commit
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 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_ERR_NOENT;
// commit with one attribute
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, 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_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;
// commit with two attributes
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, 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_MKRTAG(UATTR, 2, 0);
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_ERR_NOENT;
'''
[cases.test_rbyd_multi_lookup]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// try an empty commit
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 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_ERR_NOENT;
// commit with one attribute
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, 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_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;
// commit with two attributes
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, 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_MKRTAG(UATTR, 2, 0);
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_ERR_NOENT;
'''
[cases.test_rbyd_traverse]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
lfs_srtag_t tag;
// traverse requires correct biasing of the weights in the rbyd tree
// so that lookups return strictly the tag greater than or equal to
// the tag requested
rbyd = rbyd_init;
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))) => 0;
tag = lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size);
assert(tag == LFS_MKRTAG(UATTR, 1, 0));
tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size);
assert(tag == LFS_MKRTAG(UATTR, 2, 0));
tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size);
assert(tag == LFS_ERR_NOENT);
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
tag = lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size);
assert(tag == LFS_MKRTAG(UATTR, 1, 0));
tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size);
assert(tag == LFS_MKRTAG(UATTR, 2, 0));
tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size);
assert(tag == LFS_ERR_NOENT);
'''
[cases.test_rbyd_multi_traverse]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
lfs_srtag_t tag;
// traverse requires correct biasing of the weights in the rbyd tree
// so that lookups return strictly the tag greater than or equal to
// the tag requested
rbyd = rbyd_init;
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)) => 0;
tag = lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size);
assert(tag == LFS_MKRTAG(UATTR, 1, 0));
tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size);
assert(tag == LFS_MKRTAG(UATTR, 2, 0));
tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size);
assert(tag == LFS_ERR_NOENT);
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
tag = lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size);
assert(tag == LFS_MKRTAG(UATTR, 1, 0));
tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size);
assert(tag == LFS_MKRTAG(UATTR, 2, 0));
tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size);
assert(tag == LFS_ERR_NOENT);
'''
[cases.test_rbyd_bifoliate]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// create a split in the leaves
// <b
// => .-'|
// 1 1 2
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))) => 0;
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_MKRTAG(UATTR, 2, 0);
// split the other direction
// >b
// => .-'|
// 2 2 1
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL))) => 0;
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_MKRTAG(UATTR, 2, 0);
'''
[cases.test_rbyd_bflips]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// ignore a black edge
// <b <b
// .-'| => .----'|
// 1 2 1 2 2
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)))) => 0;
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_MKRTAG(UATTR, 2, 0);
// flip a black edge
// <b >b
// .-'| => .-'|
// 1 2 1 2 1
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)))) => 0;
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_MKRTAG(UATTR, 2, 0);
'''
[cases.test_rbyd_trifoliate]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// ignore a black edge
// <r
// .----'|
// <b => | <b
// .-'| | .-'|
// 1 2 1 2 3
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4, NULL)))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
// flip a black edge
// >r
// .-'|
// <b => | >b
// .-'| .--|-'|
// 2 3 2 3 1
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
'''
[cases.test_rbyd_rflips]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// ignore a red edge and black edge
// <r <r
// .----'| .-------'|
// | <b => | <b
// | .-'| | .----'|
// 1 2 3 1 2 3 3
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4, NULL))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
// ignore a red edge, flip a black edge
// <r <r
// .----'| .-------'|
// | <b => | >b
// | .-'| | .-'|
// 1 2 3 1 2 3 2
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
// flip a red edge and black edge
// <r >r
// .----'| .-'|
// | <b => | >b
// | .-'| .--|-'|
// 1 2 3 1 2 3 1
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
// flip a red edge, ignore a black edge
// <r >r
// .-'| .-------'|
// | >b => | >b
// .--|-'| | .-'|
// 3 1 2 3 1 2 1
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
'''
[cases.test_rbyd_quadrifoliate]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// ignore a red edge and black edge
// <y
// .-------'|
// <r | <r
// .----'| => | .----'|
// | <b | | <b
// | .-'| | | .-'|
// 1 2 3 1 2 3 4
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
// ignore a red edge, flip a black edge
// <y >y
// .-------'| .-'|
// <r | >r | >r
// .----'| => | .-'| => .--|-'|
// | <b | | >b | | <b
// | .-'| | .--|-'| .--|--|-'|
// 1 3 4 1 3 4 2 1 3 4 2
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
// flip a red edge and black edge
// >y
// .-'|
// <r | >b
// .----'| => .--|-'|
// | <b | | >b
// | .-'| .--|--|-'|
// 2 3 4 2 3 4 1
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
// flip a red edge, ignore a black edge
// >y
// .-------'|
// <r | >r
// .-'| => | .-'|
// | >b | | <b
// .--|-'| | .--|-'|
// 4 2 3 4 2 3 1
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
'''
[cases.test_rbyd_rotations]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// all three the same
// <y
// .-------'|
// <r | <r
// .----'| => | .----'|
// | <b | | <b
// | .-'| | | .-'|
// 1 2 3 1 2 3 4
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
// yellow and red alt the same
// <y
// .-------'|
// <r | <r
// .----'| => | .----'|
// | <b | | >b
// | .-'| | | .-'|
// 1 2 4 1 2 4 3
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4, NULL))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
// yellow and black alt the same
// <y <y
// .-------'| .-------'|
// <r | >r | <r
// .----'| => | .----'| => | .-'|
// | >b | | <b | | >b
// | .-'| | | .-'| | .--|-'|
// 1 4 2 1 4 2 3 1 4 2 3
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4, NULL))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
// red and black alt the same
// >y <y
// .-------'| .----'|
// >r | <r | <r
// .----'| => | .----'| => | .-'|
// | <b | | <b | | >b
// | .-'| | | .-'| .--|--|-'|
// 4 1 2 4 1 2 3 4 1 2 3
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4, NULL))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
'''
[cases.test_rbyd_ysplits]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// split a yellow triple, not taking any alt
// <b
// .-'|
// <y <y |
// .-------'| .-------'| |
// | <r => | <r |
// | .----'| | .----' |
// | | <b | | <b
// | | .-'| | | .----'|
// 1 2 3 4 1 2 3 4 4
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4, NULL)))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
// split a yellow triple, taking the black alt
// <b
// .-'|
// <y <y |
// .-------'| .-------'| |
// | <r => | <r |
// | .----'| | .----' |
// | | <b | | >b
// | | .-'| | | .-'|
// 1 2 3 4 1 2 3 4 3
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4, NULL)))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
// split a yellow triple, taking the red alt
// <y >b
// .-------'| .-'|
// | <r | <b
// | .----'| => .--------|-'|
// | | <b | <b |
// | | .-'| | .-'| |
// 1 2 3 4 1 2 3 4 2
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
// split a yellow triple, taking the yellow alt
// <y >b
// .-------'| .-'|
// | <r | >b
// | .----'| => .-----|-'|
// | | <b | <b |
// | | .-'| | .-'| |
// 1 2 3 4 1 2 3 4 1
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 4, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 4, 0);
'''
[cases.test_rbyd_quintifoliate]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// split a yellow triple, not taking any alt
// <b
// .-'|
// <y |
// .-------'| |
// <y | <r |
// .-------'| => | .----' |
// | <r | | <r
// | .----'| | | .----'|
// | | <b | | | <b
// | | .-'| | | | .-'|
// 1 2 3 4 1 2 3 4 5
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 5, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 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_MKRTAG(UATTR, 5, 0);
// split a yellow triple, taking the black alt
// <b
// .-'|
// <y |
// .-------'| |
// <y | <r |
// .-------'| => | .----' |
// | <r | | >r
// | .----'| | | .-'|
// | | <b | | | >b
// | | .-'| | | .--|-'|
// 1 2 4 5 1 2 4 5 3
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 5, 0, &(uint32_t){0xeeeeeeee}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4, NULL)))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 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_MKRTAG(UATTR, 5, 0);
// split a yellow triple, taking the red alt
// >b
// .-'|
// <y | <r
// .-------'| .--------|-'|
// | <r | | >b
// | .----'| => | .-----|-'|
// | | <b | | <b |
// | | .-'| | | .-'| |
// 1 3 4 5 1 3 4 5 2
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 5, 0, &(uint32_t){0xeeeeeeee}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 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_MKRTAG(UATTR, 5, 0);
// split a yellow triple, taking the yellow alt
// >b
// .-'|
// <y | >r
// .-------'| .-----|-'|
// | <r | | >b
// | .----'| => .--|-----|-'|
// | | <b | | <b |
// | | .-'| | | .-'| |
// 2 3 4 5 2 3 4 5 1
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 5, 0, &(uint32_t){0xeeeeeeee}, 4,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 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_MKRTAG(UATTR, 5, 0);
'''
[cases.test_rbyd_prunes]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// don't prune
// <b <b
// .-'| .----'|
// <y | <y |
// .-------'| | .-------'| |
// | <r | | <r |
// | .----' | => | .----' |
// | | <r | | <r
// | | .----'| | | .-------'|
// | | | <b | | | <b
// | | | .-'| | | | .----'|
// 1 2 3 4 5 1 2 3 4 5 5
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 5, 0, &(uint32_t){0xeeeeeeee}, 4,
LFS_MKRATTR(UATTR, 5, 0, &(uint32_t){0xeeeeeeee}, 4, NULL))))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 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_MKRTAG(UATTR, 5, 0);
// prune by taking a red alt
// <b
// .-'|
// <y | >b
// .-------'| | .-'|
// | <r | | <b
// | .----' | => .-----------|-'|
// | | <r | <r |
// | | .----'| | .----'| |
// | | | <b | | <b |
// | | | .-'| | | .-'| |
// 1 2 3 4 5 1 2 3 4 5 2
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 5, 0, &(uint32_t){0xeeeeeeee}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 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_MKRTAG(UATTR, 5, 0);
// prune by taking a yellow alt (this needs to prune during the rflip)
// <b
// .-'|
// <y | >b
// .-------'| | .-'|
// | <r | | >b
// | .----' | => .--------|-'|
// | | <r | <r |
// | | .----'| | .----'| |
// | | | <b | | <b |
// | | | .-'| | | .-'| |
// 1 2 3 4 5 1 2 3 4 5 1
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 5, 0, &(uint32_t){0xeeeeeeee}, 4,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL))))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 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_MKRTAG(UATTR, 5, 0);
'''
[cases.test_rbyd_sextifoliate]
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// don't prune
// <b
// .----'|
// <b <y |
// .-'| .-------'| |
// <y | | <r |
// .-------'| | | .----' |
// | <r | | | <y
// | .----' | => | | .-------'|
// | | <r | | | <r
// | | .----'| | | | .----'|
// | | | <b | | | | <b
// | | | .-'| | | | | .-'|
// 1 2 3 4 5 1 2 3 4 5 6
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 5, 0, &(uint32_t){0xeeeeeeee}, 4,
LFS_MKRATTR(UATTR, 6, 0, &(uint32_t){0xffffffff}, 4, NULL))))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 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_MKRTAG(UATTR, 5, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 6, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 6, 0);
// prune by taking a red alt
// <b >b
// .-'| .-'|
// <y | | <r
// .-------'| | .-----------|-'|
// | <r | | | >b
// | .----' | => | .--------|-'|
// | | <r | | <r |
// | | .----'| | | .----'| |
// | | | <b | | | <b |
// | | | .-'| | | | .-'| |
// 1 3 4 5 6 1 3 4 5 6 2
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 5, 0, &(uint32_t){0xeeeeeeee}, 4,
LFS_MKRATTR(UATTR, 6, 0, &(uint32_t){0xffffffff}, 4,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 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_MKRTAG(UATTR, 5, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 6, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 6, 0);
// prune by taking a yellow alt (this needs to prune during the rflip)
// <b >b
// .-'| .-'|
// <y | | >r
// .-------'| | .--------|-'|
// | <r | | | >b
// | .----' | => .--|--------|-'|
// | | <r | | <r |
// | | .----'| | | .----'| |
// | | | <b | | | <b |
// | | | .-'| | | | .-'| |
// 2 3 4 5 6 2 3 4 5 6 1
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
LFS_MKRATTR(UATTR, 3, 0, &(uint32_t){0xcccccccc}, 4,
LFS_MKRATTR(UATTR, 4, 0, &(uint32_t){0xdddddddd}, 4,
LFS_MKRATTR(UATTR, 5, 0, &(uint32_t){0xeeeeeeee}, 4,
LFS_MKRATTR(UATTR, 6, 0, &(uint32_t){0xffffffff}, 4,
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL))))))) => 0;
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_MKRTAG(UATTR, 2, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 3, 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_MKRTAG(UATTR, 5, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 6, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 6, 0);
'''
[cases.test_rbyd_permutations]
defines.N = 'range(1, 8)'
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// test all permutations of a given size
uint8_t perm[N];
uint8_t stack[N];
for (uint8_t i = 0; i < N; i++) {
perm[i] = i;
stack[i] = 0;
}
uint8_t i = 1;
while (i < N) {
// print permutation to help debugging
printf("--- permutation: [");
for (int j = 0; j < N; j++) {
if (j > 0) {
printf(", ");
}
printf("%d", perm[j]+1);
}
printf("] ---\n");
// build the attribute list for the current permutation
struct lfs_rattr attrs[N];
for (int j = 0; j < N; j++) {
attrs[j] = *LFS_MKRATTR(
UATTR, perm[j]+1, 0,
&(uint32_t){0xaaaaaaaa}, 4,
(j+1 < N) ? &attrs[j+1] : NULL);
}
// test the given permutation
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, attrs) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
for (int j = 0; j < N; j++) {
lfs_rbyd_lookup(&lfs, &rbyd,
LFS_MKRTAG(UATTR, j+1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, j+1, 0);
}
// next permutation using Heap's algorithm
if (stack[i] < i) {
if (i % 2 == 0) {
uint8_t t = perm[0];
perm[0] = perm[i];
perm[i] = t;
} else {
uint8_t t = perm[stack[i]];
perm[stack[i]] = perm[i];
perm[i] = t;
}
stack[i] += 1;
i = 1;
} else {
stack[i] = 0;
i += 1;
}
}
'''
[cases.test_rbyd_multi_permutations]
defines.N = 'range(1, 8)'
in = 'lfs.c'
code = '''
lfs_t lfs;
lfs_init(&lfs, cfg) => 0;
lfs_rbyd_t rbyd_init = {
.block = 0,
.trunk = 0,
.noff = 0,
.rev = 1,
.crc = 0,
.count = 0,
.erased = true,
};
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// test all permutations of a given size
uint8_t perm[N];
uint8_t stack[N];
for (uint8_t i = 0; i < N; i++) {
perm[i] = i;
stack[i] = 0;
}
uint8_t i = 1;
while (i < N) {
// print permutation to help debugging
printf("--- permutation: [");
for (int j = 0; j < N; j++) {
if (j > 0) {
printf(", ");
}
printf("%d", perm[j]+1);
}
printf("] ---\n");
// test the given permutation with multiple commits
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
for (int j = 0; j < N; j++) {
lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(
UATTR, perm[j]+1, 0,
&(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
}
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
for (int j = 0; j < N; j++) {
lfs_rbyd_lookup(&lfs, &rbyd,
LFS_MKRTAG(UATTR, j+1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, j+1, 0);
}
// next permutation using Heap's algorithm
if (stack[i] < i) {
if (i % 2 == 0) {
uint8_t t = perm[0];
perm[0] = perm[i];
perm[i] = t;
} else {
uint8_t t = perm[stack[i]];
perm[stack[i]] = perm[i];
perm[i] = t;
}
stack[i] += 1;
i = 1;
} else {
stack[i] = 0;
i += 1;
}
}
'''