Added delete permutation testing (failing as expected) and some minor tweaks
This commit is contained in:
@@ -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);
|
// lt = lfs_rtag_weight_lt(attr->tag & ~0x7fff, count+1);
|
||||||
// gt = lfs_rtag_weight_gt(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;
|
gt = lfs_rtag_weight_gt(tag & ~0x7fff, rbyd_->count+1) + 1;
|
||||||
} else {
|
} else {
|
||||||
lt = lfs_rtag_weight_lt(tag, rbyd_->count+1);
|
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)
|
if (cut && lfs_rtag_isblack(alt)
|
||||||
&& ((lower && lfs_rtag_isgt(alt))
|
&& ((lower && lfs_rtag_isgt(alt))
|
||||||
|| (!lower && lfs_rtag_islt(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])) {
|
if (p_alts[0] && lfs_rtag_isred(p_alts[0])) {
|
||||||
printf("bcut\n");
|
|
||||||
p_alts[0] = lfs_rtag_black(p_alts[0]);
|
p_alts[0] = lfs_rtag_black(p_alts[0]);
|
||||||
|
|
||||||
if ((lower && lfs_rtag_isgt(alt))
|
if ((lower && lfs_rtag_isgt(p_alts[0]))
|
||||||
|| (!lower && lfs_rtag_islt(alt))) {
|
|| (!lower && lfs_rtag_islt(p_alts[0]))) {
|
||||||
printf("rcut\n");
|
printf("rcut (%s, %s)\n", lower ? "lower" : "upper", lfs_rtag_isgt(p_alts[0]) ? "gt" : "lt");
|
||||||
lfs_rbyd_p_pop(p_alts, p_jumps);
|
lfs_rbyd_p_pop(p_alts, p_jumps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -371,7 +371,7 @@ def main(disk, block_size, block1, block2=None, *,
|
|||||||
and not tag & 0x4 else ''),
|
and not tag & 0x4 else ''),
|
||||||
'\x1b[m' if color and j_ >= off else '',
|
'\x1b[m' if color and j_ >= off else '',
|
||||||
' (%s)' % ', '.join(notes) if notes
|
' (%s)' % ', '.join(notes) if notes
|
||||||
else ' %s' % ''.join(
|
else ' %s' % ''.join(
|
||||||
('\x1b[33my\x1b[m' if color else 'y')
|
('\x1b[33my\x1b[m' if color else 'y')
|
||||||
if alts[i] & 0x1
|
if alts[i] & 0x1
|
||||||
and i+1 < len(alts)
|
and i+1 < len(alts)
|
||||||
|
|||||||
+121
-201
@@ -1841,98 +1841,6 @@ code = '''
|
|||||||
=> LFS_ERR_NOENT;
|
=> 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]
|
[cases.test_rbyd_remove_permutations]
|
||||||
defines.N = 'range(1, 7)'
|
defines.N = 'range(1, 7)'
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
@@ -1961,115 +1869,6 @@ code = '''
|
|||||||
stack[i] = 0;
|
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;
|
uint8_t i = 1;
|
||||||
while (i < N) {
|
while (i < N) {
|
||||||
// print permutation to help debugging
|
// print permutation to help debugging
|
||||||
@@ -3100,3 +2899,124 @@ code = '''
|
|||||||
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 3), buffer, 4)
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(CREATEREG, 0, 3), buffer, 4)
|
||||||
=> LFS_ERR_NOENT;
|
=> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
|||||||
Reference in New Issue
Block a user