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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
Reference in New Issue
Block a user