# 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; // TODO test in-between lookups for consistently finding the next >= tag? lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) => LFS_ERR_NOENT; 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, 0, &off, &size) => LFS_ERR_NOENT; 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, 0, &off, &size) => LFS_MKRTAG(UATTR, 1, 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, 0, &off, &size) => LFS_MKRTAG(UATTR, 1, 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, 0, &off, &size) => LFS_MKRTAG(UATTR, 1, 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, 0, &off, &size) => LFS_MKRTAG(UATTR, 1, 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, 0, &off, &size) => LFS_ERR_NOENT; lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size) => LFS_ERR_NOENT; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; // TODO move these extra checks (for 0, in-between, enoent) to other tests lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) => LFS_ERR_NOENT; 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, 0, &off, &size) => LFS_MKRTAG(UATTR, 1, 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, 0, &off, &size) => LFS_MKRTAG(UATTR, 1, 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, 0, &off, &size) => LFS_MKRTAG(UATTR, 1, 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, 0, &off, &size) => LFS_MKRTAG(UATTR, 1, 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 // .-'| // 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 // .----'| // 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 // .-'| => .-'| // 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 // | 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 // .-'| .--|-'| // 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 // | 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 // | >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 // .----'| .-'| // | | >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 // .-'| .-------'| // | >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 // | .----'| // | 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 // .-------'| .-'| // r | >r // .----'| => | .-'| => .--|-'| // | b | | 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 // .-'| // 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 // .-'| => | .-'| // | >b | | 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 // | .----'| // | 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 // | .----'| // | 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 // 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(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 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(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 // | 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 // | | .-'| | | .-'| // 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 // b // .-------'| .-'| // | .--------|-'| // | | 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 // b // .-------'| .-'| // | b // | .----'| => .-----|-'| // | | 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 // | .----' | // | 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 // | .----' | // | 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(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 // .-'| // b // | .----'| => | .-----|-'| // | | 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 // .-'| // r // .-------'| .-----|-'| // | b // | .----'| => .--|-----|-'| // | | 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 // | .----' | // | | 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 // .-------'| | .-'| // | .-----------|-'| // | | 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 // .-------'| | .-'| // | b // | .----' | => .--------|-'| // | | 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 // | | .-------'| // | | 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 // | .----' | => | .--------|-'| // | | 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 // .-'| .-'| // r // .-------'| | .--------|-'| // | b // | .----' | => .--|--------|-'| // | | 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); '''