From ef7ee6eb7d7bc83508ab757d5074c7da5fb6927f Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sat, 31 Dec 2022 15:17:27 -0600 Subject: [PATCH] Added delete permutation testing (failing as expected) and some minor tweaks --- lfs.c | 10 +- scripts/dbgrbyd.py | 2 +- tests/test_rbyd.toml | 322 ++++++++++++++++--------------------------- 3 files changed, 127 insertions(+), 207 deletions(-) diff --git a/lfs.c b/lfs.c index 02ebff8f..a28e533f 100644 --- a/lfs.c +++ b/lfs.c @@ -1488,7 +1488,7 @@ static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_, // lt = lfs_rtag_weight_lt(attr->tag & ~0x7fff, count+1); // gt = lfs_rtag_weight_gt(attr->tag & ~0x7fff, count+1); // } - lt = lfs_rtag_weight_lt(tag & ~0x7fff, rbyd_->count+1); + lt = lfs_rtag_weight_lt(tag & ~0x7fff, rbyd_->count+1) - 1; gt = lfs_rtag_weight_gt(tag & ~0x7fff, rbyd_->count+1) + 1; } else { lt = lfs_rtag_weight_lt(tag, rbyd_->count+1); @@ -1917,13 +1917,13 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_, if (cut && lfs_rtag_isblack(alt) && ((lower && lfs_rtag_isgt(alt)) || (!lower && lfs_rtag_islt(alt)))) { + printf("bcut (%s, %s)\n", lower ? "lower" : "upper", lfs_rtag_isgt(alt) ? "gt" : "lt"); 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"); + if ((lower && lfs_rtag_isgt(p_alts[0])) + || (!lower && lfs_rtag_islt(p_alts[0]))) { + printf("rcut (%s, %s)\n", lower ? "lower" : "upper", lfs_rtag_isgt(p_alts[0]) ? "gt" : "lt"); lfs_rbyd_p_pop(p_alts, p_jumps); } } diff --git a/scripts/dbgrbyd.py b/scripts/dbgrbyd.py index 7d72be56..81a20ad6 100755 --- a/scripts/dbgrbyd.py +++ b/scripts/dbgrbyd.py @@ -371,7 +371,7 @@ def main(disk, block_size, block1, block2=None, *, and not tag & 0x4 else ''), '\x1b[m' if color and j_ >= off else '', ' (%s)' % ', '.join(notes) if notes - else ' %s' % ''.join( + else ' %s' % ''.join( ('\x1b[33my\x1b[m' if color else 'y') if alts[i] & 0x1 and i+1 < len(alts) diff --git a/tests/test_rbyd.toml b/tests/test_rbyd.toml index f710c52a..195e35ad 100644 --- a/tests/test_rbyd.toml +++ b/tests/test_rbyd.toml @@ -1841,98 +1841,6 @@ code = ''' => LFS_ERR_NOENT; ''' -[cases.test_rbyd_multi_remove] -in = 'lfs.c' -code = ''' - lfs_t lfs; - lfs_init(&lfs, cfg) => 0; - - lfs_rbyd_t init_rbyd = { - .block = 0, - .trunk = 0, - .off = 0, - .rev = 1, - .crc = 0, - .count = 0, - .erased = true, - }; - lfs_rbyd_t rbyd; - lfs_off_t off; - lfs_size_t size; - - // add and remove one attribute - rbyd = init_rbyd; - 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_MKRRMATTR(UATTR, 1, 0, NULL)) => 0; - - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size) - => LFS_ERR_NOENT; - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size) - => LFS_ERR_NOENT; - - lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size) - => LFS_ERR_NOENT; - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size) - => LFS_ERR_NOENT; - - // commit with two attributes, remove the first one - rbyd = init_rbyd; - 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_commit(&lfs, &rbyd, - LFS_MKRRMATTR(UATTR, 1, 0, NULL)) => 0; - - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size) - => LFS_MKRTAG(UATTR, 2, 0); - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size) - => LFS_MKRTAG(UATTR, 2, 0); - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size) - => LFS_ERR_NOENT; - - lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size) - => LFS_MKRTAG(UATTR, 2, 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; - - // commit with two attributes, remove the second one - rbyd = init_rbyd; - 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_commit(&lfs, &rbyd, - LFS_MKRRMATTR(UATTR, 2, 0, NULL)) => 0; - - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size) - => LFS_MKRTAG(UATTR, 1, 0); - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size) - => LFS_ERR_NOENT; - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size) - => LFS_ERR_NOENT; - - lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size) - => LFS_MKRTAG(UATTR, 1, 0); - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size) - => LFS_ERR_NOENT; - lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size) - => LFS_ERR_NOENT; -''' - [cases.test_rbyd_remove_permutations] defines.N = 'range(1, 7)' in = 'lfs.c' @@ -1961,115 +1869,6 @@ code = ''' stack[i] = 0; } - uint8_t i = 1; - while (i < N) { - // print permutation to help debugging - printf("--- permutation: ["); - for (int j = 0; j < N; j++) { - if (j > 0) { - printf(", "); - } - printf("%d", perm[j]+1); - } - printf("] ---\n"); - - // build the attribute list for the current permutation - struct lfs_rattr attrs[N]; - for (int j = 0; j < N; j++) { - attrs[j] = *LFS_MKRATTR( - UATTR, perm[j]+1, 0, - &(uint32_t){0xaaaaaaaa}, 4, - (j+1 < N) ? &attrs[j+1] : NULL); - } - - // create the given permutation - rbyd = init_rbyd; - lfs_bd_erase(&lfs, rbyd.block) => 0; - lfs_rbyd_commit(&lfs, &rbyd, attrs) => 0; - - // copy block so we can reset after each remove - lfs_rbyd_t backup_rbyd = rbyd; - uint8_t backup_block[BLOCK_SIZE]; - lfs_bd_read(&lfs, NULL, &lfs.rcache, rbyd.off, - rbyd.block, 0, backup_block, rbyd.off) => 0; - - // try removing each tag - for (int j = 0; j < N; j++) { - // print what we are removing to help debugging - printf("--- remove: %d ---\n", j+1); - - rbyd = backup_rbyd; - lfs_bd_erase(&lfs, rbyd.block) => 0; - lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false, - rbyd.block, 0, backup_block, rbyd.off) => 0; - - lfs_rbyd_commit(&lfs, &rbyd, - LFS_MKRRMATTR(UATTR, j+1, 0, NULL)) => 0; - - lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; - for (int k = 0; k < N; k++) { - lfs_srtag_t tag = lfs_rbyd_lookup(&lfs, &rbyd, - LFS_MKRTAG(UATTR, k+1, 0), &off, &size); - if (k == j) { - if (j == N-1) { - assert(tag == LFS_ERR_NOENT); - } else { - assert(tag == LFS_MKRTAG(UATTR, j+1+1, 0)); - } - } else { - assert(tag == LFS_MKRTAG(UATTR, k+1, 0)); - } - } - } - - // next permutation using Heap's algorithm - if (stack[i] < i) { - if (i % 2 == 0) { - uint8_t t = perm[0]; - perm[0] = perm[i]; - perm[i] = t; - } else { - uint8_t t = perm[stack[i]]; - perm[stack[i]] = perm[i]; - perm[i] = t; - } - stack[i] += 1; - i = 1; - } else { - stack[i] = 0; - i += 1; - } - } -''' - -[cases.test_rbyd_multi_remove_permutations] -defines.N = 'range(1, 7)' -in = 'lfs.c' -code = ''' - lfs_t lfs; - lfs_init(&lfs, cfg) => 0; - - lfs_rbyd_t init_rbyd = { - .block = 0, - .trunk = 0, - .off = 0, - .rev = 1, - .crc = 0, - .count = 0, - .erased = true, - }; - lfs_rbyd_t rbyd; - lfs_off_t off; - lfs_size_t size; - - // test all permutations of a given size - uint8_t perm[N]; - uint8_t stack[N]; - for (uint8_t i = 0; i < N; i++) { - perm[i] = i; - stack[i] = 0; - } - uint8_t i = 1; while (i < N) { // print permutation to help debugging @@ -3100,3 +2899,124 @@ code = ''' lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 3), buffer, 4) => LFS_ERR_NOENT; ''' + +[cases.test_rbyd_delete_permutations] +defines.N = 'range(1, 7)' +in = 'lfs.c' +code = ''' + lfs_t lfs; + lfs_init(&lfs, cfg) => 0; + + lfs_rbyd_t init_rbyd = { + .block = 0, + .trunk = 0, + .off = 0, + .rev = 1, + .crc = 0, + .count = 0, + .erased = true, + }; + lfs_rbyd_t rbyd; + const uint8_t names[6][4] = { + "\xaa\xaa\xaa\xaa", + "\xbb\xbb\xbb\xbb", + "\xcc\xcc\xcc\xcc", + "\xdd\xdd\xdd\xdd", + "\xee\xee\xee\xee", + "\xff\xff\xff\xff", + }; + uint8_t buffer[4]; + + // test all permutations of a given size + uint8_t perm[N]; + uint8_t stack[N]; + for (uint8_t i = 0; i < N; i++) { + perm[i] = i; + stack[i] = 0; + } + + uint8_t i = 1; + while (i < N) { + // print permutation to help debugging + printf("--- permutation: ["); + for (int j = 0; j < N; j++) { + if (j > 0) { + printf(", "); + } + printf("%d", perm[j]+1); + } + printf("] ---\n"); + + // create given permutation with multiple commits + rbyd = init_rbyd; + lfs_bd_erase(&lfs, rbyd.block) => 0; + + for (int j = 0; j < N; j++) { + // adjust id based on future insertions + uint16_t id = perm[j]; + for (int k = j+1; k < N; k++) { + if (perm[j] > perm[k]) { + id -= 1; + } + } + + lfs_rbyd_commit(&lfs, &rbyd, + LFS_MKRATTR(CREATEREG, 0, id+1, names[perm[j] % 6], 4, + NULL)) => 0; + } + assert(rbyd.count == N); + + // copy block so we can reset after each delete + lfs_rbyd_t backup_rbyd = rbyd; + uint8_t backup_block[BLOCK_SIZE]; + lfs_bd_read(&lfs, NULL, &lfs.rcache, rbyd.off, + rbyd.block, 0, backup_block, rbyd.off) => 0; + + // try deleting each id + for (int j = 0; j < N; j++) { + // print what we are deleting to help debugging + printf("--- delete: %d ---\n", j+1); + + rbyd = backup_rbyd; + lfs_bd_erase(&lfs, rbyd.block) => 0; + lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false, + rbyd.block, 0, backup_block, rbyd.off) => 0; + + lfs_rbyd_commit(&lfs, &rbyd, + LFS_MKRATTR(DELETE, 0, j+1, NULL, 0, NULL)) => 0; + assert(rbyd.count == N-1); + + lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; + for (int k = 0; k < N-1; k++) { + lfs_rbyd_get(&lfs, &rbyd, + LFS_MKRTAG(CREATEREG, 0, k+1), buffer, 4) => 4; + if (k >= j) { + assert(memcmp(buffer, names[(k+1) % 6], 4) == 0); + } else { + assert(memcmp(buffer, names[k % 6], 4) == 0); + } + } + lfs_rbyd_get(&lfs, &rbyd, + LFS_MKRTAG(CREATEREG, 0, N-1+1), buffer, 4) + => LFS_ERR_NOENT; + } + + // next permutation using Heap's algorithm + if (stack[i] < i) { + if (i % 2 == 0) { + uint8_t t = perm[0]; + perm[0] = perm[i]; + perm[i] = t; + } else { + uint8_t t = perm[stack[i]]; + perm[stack[i]] = perm[i]; + perm[i] = t; + } + stack[i] += 1; + i = 1; + } else { + stack[i] = 0; + i += 1; + } + } +'''