diff --git a/lfs.c b/lfs.c index 47394faf..8489727c 100644 --- a/lfs.c +++ b/lfs.c @@ -543,6 +543,10 @@ static inline void lfs_rtag_untrim(lfs_rtag_t alt, } } +static inline lfs_rtag_t lfs_rtag_inc(lfs_rtag_t tag) { + return tag + 0x8; +} + static inline lfs_rtag_t lfs_rtag_red(lfs_rtag_t tag) { return tag | 0x1; } @@ -1158,6 +1162,7 @@ static int lfs_rbyd_fetch(lfs_t *lfs, static lfs_srtag_t lfs_rbyd_lookup(lfs_t *lfs, const lfs_rbyd_t *rbyd, lfs_rtag_t tag, lfs_off_t *off, lfs_size_t *size) { + printf("lookup(%08x)\n", tag); // no trunk yet? lfs_off_t branch = rbyd->trunk; if (!branch) { @@ -1382,6 +1387,7 @@ static void lfs_rbyd_p_red( static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd, const struct lfs_rattr *attrs) { + printf("commit()\n"); LFS_ASSERT(rbyd->erased); // setup commit state diff --git a/tests/test_rbyd.toml b/tests/test_rbyd.toml index 4f52c6c4..a06aa4fa 100644 --- a/tests/test_rbyd.toml +++ b/tests/test_rbyd.toml @@ -4,7 +4,7 @@ # test with a number of different erase values defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1] -[cases.test_rbyd_commit_fetch] +[cases.test_rbyd_fetch] in = 'lfs.c' code = ''' lfs_t lfs; @@ -38,12 +38,11 @@ code = ''' lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, - LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, - NULL))) => 0; + LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; ''' -[cases.test_rbyd_multi_commit_fetch] +[cases.test_rbyd_multi_fetch] in = 'lfs.c' code = ''' lfs_t lfs; @@ -83,7 +82,10 @@ code = ''' lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; ''' -[cases.test_rbyd_commit_lookup] +# [cases.test_rbyd_fetchmatch] +# [cases.test_rbyd_multi_fetchmatch] + +[cases.test_rbyd_lookup] in = 'lfs.c' code = ''' lfs_t lfs; @@ -144,8 +146,7 @@ code = ''' lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, - LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, - NULL))) => 0; + LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))) => 0; lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) => LFS_MKRTAG(GSTATE, 1, 0); @@ -167,7 +168,7 @@ code = ''' => LFS_ERR_NOENT; ''' -[cases.test_rbyd_multi_commit_lookup] +[cases.test_rbyd_multi_lookup] in = 'lfs.c' code = ''' lfs_t lfs; @@ -251,8 +252,95 @@ code = ''' => LFS_ERR_NOENT; ''' -# [cases.test_rbyd_commit_fetchmatch] -# [cases.test_rbyd_multi_commit_fetchmatch] +[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, + }; + + // 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 + lfs_rbyd_t rbyd = rbyd_init; + rbyd = rbyd_init; + lfs_bd_erase(&lfs, rbyd.block) => 0; + lfs_rbyd_commit(&lfs, &rbyd, + LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, + LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))) => 0; + + lfs_off_t off; + lfs_size_t size; + lfs_srtag_t tag = lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size); + assert(tag == LFS_MKRTAG(GSTATE, 1, 0)); + // TODO use lfs_tag_incid? + tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size); + assert(tag == LFS_MKRTAG(GSTATE, 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(GSTATE, 1, 0)); + tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size); + assert(tag == LFS_MKRTAG(GSTATE, 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, + }; + + // 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 + lfs_rbyd_t rbyd = rbyd_init; + rbyd = rbyd_init; + lfs_bd_erase(&lfs, rbyd.block) => 0; + lfs_rbyd_commit(&lfs, &rbyd, + LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0; + lfs_rbyd_commit(&lfs, &rbyd, + LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)) => 0; + + lfs_off_t off; + lfs_size_t size; + lfs_srtag_t tag = lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size); + assert(tag == LFS_MKRTAG(GSTATE, 1, 0)); + tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size); + assert(tag == LFS_MKRTAG(GSTATE, 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(GSTATE, 1, 0)); + tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size); + assert(tag == LFS_MKRTAG(GSTATE, 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' @@ -321,7 +409,7 @@ code = ''' .erased = true, }; - // ignore a black edge + // ignore a black edge // .----'| // 1 2 1 2 2 @@ -374,7 +462,7 @@ code = ''' .erased = true, }; - // ignore a black edge + // ignore a black edge // | 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; @@ -493,7 +581,7 @@ code = ''' lfs_rbyd_commit(&lfs, &rbyd, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, - LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, + LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; @@ -515,7 +603,7 @@ code = ''' lfs_rbyd_commit(&lfs, &rbyd, LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xbbbbbbbb}, 4, - LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xcccccccc}, 4, + LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; @@ -584,7 +672,7 @@ code = ''' lfs_rbyd_commit(&lfs, &rbyd, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xbbbbbbbb}, 4, - LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4, + LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; @@ -610,7 +698,7 @@ code = ''' lfs_rbyd_commit(&lfs, &rbyd, LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xbbbbbbbb}, 4, - LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4, + LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; @@ -636,7 +724,7 @@ code = ''' lfs_rbyd_commit(&lfs, &rbyd, LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, - LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, + LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; @@ -649,3 +737,653 @@ code = ''' lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) => LFS_MKRTAG(GSTATE, 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, + }; + + // all three the same + // | .----'| + // | 0; + lfs_rbyd_commit(&lfs, &rbyd, + LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, + LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, + LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, + LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0; + + lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; + lfs_off_t off; + lfs_size_t size; + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 1, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 2, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 3, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 4, 0); + + // yellow and red alt the same + // | .----'| + // | 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(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, + LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, + LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4, + LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0; + + lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 1, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 2, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 3, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 4, 0); + + // yellow and black alt the same + // r | | .----'| => | .-'| + // | >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(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, + LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xbbbbbbbb}, 4, + LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xcccccccc}, 4, + LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0; + + lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 1, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 2, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 3, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 4, 0); + + // red and black alt the same + // >y r | | .----'| => | .-'| + // | 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(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, + LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xbbbbbbbb}, 4, + LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xcccccccc}, 4, + LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0; + + lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 1, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 2, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 3, 0); + lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) + => LFS_MKRTAG(GSTATE, 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, +# }; +# +# // split a yellow triple, not taking any alt +# // | 0; +# lfs_rbyd_commit(&lfs, &rbyd, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_off_t off; +# lfs_size_t size; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 4, 0); +# +# // split a yellow triple, taking the black alt +# // | 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(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 4, 0); +# +# // split a yellow triple, taking the red alt +# // b +# // .-------'| .-'| +# // | .--------|-'| +# // | | 0; +# lfs_rbyd_commit(&lfs, &rbyd, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 4, 0); +# +# // split a yellow triple, taking the yellow alt +# // b +# // .-------'| .-'| +# // | b +# // | .----'| => .-----|-'| +# // | | 0; +# lfs_rbyd_commit(&lfs, &rbyd, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 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, +# }; +# +# // split a yellow triple, not taking any alt +# // | .----' | +# // | 0; +# lfs_rbyd_commit(&lfs, &rbyd, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_off_t off; +# lfs_size_t size; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 4, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 5, 0); +# +# // split a yellow triple, taking the black alt +# // | .----' | +# // | r +# // | .----'| | | .-'| +# // | | 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(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 4, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 5, 0); +# +# // split a yellow triple, taking the red alt +# // >b +# // .-'| +# // b +# // | .----'| => | .-----|-'| +# // | | 0; +# lfs_rbyd_commit(&lfs, &rbyd, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 4, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 5, 0); +# +# // split a yellow triple, taking the yellow alt +# // >b +# // .-'| +# // r +# // .-------'| .-----|-'| +# // | b +# // | .----'| => .--|-----|-'| +# // | | 0; +# lfs_rbyd_commit(&lfs, &rbyd, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 4, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 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, +# }; +# +# // don't prune +# // | .----' | +# // | | 0; +# lfs_rbyd_commit(&lfs, &rbyd, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, +# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xffffffff}, 4, NULL))))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_off_t off; +# lfs_size_t size; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 4, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 5, 0); +# +# // prune by taking a red alt +# // b +# // .-------'| | .-'| +# // | .-----------|-'| +# // | | 0; +# lfs_rbyd_commit(&lfs, &rbyd, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xeeeeeeee}, 4, NULL))))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 4, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 5, 0); +# +# // prune by taking a yellow alt (this needs to prune during the rflip) +# // b +# // .-------'| | .-'| +# // | b +# // | .----' | => .--------|-'| +# // | | 0; +# lfs_rbyd_commit(&lfs, &rbyd, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xeeeeeeee}, 4, NULL))))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 4, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 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, +# }; +# +# // don't prune +# // | | .-------'| +# // | | 0; +# lfs_rbyd_commit(&lfs, &rbyd, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, +# LFS_MKRATTR(GSTATE, 6, 0, &(uint32_t){0xffffffff}, 4, NULL))))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_off_t off; +# lfs_size_t size; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 4, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 5, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 6, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 6, 0); +# +# // prune by taking a red alt +# // b +# // .-'| .-'| +# // b +# // | .----' | => | .--------|-'| +# // | | 0; +# lfs_rbyd_commit(&lfs, &rbyd, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 6, 0, &(uint32_t){0xeeeeeeee}, 4, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xeeeeeeee}, 4, NULL))))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 4, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 5, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 6, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 6, 0); +# +# // prune by taking a yellow alt (this needs to prune during the rflip) +# // b +# // .-'| .-'| +# // r +# // .-------'| | .--------|-'| +# // | b +# // | .----' | => .--|--------|-'| +# // | | 0; +# lfs_rbyd_commit(&lfs, &rbyd, +# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xaaaaaaaa}, 4, +# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xbbbbbbbb}, 4, +# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4, +# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xdddddddd}, 4, +# LFS_MKRATTR(GSTATE, 6, 0, &(uint32_t){0xeeeeeeee}, 4, +# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xeeeeeeee}, 4, NULL))))))) => 0; +# +# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 1, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 2, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 3, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 4, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 5, 0); +# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 6, 0), &off, &size) +# => LFS_MKRTAG(GSTATE, 6, 0); +#'''