diff --git a/lfs.c b/lfs.c index e9a3a68a..58c57a7c 100644 --- a/lfs.c +++ b/lfs.c @@ -1568,9 +1568,9 @@ static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_, // should've taken red alt? needs a flip if (lt < 0 || gt < 0) { - LFS_ASSERT(lfs_rtag_isblack(alt)); LFS_ASSERT(p_alts[0]); LFS_ASSERT(lfs_rtag_isred(p_alts[0])); + LFS_ASSERT(lfs_rtag_isblack(alt)); printf("rflip %s (%x,%x)\n", lfs_rtag_isparallel(alt, p_alts[0]) ? "parallel" : "perpendicular", @@ -1777,7 +1777,7 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_, // queue of pending alts we can emulate rotations with lfs_rtag_t p_alts[3] = {0, 0, 0}; lfs_off_t p_jumps[3] = {0, 0, 0}; - lfs_off_t graft = 0; + lfs_off_t graft = lower_branch; // descend down tree, building alt pointers while (true) { @@ -1804,7 +1804,14 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_, if (!cut && lfs_rtag_follow(alt, lower_lt, lower_gt) != lfs_rtag_follow(alt, upper_lt, upper_gt)) { printf("beginning cut\n"); + printf("lower, upper = (%x, %x), (%x, %x)\n", lower_lt, lower_gt, upper_lt, upper_gt); cut = true; + + // TODO do we need this if we flip red alts early? + if (p_alts[0] && lfs_rtag_isred(p_alts[0])) { + upper_branch = graft; + lfs_rtag_untrim(p_alts[0], &upper_lt, &upper_gt); + } } // prune? @@ -1847,7 +1854,7 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_, } else { printf("ysplit nofollow\n"); - LFS_ASSERT(graft != 0); +// LFS_ASSERT(graft != 0); p_alts[0] = lfs_rtag_black( lfs_rtag_merge(alt, p_alts[0])); p_jumps[0] = graft; @@ -1855,7 +1862,7 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_, lfs_rtag_trim(alt, <, >); lfs_rbyd_p_red(p_alts, p_jumps); - graft = 0; + graft = branch; branch = branch_; goto next; } @@ -1863,13 +1870,12 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_, // should've taken red alt? needs a flip if (lt < 0 || gt < 0) { - LFS_ASSERT(lfs_rtag_isblack(alt)); - LFS_ASSERT(p_alts[0]); - LFS_ASSERT(lfs_rtag_isred(p_alts[0])); - printf("rflip %s (%x,%x)\n", lfs_rtag_isparallel(alt, p_alts[0]) ? "parallel" : "perpendicular", lt, gt); + LFS_ASSERT(p_alts[0]); + LFS_ASSERT(lfs_rtag_isred(p_alts[0])); + LFS_ASSERT(lfs_rtag_isblack(alt)); // if black alt would've been taken, it also needs a flip if (lfs_rtag_isparallel(alt, p_alts[0])) { @@ -1901,13 +1907,16 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_, // TODO can this be combined with prune? maybe not? // cut? - if (cut && ((lower && lfs_rtag_isgt(alt)) - || (!lower && lfs_rtag_islt(alt)))) { - if (p_alts[0]) { + if (cut && lfs_rtag_isblack(alt) + && ((lower && lfs_rtag_isgt(alt)) + || (!lower && lfs_rtag_islt(alt)))) { + if (p_alts[0] && lfs_rtag_isred(p_alts[0])) { + printf("bcut\n"); p_alts[0] = lfs_rtag_black(p_alts[0]); if ((lower && lfs_rtag_isgt(alt)) || (!lower && lfs_rtag_islt(alt))) { + printf("rcut\n"); lfs_rbyd_p_pop(p_alts, p_jumps); } } @@ -1941,9 +1950,9 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_, } // switch bounds we are following? - if (cut && lfs_rtag_isblack(alt) && !other_done) { - printf("switch bounds\n"); + if (cut && p_alts[0] && lfs_rtag_isblack(p_alts[0]) && !other_done) { lower = !lower; + printf("switch bounds -> %s\n", lower ? "lower" : "upper"); } // found end of tree? @@ -1985,6 +1994,7 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_, if (cut && !other_done) { other_done = true; lower = !lower; + printf("switch bounds -> %s\n", lower ? "lower" : "upper"); continue; } diff --git a/tests/test_rbyd.toml b/tests/test_rbyd.toml index 2da72815..ce561019 100644 --- a/tests/test_rbyd.toml +++ b/tests/test_rbyd.toml @@ -2149,7 +2149,7 @@ code = ''' ### Insertion testing ### -[cases.test_rbyd_insert] +[cases.test_rbyd_create] in = 'lfs.c' code = ''' lfs_t lfs; @@ -2167,7 +2167,7 @@ code = ''' lfs_rbyd_t rbyd; uint8_t buffer[4]; - // try to insert one id + // try to create one id rbyd = init_rbyd; lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, @@ -2184,7 +2184,7 @@ code = ''' => 4; assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); - // try to insert two ids + // try to create two ids rbyd = init_rbyd; lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, @@ -2204,7 +2204,7 @@ code = ''' lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 2), buffer, 4) => 4; assert(memcmp(buffer, "\xbb\xbb\xbb\xbb", 4) == 0); - // try to insert two in the other direction + // try to create two in the other direction rbyd = init_rbyd; lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, @@ -2224,7 +2224,7 @@ code = ''' lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 2), buffer, 4) => 4; assert(memcmp(buffer, "\xbb\xbb\xbb\xbb", 4) == 0); - // insert a third to the right + // create a third to the right rbyd = init_rbyd; lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, @@ -2249,7 +2249,7 @@ code = ''' lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 3), buffer, 4) => 4; assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); - // insert a third to the left + // create a third to the left rbyd = init_rbyd; lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, @@ -2274,7 +2274,7 @@ code = ''' lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 3), buffer, 4) => 4; assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); - // insert a third in the middle + // create a third in the middle rbyd = init_rbyd; lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, @@ -2300,7 +2300,7 @@ code = ''' assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); ''' -[cases.test_rbyd_multi_insert] +[cases.test_rbyd_multi_create] in = 'lfs.c' code = ''' lfs_t lfs; @@ -2318,7 +2318,7 @@ code = ''' lfs_rbyd_t rbyd; uint8_t buffer[4]; - // try to insert one id + // try to create one id rbyd = init_rbyd; lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, @@ -2335,7 +2335,7 @@ code = ''' => 4; assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); - // try to insert two ids + // try to create two ids rbyd = init_rbyd; lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, @@ -2356,7 +2356,7 @@ code = ''' lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 2), buffer, 4) => 4; assert(memcmp(buffer, "\xbb\xbb\xbb\xbb", 4) == 0); - // try to insert two in the other direction + // try to create two in the other direction rbyd = init_rbyd; lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, @@ -2377,7 +2377,7 @@ code = ''' lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 2), buffer, 4) => 4; assert(memcmp(buffer, "\xbb\xbb\xbb\xbb", 4) == 0); - // insert a third to the right + // create a third to the right rbyd = init_rbyd; lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, @@ -2404,7 +2404,7 @@ code = ''' lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 3), buffer, 4) => 4; assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); - // insert a third to the left + // create a third to the left rbyd = init_rbyd; lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, @@ -2431,7 +2431,7 @@ code = ''' lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 3), buffer, 4) => 4; assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); - // insert a third in the middle + // create a third in the middle rbyd = init_rbyd; lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_rbyd_commit(&lfs, &rbyd, @@ -2459,7 +2459,7 @@ code = ''' assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); ''' -[cases.test_rbyd_insert_permutations] +[cases.test_rbyd_create_permutations] defines.N = 'range(1, 8)' in = 'lfs.c' code = ''' @@ -2556,7 +2556,7 @@ code = ''' } ''' -[cases.test_rbyd_multi_insert_permutations] +[cases.test_rbyd_multi_create_permutations] defines.N = 'range(1, 8)' in = 'lfs.c' code = ''' @@ -2649,7 +2649,7 @@ code = ''' } ''' -[cases.test_rbyd_insert_large] +[cases.test_rbyd_create_large] in = 'lfs.c' # ORDER: # 0 = in-order @@ -3024,53 +3024,53 @@ code = ''' // lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 3), buffer, 4) // => LFS_ERR_NOENT; -// // try to delete the smallest of three -// rbyd = init_rbyd; -// lfs_bd_erase(&lfs, rbyd.block) => 0; -// lfs_rbyd_commit(&lfs, &rbyd, -// LFS_MKRATTR(CREATEREG, 0, 1, "\xaa\xaa\xaa\xaa", 4, -// LFS_MKRATTR(UATTR, 0, 1, "\xaa\xaa\xaa\xaa", 4, -// LFS_MKRATTR(CREATEREG, 0, 2, "\xbb\xbb\xbb\xbb", 4, -// LFS_MKRATTR(UATTR, 0, 2, "\xbb\xbb\xbb\xbb", 4, -// LFS_MKRATTR(CREATEREG, 0, 3, "\xcc\xcc\xcc\xcc", 4, -// LFS_MKRATTR(UATTR, 0, 3, "\xcc\xcc\xcc\xcc", 4, NULL))))))) => 0; -// lfs_rbyd_commit(&lfs, &rbyd, -// LFS_MKRATTR(DELETE, 0, 1, NULL, 0, NULL)) => 0; -// -// assert(rbyd.count == 2); -// lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 1), buffer, 4) -// => 4; -// assert(memcmp(buffer, "\xbb\xbb\xbb\xbb", 4) == 0); -// lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 0, 1), buffer, 4) -// => 4; -// assert(memcmp(buffer, "\xbb\xbb\xbb\xbb", 4) == 0); -// lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 2), buffer, 4) -// => 4; -// assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); -// lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 0, 2), buffer, 4) -// => 4; -// assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); -//// TODO -//// lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 3), buffer, 4) -//// => LFS_ERR_NOENT; -// -// lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; -// assert(rbyd.count == 2); -// lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 1), buffer, 4) -// => 4; -// assert(memcmp(buffer, "\xbb\xbb\xbb\xbb", 4) == 0); -// lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 0, 1), buffer, 4) -// => 4; -// assert(memcmp(buffer, "\xbb\xbb\xbb\xbb", 4) == 0); -// lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 2), buffer, 4) -// => 4; -// assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); -// lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 0, 2), buffer, 4) -// => 4; -// assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); -//// TODO -//// lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 3), buffer, 4) -//// => LFS_ERR_NOENT; + // try to delete the smallest of three + rbyd = init_rbyd; + lfs_bd_erase(&lfs, rbyd.block) => 0; + lfs_rbyd_commit(&lfs, &rbyd, + LFS_MKRATTR(CREATEREG, 0, 1, "\xaa\xaa\xaa\xaa", 4, + LFS_MKRATTR(UATTR, 0, 1, "\xaa\xaa\xaa\xaa", 4, + LFS_MKRATTR(CREATEREG, 0, 2, "\xbb\xbb\xbb\xbb", 4, + LFS_MKRATTR(UATTR, 0, 2, "\xbb\xbb\xbb\xbb", 4, + LFS_MKRATTR(CREATEREG, 0, 3, "\xcc\xcc\xcc\xcc", 4, + LFS_MKRATTR(UATTR, 0, 3, "\xcc\xcc\xcc\xcc", 4, NULL))))))) => 0; + lfs_rbyd_commit(&lfs, &rbyd, + LFS_MKRATTR(DELETE, 0, 1, NULL, 0, NULL)) => 0; + + assert(rbyd.count == 2); + lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 1), buffer, 4) + => 4; + assert(memcmp(buffer, "\xbb\xbb\xbb\xbb", 4) == 0); + lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 0, 1), buffer, 4) + => 4; + assert(memcmp(buffer, "\xbb\xbb\xbb\xbb", 4) == 0); + lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 2), buffer, 4) + => 4; + assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); + lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 0, 2), buffer, 4) + => 4; + assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); +// TODO +// lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 3), buffer, 4) +// => LFS_ERR_NOENT; + + lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; + assert(rbyd.count == 2); + lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 1), buffer, 4) + => 4; + assert(memcmp(buffer, "\xbb\xbb\xbb\xbb", 4) == 0); + lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 0, 1), buffer, 4) + => 4; + assert(memcmp(buffer, "\xbb\xbb\xbb\xbb", 4) == 0); + lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 2), buffer, 4) + => 4; + assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); + lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 0, 2), buffer, 4) + => 4; + assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); +// TODO +// lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 3), buffer, 4) +// => LFS_ERR_NOENT; // try to delete the middle rbyd = init_rbyd;