Got all <=7 lookup permutations working, required a recoloring fix

The alt pointers change position, but the colors are supposed to stay
the same. If you randomly mix up the colors it sure does make things
confusing.
This commit is contained in:
Christopher Haster
2022-12-27 13:51:06 -06:00
parent e73f1c0e8d
commit 084094116f
2 changed files with 89 additions and 9 deletions
+8 -9
View File
@@ -1335,18 +1335,18 @@ static void lfs_rbyd_p_red(
} else if (lfs_rtag_isparallel(p_alts[0], p_alts[2])) {
lfs_rtag_t alt_ = p_alts[1];
lfs_off_t jump_ = p_jumps[1];
p_alts[1] = p_alts[0];
p_alts[1] = lfs_rtag_red(p_alts[0]);
p_jumps[1] = p_jumps[0];
p_alts[0] = alt_;
p_alts[0] = lfs_rtag_black(alt_);
p_jumps[0] = jump_;
} else if (lfs_rtag_isparallel(p_alts[0], p_alts[1])) {
lfs_rtag_t alt_ = p_alts[2];
lfs_off_t jump_ = p_jumps[2];
p_alts[2] = p_alts[1];
p_alts[2] = lfs_rtag_red(p_alts[1]);
p_jumps[2] = p_jumps[1];
p_alts[1] = p_alts[0];
p_alts[1] = lfs_rtag_red(p_alts[0]);
p_jumps[1] = p_jumps[0];
p_alts[0] = alt_;
p_alts[0] = lfs_rtag_black(alt_);
p_jumps[0] = jump_;
} else {
LFS_ASSERT(false);
@@ -1540,20 +1540,19 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
if (tag_ != attr->tag) {
// bias the weights so that lookups always find the
// next biggest tag
lfs_rtag_t alt_;
if (lfs_rtag_weight(tag_) < lfs_rtag_weight(attr->tag)) {
alt_ = LFS_MKRALT(B, LT, lt+1
alt = LFS_MKRALT(B, LT, lt+1
+ lfs_rtag_weight(tag_)
- lfs_rtag_weight(attr->tag));
} else {
alt_ = LFS_MKRALT(B, GT, gt);
alt = LFS_MKRALT(B, GT, gt);
}
lfs_ssize_t delta = lfs_rbyd_p_push(lfs,
&lfs->pcache, &lfs->rcache,
block, off,
p_alts, p_jumps,
alt_, branch, &crc);
alt, branch, &crc);
if (delta < 0) {
return delta;
}
+81
View File
@@ -1405,3 +1405,84 @@ code = '''
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 6, 0), &off, &size)
=> LFS_MKRTAG(UATTR, 6, 0);
'''
[cases.test_rbyd_permutations]
defines.N = 'range(1, 8)'
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;
// 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");
// 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);
}
// test the given permutation
rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, attrs) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
for (int j = 0; j < N; j++) {
lfs_rbyd_lookup(&lfs, &rbyd,
LFS_MKRTAG(UATTR, j+1, 0), &off, &size)
=> LFS_MKRTAG(UATTR, j+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;
}
}
'''