# Test this inner rbyd data-structure [cases.test_rbyd_commit_fetch] in = 'lfs.c' defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1] 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, }; // try an empty commit lfs_rbyd_t 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(GSTATE, 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(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, 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] in = 'lfs.c' defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1] 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, }; // try an empty commit lfs_rbyd_t 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(GSTATE, 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(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_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; ''' [cases.test_rbyd_commit_lookup] in = 'lfs.c' defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1] 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, }; // try an empty commit lfs_rbyd_t 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_off_t off; lfs_size_t size; lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) => LFS_ERR_NOENT; lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 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(GSTATE, 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(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0; lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) => LFS_MKRTAG(GSTATE, 1, 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_ERR_NOENT; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) => LFS_MKRTAG(GSTATE, 1, 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_ERR_NOENT; // commit with two attributes 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_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) => LFS_MKRTAG(GSTATE, 1, 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_ERR_NOENT; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) => LFS_MKRTAG(GSTATE, 1, 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_ERR_NOENT; ''' # TODO we should make sure lookup always returns <= the requested tag, # this may require fixing in lfs_rbyd_commit to make sure the weights lean # one way [cases.test_rbyd_multi_commit_lookup] in = 'lfs.c' defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1] 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, }; // try an empty commit lfs_rbyd_t rbyd = rbyd_init; lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0; lfs_off_t off; lfs_size_t size; lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) => LFS_ERR_NOENT; lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 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(GSTATE, 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(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0; lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) => LFS_MKRTAG(GSTATE, 1, 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_ERR_NOENT; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) => LFS_MKRTAG(GSTATE, 1, 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_ERR_NOENT; // commit with two attributes 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_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) => LFS_MKRTAG(GSTATE, 1, 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_ERR_NOENT; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) => LFS_MKRTAG(GSTATE, 1, 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_ERR_NOENT; ''' # [cases.test_rbyd_commit_fetchmatch] # [cases.test_rbyd_multi_commit_fetchmatch] [cases.test_rbyd_bifoliate] in = 'lfs.c' defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1] 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, }; // create a split in the leaves // .-'| // 1 1 2 lfs_rbyd_t 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_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); // 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(GSTATE, 2, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xbbbbbbbb}, 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); ''' [cases.test_rbyd_bflips] in = 'lfs.c' defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1] 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, }; // ignore a black edge // .----'| // 1 2 1 2 2 lfs_rbyd_t 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, 2, 0, &(uint32_t){0xcccccccc}, 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); // 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(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xcccccccc}, 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); ''' [cases.test_rbyd_trifoliate] in = 'lfs.c' defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1] 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, }; // without a flip // | 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, 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); // with a flip // >r // .-'| // | >b // .-'| .--|-'| // 2 3 2 3 1 rbyd = rbyd_init; lfs_bd_erase(&lfs, rbyd.block) => 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, 1, 0, &(uint32_t){0xcccccccc}, 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); ''' [cases.test_rbyd_rflips] in = 'lfs.c' defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1] 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, }; // ignore a red edge and black edge // | 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, 3, 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); // 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(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, 2, 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); // 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(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, 1, 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); // 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(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, 1, 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); '''