Added sparse btree tests, fixed found bugs (grow/shrink bisect)
- After a B-tree split, when we're append pending attributes, it's possible for the id chosen for bisection to be itself modified by pending grows/shrinks. This needs to be accounted for in the two passes for the two children. But this means our tests are working.
This commit is contained in:
@@ -3495,8 +3495,9 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
// upper layers should make sure this can't fail by limiting the
|
// upper layers should make sure this can't fail by limiting the
|
||||||
// maximum commit size
|
// maximum commit size
|
||||||
// TODO filter-like tag? "from" but from device?
|
// TODO filter-like tag? "from" but from device?
|
||||||
|
lfs_ssize_t bisect_ = bisect;
|
||||||
for (const struct lfsr_attr *attr = attrs; attr; attr = attr->next) {
|
for (const struct lfsr_attr *attr = attrs; attr; attr = attr->next) {
|
||||||
if (attr->id < bisect) {
|
if (attr->id < bisect_) {
|
||||||
err = lfsr_rbyd_append(lfs, &rbyd_,
|
err = lfsr_rbyd_append(lfs, &rbyd_,
|
||||||
attr->tag, attr->id,
|
attr->tag, attr->id,
|
||||||
LFSR_DATA_BUF(attr->buffer, attr->size));
|
LFSR_DATA_BUF(attr->buffer, attr->size));
|
||||||
@@ -3505,6 +3506,15 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we need to make sure we keep bisect updated with weight changes
|
||||||
|
if (attr->id < bisect_) {
|
||||||
|
if (attr->tag == LFSR_TAG_GROW) {
|
||||||
|
bisect_ += attr->size;
|
||||||
|
} else if (attr->tag == LFSR_TAG_SHRINK) {
|
||||||
|
bisect_ -= attr->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalize commit
|
// finalize commit
|
||||||
@@ -3567,16 +3577,26 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
// commit pending attrs, these may need to go into both rbyds,
|
// commit pending attrs, these may need to go into both rbyds,
|
||||||
// upper layers should make sure this can't fail by limiting the
|
// upper layers should make sure this can't fail by limiting the
|
||||||
// maximum commit size
|
// maximum commit size
|
||||||
|
bisect_ = bisect;
|
||||||
for (const struct lfsr_attr *attr = attrs; attr; attr = attr->next) {
|
for (const struct lfsr_attr *attr = attrs; attr; attr = attr->next) {
|
||||||
if (attr->id >= bisect) {
|
if (attr->id >= bisect_) {
|
||||||
err = lfsr_rbyd_append(lfs, &sibling,
|
err = lfsr_rbyd_append(lfs, &sibling,
|
||||||
attr->tag, attr->id-bisect,
|
attr->tag, attr->id-bisect_,
|
||||||
LFSR_DATA_BUF(attr->buffer, attr->size));
|
LFSR_DATA_BUF(attr->buffer, attr->size));
|
||||||
if (err) {
|
if (err) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we need to make sure we keep bisect updated with weight changes
|
||||||
|
if (attr->id < bisect_) {
|
||||||
|
if (attr->tag == LFSR_TAG_GROW) {
|
||||||
|
bisect_ += attr->size;
|
||||||
|
} else if (attr->tag == LFSR_TAG_SHRINK) {
|
||||||
|
bisect_ -= attr->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalize commit
|
// finalize commit
|
||||||
@@ -3978,16 +3998,19 @@ static int lfsr_btree_push(lfs_t *lfs,
|
|||||||
// return ENOENT, is this ok?
|
// return ENOENT, is this ok?
|
||||||
lfsr_rbyd_t rbyd;
|
lfsr_rbyd_t rbyd;
|
||||||
lfs_ssize_t rid;
|
lfs_ssize_t rid;
|
||||||
|
lfs_size_t rweight;
|
||||||
lfs_ssize_t size = lfsr_btree_lookup(lfs, btree,
|
lfs_ssize_t size = lfsr_btree_lookup(lfs, btree,
|
||||||
lfs_min32(id, btree->weight-1),
|
lfs_min32(id, btree->weight-1),
|
||||||
NULL, NULL, &rbyd, &rid, NULL, NULL, 0);
|
NULL, NULL, &rbyd, &rid, &rweight, NULL, 0);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust rid if we're appending
|
// adjust rid for push
|
||||||
if (id >= btree->weight) {
|
if (id >= btree->weight) {
|
||||||
rid += 1;
|
rid += 1;
|
||||||
|
} else {
|
||||||
|
rid -= rweight-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// commit our id into the tree, letting lfsr_btree_commit take care
|
// commit our id into the tree, letting lfsr_btree_commit take care
|
||||||
|
|||||||
+350
-2
@@ -398,15 +398,26 @@ code = '''
|
|||||||
|
|
||||||
// add to btree
|
// add to btree
|
||||||
lfsr_btree_push(&lfs, &btree, id, LFSR_TAG_INLINED, 1,
|
lfsr_btree_push(&lfs, &btree, id, LFSR_TAG_INLINED, 1,
|
||||||
&alphas[i], 1) => 0;
|
&alphas[i % 26], 1) => 0;
|
||||||
|
|
||||||
// add to sim
|
// add to sim
|
||||||
memcpy(&sim[id+1], &sim[id], sim_size-id);
|
memcpy(&sim[id+1], &sim[id], sim_size-id);
|
||||||
sim[id] = alphas[i];
|
sim[id] = alphas[i % 26];
|
||||||
sim_size += 1;
|
sim_size += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that btree matches sim
|
// check that btree matches sim
|
||||||
|
printf("expd: [");
|
||||||
|
bool first = true;
|
||||||
|
for (lfs_size_t i = 0; i < N; i++) {
|
||||||
|
if (!first) {
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
printf("%c", sim[i]);
|
||||||
|
}
|
||||||
|
printf("]\n");
|
||||||
|
|
||||||
assert(btree.weight == N);
|
assert(btree.weight == N);
|
||||||
|
|
||||||
uint8_t buffer[4];
|
uint8_t buffer[4];
|
||||||
@@ -433,3 +444,340 @@ code = '''
|
|||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
[cases.test_btree_sparse]
|
||||||
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
|
||||||
|
defines.W = 5
|
||||||
|
in = 'lfs.c'
|
||||||
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_init(&lfs, cfg) => 0;
|
||||||
|
// create free lookahead
|
||||||
|
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
|
||||||
|
lfs.free.off = 0;
|
||||||
|
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
|
||||||
|
lfs.cfg->block_count);
|
||||||
|
lfs.free.i = 0;
|
||||||
|
lfs_alloc_ack(&lfs);
|
||||||
|
|
||||||
|
// create a tree with N elements
|
||||||
|
lfsr_btree_t btree = LFSR_BTREE_NULL;
|
||||||
|
const char *alphas = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
for (lfs_size_t i = 0; i < N; i++) {
|
||||||
|
lfsr_btree_push(&lfs, &btree, i*W, LFSR_TAG_INLINED, W,
|
||||||
|
&alphas[i % 26], 1) => 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that the elements are in the tree
|
||||||
|
uint8_t buffer[4];
|
||||||
|
lfsr_tag_t tag_;
|
||||||
|
lfs_size_t id_;
|
||||||
|
lfs_size_t weight_;
|
||||||
|
|
||||||
|
for (lfs_size_t i = 0; i < N; i++) {
|
||||||
|
lfsr_btree_get(&lfs, &btree, i*W+W-1,
|
||||||
|
&tag_, &id_, &weight_,
|
||||||
|
buffer, 4) => 1;
|
||||||
|
assert(tag_ == LFSR_TAG_INLINED);
|
||||||
|
assert(id_ == i*W+W-1);
|
||||||
|
assert(weight_ == W);
|
||||||
|
assert(memcmp(buffer, &alphas[i % 26], 1) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// and check that we can't lookup elements that aren't in the tree
|
||||||
|
lfsr_btree_get(&lfs, &btree, N*W,
|
||||||
|
&tag_, &id_, &weight_,
|
||||||
|
buffer, 4) => LFS_ERR_NOENT;
|
||||||
|
'''
|
||||||
|
|
||||||
|
[cases.test_btree_sparse_fuzz]
|
||||||
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
|
||||||
|
defines.W = 5
|
||||||
|
defines.ITER = 10
|
||||||
|
in = 'lfs.c'
|
||||||
|
code = '''
|
||||||
|
const char *alphas = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
// iterate through severals seeds that we can reproduce easily
|
||||||
|
for (uint32_t seed = 1; seed < ITER+1; seed++) {
|
||||||
|
// create lfs here since we need to reset each iteration, we're
|
||||||
|
// space constrained and we can't expect gc to work at this point
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_init(&lfs, cfg) => 0;
|
||||||
|
// create free lookahead
|
||||||
|
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
|
||||||
|
lfs.free.off = 0;
|
||||||
|
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
|
||||||
|
lfs.cfg->block_count);
|
||||||
|
lfs.free.i = 0;
|
||||||
|
lfs_alloc_ack(&lfs);
|
||||||
|
|
||||||
|
// create a btree
|
||||||
|
lfsr_btree_t btree = LFSR_BTREE_NULL;
|
||||||
|
|
||||||
|
// set up a simulation to compare against
|
||||||
|
//
|
||||||
|
// fun fact this is slower than our actual tree! unfun fact this is
|
||||||
|
// starting to be a problem...
|
||||||
|
char *sim = malloc(N);
|
||||||
|
lfs_size_t *sim_weights = malloc(N*sizeof(lfs_size_t));
|
||||||
|
lfs_size_t sim_size = 0;
|
||||||
|
memset(sim, 0, N);
|
||||||
|
memset(sim_weights, 0, N*sizeof(lfs_size_t));
|
||||||
|
|
||||||
|
uint32_t prng = seed;
|
||||||
|
for (lfs_size_t i = 0; i < N; i++) {
|
||||||
|
// choose a pseudo-random id
|
||||||
|
lfs_size_t id = TEST_PRNG(&prng) % (sim_size+1);
|
||||||
|
// choose a pseudo-random weight
|
||||||
|
lfs_size_t weight = 1 + (TEST_PRNG(&prng) % W);
|
||||||
|
|
||||||
|
// calculate actual id in btree space
|
||||||
|
lfs_size_t weighted_id = 0;
|
||||||
|
for (lfs_size_t j = 0; j < id; j++) {
|
||||||
|
weighted_id += sim_weights[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to btree
|
||||||
|
lfsr_btree_push(&lfs, &btree, weighted_id, LFSR_TAG_INLINED, weight,
|
||||||
|
&alphas[i % 26], 1) => 0;
|
||||||
|
|
||||||
|
// add to sim
|
||||||
|
memcpy(&sim[id+1], &sim[id], sim_size-id);
|
||||||
|
memcpy(&sim_weights[id+1], &sim_weights[id],
|
||||||
|
(sim_size-id)*sizeof(lfs_size_t));
|
||||||
|
sim[id] = alphas[i % 26];
|
||||||
|
sim_weights[id] = weight;
|
||||||
|
sim_size += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that btree matches sim
|
||||||
|
printf("expd: [");
|
||||||
|
bool first = true;
|
||||||
|
for (lfs_size_t i = 0; i < N; i++) {
|
||||||
|
// calculate actual id in btree space
|
||||||
|
lfs_size_t weighted_id = 0;
|
||||||
|
for (lfs_size_t j = 0; j < i; j++) {
|
||||||
|
weighted_id += sim_weights[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!first) {
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
printf("%dw%d=%c", weighted_id+sim_weights[i]-1,
|
||||||
|
sim_weights[i], sim[i]);
|
||||||
|
}
|
||||||
|
printf("]\n");
|
||||||
|
|
||||||
|
lfs_size_t total_weight = 0;
|
||||||
|
for (lfs_size_t j = 0; j < N; j++) {
|
||||||
|
total_weight += sim_weights[j];
|
||||||
|
}
|
||||||
|
assert(btree.weight == total_weight);
|
||||||
|
|
||||||
|
uint8_t buffer[4];
|
||||||
|
lfsr_tag_t tag_;
|
||||||
|
lfs_size_t id_;
|
||||||
|
lfs_size_t weight_;
|
||||||
|
for (lfs_size_t i = 0; i < N; i++) {
|
||||||
|
// calculate actual id in btree space
|
||||||
|
lfs_size_t weighted_id = 0;
|
||||||
|
for (lfs_size_t j = 0; j < i; j++) {
|
||||||
|
weighted_id += sim_weights[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
lfsr_btree_get(&lfs, &btree, weighted_id+sim_weights[i]-1,
|
||||||
|
&tag_, &id_, &weight_,
|
||||||
|
buffer, 4) => 1;
|
||||||
|
assert(tag_ == LFSR_TAG_INLINED);
|
||||||
|
assert(id_ == weighted_id+sim_weights[i]-1);
|
||||||
|
assert(weight_ == sim_weights[i]);
|
||||||
|
assert(memcmp(buffer, &sim[i], 1) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// and no extra elements
|
||||||
|
lfsr_btree_get(&lfs, &btree, total_weight,
|
||||||
|
&tag_, &id_, &weight_,
|
||||||
|
buffer, 4) => LFS_ERR_NOENT;
|
||||||
|
|
||||||
|
// clean up sim
|
||||||
|
free(sim);
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
|
||||||
|
[cases.test_btree_traverse]
|
||||||
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
|
||||||
|
defines.W = 5
|
||||||
|
in = 'lfs.c'
|
||||||
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_init(&lfs, cfg) => 0;
|
||||||
|
// create free lookahead
|
||||||
|
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
|
||||||
|
lfs.free.off = 0;
|
||||||
|
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
|
||||||
|
lfs.cfg->block_count);
|
||||||
|
lfs.free.i = 0;
|
||||||
|
lfs_alloc_ack(&lfs);
|
||||||
|
|
||||||
|
// create a tree with N elements
|
||||||
|
lfsr_btree_t btree = LFSR_BTREE_NULL;
|
||||||
|
const char *alphas = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
for (lfs_size_t i = 0; i < N; i++) {
|
||||||
|
lfsr_btree_push(&lfs, &btree, i*W, LFSR_TAG_INLINED, W,
|
||||||
|
&alphas[i % 26], 1) => 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// traverse the elements in the tree
|
||||||
|
uint8_t buffer[4];
|
||||||
|
lfs_size_t id_ = -1;
|
||||||
|
lfsr_tag_t tag_;
|
||||||
|
lfs_size_t weight_;
|
||||||
|
for (lfs_size_t i = 0; i < N; i++) {
|
||||||
|
lfsr_btree_get(&lfs, &btree, id_+1,
|
||||||
|
&tag_, &id_, &weight_,
|
||||||
|
buffer, 4) => 1;
|
||||||
|
assert(tag_ == LFSR_TAG_INLINED);
|
||||||
|
assert(id_ == i*W+W-1);
|
||||||
|
assert(weight_ == W);
|
||||||
|
assert(memcmp(buffer, &alphas[i % 26], 1) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// and check that we can't lookup elements that aren't in the tree
|
||||||
|
lfsr_btree_get(&lfs, &btree, id_+1,
|
||||||
|
&tag_, &id_, &weight_,
|
||||||
|
buffer, 4) => LFS_ERR_NOENT;
|
||||||
|
'''
|
||||||
|
|
||||||
|
[cases.test_btree_traverse_fuzz]
|
||||||
|
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
|
||||||
|
defines.W = 5
|
||||||
|
defines.ITER = 10
|
||||||
|
in = 'lfs.c'
|
||||||
|
code = '''
|
||||||
|
const char *alphas = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
// iterate through severals seeds that we can reproduce easily
|
||||||
|
for (uint32_t seed = 1; seed < ITER+1; seed++) {
|
||||||
|
// create lfs here since we need to reset each iteration, we're
|
||||||
|
// space constrained and we can't expect gc to work at this point
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_init(&lfs, cfg) => 0;
|
||||||
|
// create free lookahead
|
||||||
|
memset(lfs.free.buffer, 0, lfs.cfg->lookahead_size);
|
||||||
|
lfs.free.off = 0;
|
||||||
|
lfs.free.size = lfs_min(8*lfs.cfg->lookahead_size,
|
||||||
|
lfs.cfg->block_count);
|
||||||
|
lfs.free.i = 0;
|
||||||
|
lfs_alloc_ack(&lfs);
|
||||||
|
|
||||||
|
// create a btree
|
||||||
|
lfsr_btree_t btree = LFSR_BTREE_NULL;
|
||||||
|
|
||||||
|
// set up a simulation to compare against
|
||||||
|
//
|
||||||
|
// fun fact this is slower than our actual tree! unfun fact this is
|
||||||
|
// starting to be a problem...
|
||||||
|
char *sim = malloc(N);
|
||||||
|
lfs_size_t *sim_weights = malloc(N*sizeof(lfs_size_t));
|
||||||
|
lfs_size_t sim_size = 0;
|
||||||
|
memset(sim, 0, N);
|
||||||
|
memset(sim_weights, 0, N*sizeof(lfs_size_t));
|
||||||
|
|
||||||
|
uint32_t prng = seed;
|
||||||
|
for (lfs_size_t i = 0; i < N; i++) {
|
||||||
|
// choose a pseudo-random id
|
||||||
|
lfs_size_t id = TEST_PRNG(&prng) % (sim_size+1);
|
||||||
|
// choose a pseudo-random weight
|
||||||
|
lfs_size_t weight = 1 + (TEST_PRNG(&prng) % W);
|
||||||
|
|
||||||
|
// calculate actual id in btree space
|
||||||
|
lfs_size_t weighted_id = 0;
|
||||||
|
for (lfs_size_t j = 0; j < id; j++) {
|
||||||
|
weighted_id += sim_weights[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to btree
|
||||||
|
lfsr_btree_push(&lfs, &btree, weighted_id, LFSR_TAG_INLINED, weight,
|
||||||
|
&alphas[i % 26], 1) => 0;
|
||||||
|
|
||||||
|
// add to sim
|
||||||
|
memcpy(&sim[id+1], &sim[id], sim_size-id);
|
||||||
|
memcpy(&sim_weights[id+1], &sim_weights[id],
|
||||||
|
(sim_size-id)*sizeof(lfs_size_t));
|
||||||
|
sim[id] = alphas[i % 26];
|
||||||
|
sim_weights[id] = weight;
|
||||||
|
sim_size += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that btree matches sim
|
||||||
|
printf("expd: [");
|
||||||
|
bool first = true;
|
||||||
|
for (lfs_size_t i = 0; i < N; i++) {
|
||||||
|
// calculate actual id in btree space
|
||||||
|
lfs_size_t weighted_id = 0;
|
||||||
|
for (lfs_size_t j = 0; j < i; j++) {
|
||||||
|
weighted_id += sim_weights[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!first) {
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
printf("%dw%d=%c", weighted_id+sim_weights[i]-1,
|
||||||
|
sim_weights[i], sim[i]);
|
||||||
|
}
|
||||||
|
printf("]\n");
|
||||||
|
|
||||||
|
lfs_size_t total_weight = 0;
|
||||||
|
for (lfs_size_t j = 0; j < N; j++) {
|
||||||
|
total_weight += sim_weights[j];
|
||||||
|
}
|
||||||
|
assert(btree.weight == total_weight);
|
||||||
|
|
||||||
|
uint8_t buffer[4];
|
||||||
|
lfs_size_t id_ = -1;
|
||||||
|
lfsr_tag_t tag_;
|
||||||
|
lfs_size_t weight_;
|
||||||
|
for (lfs_size_t i = 0; i < N; i++) {
|
||||||
|
// calculate actual id in btree space
|
||||||
|
lfs_size_t weighted_id = 0;
|
||||||
|
for (lfs_size_t j = 0; j < i; j++) {
|
||||||
|
weighted_id += sim_weights[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
lfsr_btree_get(&lfs, &btree, id_+1,
|
||||||
|
&tag_, &id_, &weight_,
|
||||||
|
buffer, 4) => 1;
|
||||||
|
assert(tag_ == LFSR_TAG_INLINED);
|
||||||
|
assert(id_ == weighted_id+sim_weights[i]-1);
|
||||||
|
assert(weight_ == sim_weights[i]);
|
||||||
|
assert(memcmp(buffer, &sim[i], 1) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// and no extra elements
|
||||||
|
lfsr_btree_get(&lfs, &btree, id_+1,
|
||||||
|
&tag_, &id_, &weight_,
|
||||||
|
buffer, 4) => LFS_ERR_NOENT;
|
||||||
|
|
||||||
|
// clean up sim
|
||||||
|
free(sim);
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
|
||||||
|
# [cases.test_btree_update]
|
||||||
|
# [cases.test_btree_update_fuzz]
|
||||||
|
# [cases.test_btree_update_sparse]
|
||||||
|
# [cases.test_btree_update_sparse_fuzz]
|
||||||
|
# [cases.test_btree_update_traverse]
|
||||||
|
# [cases.test_btree_update_traverse_fuzz]
|
||||||
|
|
||||||
|
# [cases.test_btree_pop]
|
||||||
|
# [cases.test_btree_pop_fuzz]
|
||||||
|
|
||||||
|
# [cases.test_btree_split]
|
||||||
|
# [cases.test_btree_split_fuzz]
|
||||||
|
|
||||||
|
# [cases.test_btree_general_fuzz]
|
||||||
|
|
||||||
|
# TODO also test copy-on-write!
|
||||||
|
|||||||
+43
-42
@@ -11691,7 +11691,7 @@ code = '''
|
|||||||
// choose an id
|
// choose an id
|
||||||
lfs_ssize_t id = TEST_PRNG(&prng) % (count+1);
|
lfs_ssize_t id = TEST_PRNG(&prng) % (count+1);
|
||||||
// choose a weight
|
// choose a weight
|
||||||
lfs_size_t weight = 1 + (TEST_PRNG(&prng) % (W-1));
|
lfs_size_t weight = 1 + (TEST_PRNG(&prng) % W);
|
||||||
|
|
||||||
if (id == (lfs_ssize_t)count || op == 0) {
|
if (id == (lfs_ssize_t)count || op == 0) {
|
||||||
printf("c%dw%d=%c", id, weight, alpha[i % 26]);
|
printf("c%dw%d=%c", id, weight, alpha[i % 26]);
|
||||||
@@ -11729,12 +11729,12 @@ code = '''
|
|||||||
// choose an id
|
// choose an id
|
||||||
lfs_ssize_t id = TEST_PRNG(&prng) % (count+1);
|
lfs_ssize_t id = TEST_PRNG(&prng) % (count+1);
|
||||||
// choose a weight
|
// choose a weight
|
||||||
lfs_size_t weight = 1 + (TEST_PRNG(&prng) % (W-1));
|
lfs_size_t weight = 1 + (TEST_PRNG(&prng) % W);
|
||||||
|
|
||||||
// calculate actual id in rbyd space
|
// calculate actual id in rbyd space
|
||||||
lfs_ssize_t id__ = 0;
|
lfs_ssize_t weighted_id = 0;
|
||||||
for (lfs_ssize_t j = 0; j < id; j++) {
|
for (lfs_ssize_t j = 0; j < id; j++) {
|
||||||
id__ += sim_weights[j];
|
weighted_id += sim_weights[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == (lfs_ssize_t)count || op == 0) {
|
if (id == (lfs_ssize_t)count || op == 0) {
|
||||||
@@ -11747,8 +11747,9 @@ code = '''
|
|||||||
count += 1;
|
count += 1;
|
||||||
// update our rbyd
|
// update our rbyd
|
||||||
lfsr_rbyd_commit(&lfs, &rbyd,
|
lfsr_rbyd_commit(&lfs, &rbyd,
|
||||||
LFSR_ATTR(GROW, id__, NULL, weight,
|
LFSR_ATTR(GROW, weighted_id, NULL, weight,
|
||||||
LFSR_ATTR(MKREG, id__+weight-1, &alpha[i % 26], 1,
|
LFSR_ATTR(MKREG, weighted_id+weight-1,
|
||||||
|
&alpha[i % 26], 1,
|
||||||
NULL))) => 0;
|
NULL))) => 0;
|
||||||
} else if (op == 1) {
|
} else if (op == 1) {
|
||||||
// get the correct weight from the sim
|
// get the correct weight from the sim
|
||||||
@@ -11760,14 +11761,14 @@ code = '''
|
|||||||
count -= 1;
|
count -= 1;
|
||||||
// update our rbyd
|
// update our rbyd
|
||||||
lfsr_rbyd_commit(&lfs, &rbyd,
|
lfsr_rbyd_commit(&lfs, &rbyd,
|
||||||
LFSR_ATTR(SHRINK, id__, NULL, weight,
|
LFSR_ATTR(SHRINK, weighted_id, NULL, weight,
|
||||||
NULL)) => 0;
|
NULL)) => 0;
|
||||||
} else if (op == 2) {
|
} else if (op == 2) {
|
||||||
// update our sim
|
// update our sim
|
||||||
sim_weights[id] += weight;
|
sim_weights[id] += weight;
|
||||||
// update our rbyd
|
// update our rbyd
|
||||||
lfsr_rbyd_commit(&lfs, &rbyd,
|
lfsr_rbyd_commit(&lfs, &rbyd,
|
||||||
LFSR_ATTR(GROW, id__, NULL, weight,
|
LFSR_ATTR(GROW, weighted_id, NULL, weight,
|
||||||
NULL)) => 0;
|
NULL)) => 0;
|
||||||
} else if (op == 3) {
|
} else if (op == 3) {
|
||||||
// don't let shrink go to zero here! this is already hard enough
|
// don't let shrink go to zero here! this is already hard enough
|
||||||
@@ -11777,7 +11778,7 @@ code = '''
|
|||||||
sim_weights[id] -= weight;
|
sim_weights[id] -= weight;
|
||||||
// update our rbyd
|
// update our rbyd
|
||||||
lfsr_rbyd_commit(&lfs, &rbyd,
|
lfsr_rbyd_commit(&lfs, &rbyd,
|
||||||
LFSR_ATTR(SHRINK, id__, NULL, weight,
|
LFSR_ATTR(SHRINK, weighted_id, NULL, weight,
|
||||||
NULL)) => 0;
|
NULL)) => 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11794,13 +11795,13 @@ code = '''
|
|||||||
printf("rbyd: [");
|
printf("rbyd: [");
|
||||||
for (lfs_ssize_t id = 0; id < (lfs_ssize_t)count; id++) {
|
for (lfs_ssize_t id = 0; id < (lfs_ssize_t)count; id++) {
|
||||||
// calculate actual id in rbyd space
|
// calculate actual id in rbyd space
|
||||||
lfs_ssize_t id__ = 0;
|
lfs_ssize_t weighted_id = 0;
|
||||||
for (lfs_ssize_t j = 0; j < id; j++) {
|
for (lfs_ssize_t j = 0; j < id; j++) {
|
||||||
id__ += sim_weights[j];
|
weighted_id += sim_weights[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
int err = lfsr_rbyd_lookup(&lfs, &rbyd,
|
int err = lfsr_rbyd_lookup(&lfs, &rbyd,
|
||||||
LFSR_TAG_MKREG, id__,
|
LFSR_TAG_MKREG, weighted_id,
|
||||||
&tag_, &id_, &weight_, &off_, &size_);
|
&tag_, &id_, &weight_, &off_, &size_);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
lfs_ssize_t size = lfsr_rbyd_get(&lfs, &rbyd,
|
lfs_ssize_t size = lfsr_rbyd_get(&lfs, &rbyd,
|
||||||
@@ -11828,13 +11829,13 @@ code = '''
|
|||||||
|
|
||||||
for (lfs_ssize_t id = 0; id < (lfs_ssize_t)count; id++) {
|
for (lfs_ssize_t id = 0; id < (lfs_ssize_t)count; id++) {
|
||||||
// calculate actual id in rbyd space
|
// calculate actual id in rbyd space
|
||||||
lfs_ssize_t id__ = 0;
|
lfs_ssize_t weighted_id = 0;
|
||||||
for (lfs_ssize_t j = 0; j < id; j++) {
|
for (lfs_ssize_t j = 0; j < id; j++) {
|
||||||
id__ += sim_weights[j];
|
weighted_id += sim_weights[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_rbyd_lookup(&lfs, &rbyd,
|
lfsr_rbyd_lookup(&lfs, &rbyd,
|
||||||
LFSR_TAG_MKREG, id__,
|
LFSR_TAG_MKREG, weighted_id,
|
||||||
&tag_, &id_, &weight_, &off_, &size_) => 0;
|
&tag_, &id_, &weight_, &off_, &size_) => 0;
|
||||||
lfsr_rbyd_get(&lfs, &rbyd, tag_, id_, buffer, 4) => 1;
|
lfsr_rbyd_get(&lfs, &rbyd, tag_, id_, buffer, 4) => 1;
|
||||||
assert(memcmp(&sim[id], buffer, 1) == 0);
|
assert(memcmp(&sim[id], buffer, 1) == 0);
|
||||||
@@ -11908,9 +11909,9 @@ code = '''
|
|||||||
lfs_size_t weight = 1 + (TEST_PRNG(&prng) % (W-1));
|
lfs_size_t weight = 1 + (TEST_PRNG(&prng) % (W-1));
|
||||||
|
|
||||||
// calculate actual id in rbyd space
|
// calculate actual id in rbyd space
|
||||||
lfs_ssize_t id__ = 0;
|
lfs_ssize_t weighted_id = 0;
|
||||||
for (lfs_ssize_t j = 0; j < id; j++) {
|
for (lfs_ssize_t j = 0; j < id; j++) {
|
||||||
id__ += sim_weights[j];
|
weighted_id += sim_weights[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == (lfs_ssize_t)count || op == 0) {
|
if (id == (lfs_ssize_t)count || op == 0) {
|
||||||
@@ -11923,8 +11924,8 @@ code = '''
|
|||||||
count += 1;
|
count += 1;
|
||||||
// update our rbyd
|
// update our rbyd
|
||||||
lfsr_rbyd_commit(&lfs, &rbyd,
|
lfsr_rbyd_commit(&lfs, &rbyd,
|
||||||
LFSR_ATTR(GROW, id__, NULL, weight,
|
LFSR_ATTR(GROW, weighted_id, NULL, weight,
|
||||||
LFSR_ATTR(MKREG, id__+weight-1, &alpha[i % 26], 1,
|
LFSR_ATTR(MKREG, weighted_id+weight-1, &alpha[i % 26], 1,
|
||||||
NULL))) => 0;
|
NULL))) => 0;
|
||||||
} else if (op == 1) {
|
} else if (op == 1) {
|
||||||
// get the correct weight from the sim
|
// get the correct weight from the sim
|
||||||
@@ -11936,14 +11937,14 @@ code = '''
|
|||||||
count -= 1;
|
count -= 1;
|
||||||
// update our rbyd
|
// update our rbyd
|
||||||
lfsr_rbyd_commit(&lfs, &rbyd,
|
lfsr_rbyd_commit(&lfs, &rbyd,
|
||||||
LFSR_ATTR(SHRINK, id__, NULL, weight,
|
LFSR_ATTR(SHRINK, weighted_id, NULL, weight,
|
||||||
NULL)) => 0;
|
NULL)) => 0;
|
||||||
} else if (op == 2) {
|
} else if (op == 2) {
|
||||||
// update our sim
|
// update our sim
|
||||||
sim_weights[id] += weight;
|
sim_weights[id] += weight;
|
||||||
// update our rbyd
|
// update our rbyd
|
||||||
lfsr_rbyd_commit(&lfs, &rbyd,
|
lfsr_rbyd_commit(&lfs, &rbyd,
|
||||||
LFSR_ATTR(GROW, id__, NULL, weight,
|
LFSR_ATTR(GROW, weighted_id, NULL, weight,
|
||||||
NULL)) => 0;
|
NULL)) => 0;
|
||||||
} else if (op == 3) {
|
} else if (op == 3) {
|
||||||
// don't let shrink go to zero here! this is already hard enough
|
// don't let shrink go to zero here! this is already hard enough
|
||||||
@@ -11953,7 +11954,7 @@ code = '''
|
|||||||
sim_weights[id] -= weight;
|
sim_weights[id] -= weight;
|
||||||
// update our rbyd
|
// update our rbyd
|
||||||
lfsr_rbyd_commit(&lfs, &rbyd,
|
lfsr_rbyd_commit(&lfs, &rbyd,
|
||||||
LFSR_ATTR(SHRINK, id__, NULL, weight,
|
LFSR_ATTR(SHRINK, weighted_id, NULL, weight,
|
||||||
NULL)) => 0;
|
NULL)) => 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13074,7 +13075,7 @@ code = '''
|
|||||||
// choose an id
|
// choose an id
|
||||||
lfs_ssize_t id = TEST_PRNG(&prng) % (count+1);
|
lfs_ssize_t id = TEST_PRNG(&prng) % (count+1);
|
||||||
// choose a weight
|
// choose a weight
|
||||||
lfs_size_t weight = 1 + (TEST_PRNG(&prng) % (W-1));
|
lfs_size_t weight = 1 + (TEST_PRNG(&prng) % W);
|
||||||
|
|
||||||
if (id == (lfs_ssize_t)count || op == 0) {
|
if (id == (lfs_ssize_t)count || op == 0) {
|
||||||
printf("c%dw%d=%c", id, weight, alpha[i % 26]);
|
printf("c%dw%d=%c", id, weight, alpha[i % 26]);
|
||||||
@@ -13116,12 +13117,12 @@ code = '''
|
|||||||
// choose an id
|
// choose an id
|
||||||
lfs_ssize_t id = TEST_PRNG(&prng) % (count+1);
|
lfs_ssize_t id = TEST_PRNG(&prng) % (count+1);
|
||||||
// choose a weight
|
// choose a weight
|
||||||
lfs_size_t weight = 1 + (TEST_PRNG(&prng) % (W-1));
|
lfs_size_t weight = 1 + (TEST_PRNG(&prng) % W);
|
||||||
|
|
||||||
// calculate actual id in rbyd space
|
// calculate actual id in rbyd space
|
||||||
lfs_ssize_t id__ = 0;
|
lfs_ssize_t weighted_id = 0;
|
||||||
for (lfs_ssize_t j = 0; j < id; j++) {
|
for (lfs_ssize_t j = 0; j < id; j++) {
|
||||||
id__ += sim_weights[j];
|
weighted_id += sim_weights[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == (lfs_ssize_t)count || op == 0) {
|
if (id == (lfs_ssize_t)count || op == 0) {
|
||||||
@@ -13135,8 +13136,8 @@ code = '''
|
|||||||
// update our rbyd
|
// update our rbyd
|
||||||
if (i < w) {
|
if (i < w) {
|
||||||
lfsr_rbyd_commit(&lfs, &rbyd,
|
lfsr_rbyd_commit(&lfs, &rbyd,
|
||||||
LFSR_ATTR(GROW, id__, NULL, weight,
|
LFSR_ATTR(GROW, weighted_id, NULL, weight,
|
||||||
LFSR_ATTR(MKREG, id__+weight-1,
|
LFSR_ATTR(MKREG, weighted_id+weight-1,
|
||||||
&alpha[i % 26], 1,
|
&alpha[i % 26], 1,
|
||||||
NULL))) => 0;
|
NULL))) => 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -13144,10 +13145,10 @@ code = '''
|
|||||||
attrs[a-1].next = &attrs[a];
|
attrs[a-1].next = &attrs[a];
|
||||||
}
|
}
|
||||||
attrs[a] = *LFSR_ATTR(
|
attrs[a] = *LFSR_ATTR(
|
||||||
GROW, id__, NULL, weight,
|
GROW, weighted_id, NULL, weight,
|
||||||
&attrs[a+1]);
|
&attrs[a+1]);
|
||||||
attrs[a+1] = *LFSR_ATTR(
|
attrs[a+1] = *LFSR_ATTR(
|
||||||
MKREG, id__+weight-1, &alpha[i % 26], 1,
|
MKREG, weighted_id+weight-1, &alpha[i % 26], 1,
|
||||||
NULL);
|
NULL);
|
||||||
a += 2;
|
a += 2;
|
||||||
}
|
}
|
||||||
@@ -13162,14 +13163,14 @@ code = '''
|
|||||||
// update our rbyd
|
// update our rbyd
|
||||||
if (i < w) {
|
if (i < w) {
|
||||||
lfsr_rbyd_commit(&lfs, &rbyd,
|
lfsr_rbyd_commit(&lfs, &rbyd,
|
||||||
LFSR_ATTR(SHRINK, id__, NULL, weight,
|
LFSR_ATTR(SHRINK, weighted_id, NULL, weight,
|
||||||
NULL)) => 0;
|
NULL)) => 0;
|
||||||
} else {
|
} else {
|
||||||
if (a > 0) {
|
if (a > 0) {
|
||||||
attrs[a-1].next = &attrs[a];
|
attrs[a-1].next = &attrs[a];
|
||||||
}
|
}
|
||||||
attrs[a] = *LFSR_ATTR(
|
attrs[a] = *LFSR_ATTR(
|
||||||
SHRINK, id__, NULL, weight,
|
SHRINK, weighted_id, NULL, weight,
|
||||||
NULL);
|
NULL);
|
||||||
a += 1;
|
a += 1;
|
||||||
}
|
}
|
||||||
@@ -13179,14 +13180,14 @@ code = '''
|
|||||||
// update our rbyd
|
// update our rbyd
|
||||||
if (i < w) {
|
if (i < w) {
|
||||||
lfsr_rbyd_commit(&lfs, &rbyd,
|
lfsr_rbyd_commit(&lfs, &rbyd,
|
||||||
LFSR_ATTR(GROW, id__, NULL, weight,
|
LFSR_ATTR(GROW, weighted_id, NULL, weight,
|
||||||
NULL)) => 0;
|
NULL)) => 0;
|
||||||
} else {
|
} else {
|
||||||
if (a > 0) {
|
if (a > 0) {
|
||||||
attrs[a-1].next = &attrs[a];
|
attrs[a-1].next = &attrs[a];
|
||||||
}
|
}
|
||||||
attrs[a] = *LFSR_ATTR(
|
attrs[a] = *LFSR_ATTR(
|
||||||
GROW, id__, NULL, weight,
|
GROW, weighted_id, NULL, weight,
|
||||||
NULL);
|
NULL);
|
||||||
a += 1;
|
a += 1;
|
||||||
}
|
}
|
||||||
@@ -13199,14 +13200,14 @@ code = '''
|
|||||||
// update our rbyd
|
// update our rbyd
|
||||||
if (i < w) {
|
if (i < w) {
|
||||||
lfsr_rbyd_commit(&lfs, &rbyd,
|
lfsr_rbyd_commit(&lfs, &rbyd,
|
||||||
LFSR_ATTR(SHRINK, id__, NULL, weight,
|
LFSR_ATTR(SHRINK, weighted_id, NULL, weight,
|
||||||
NULL)) => 0;
|
NULL)) => 0;
|
||||||
} else {
|
} else {
|
||||||
if (a > 0) {
|
if (a > 0) {
|
||||||
attrs[a-1].next = &attrs[a];
|
attrs[a-1].next = &attrs[a];
|
||||||
}
|
}
|
||||||
attrs[a] = *LFSR_ATTR(
|
attrs[a] = *LFSR_ATTR(
|
||||||
SHRINK, id__, NULL, weight,
|
SHRINK, weighted_id, NULL, weight,
|
||||||
NULL);
|
NULL);
|
||||||
a += 1;
|
a += 1;
|
||||||
}
|
}
|
||||||
@@ -13227,14 +13228,14 @@ code = '''
|
|||||||
printf("rbyd: [");
|
printf("rbyd: [");
|
||||||
for (lfs_ssize_t id = 0; id < (lfs_ssize_t)count; id++) {
|
for (lfs_ssize_t id = 0; id < (lfs_ssize_t)count; id++) {
|
||||||
// calculate actual id in rbyd space
|
// calculate actual id in rbyd space
|
||||||
lfs_ssize_t id__ = 0;
|
lfs_ssize_t weighted_id = 0;
|
||||||
for (lfs_ssize_t j = 0; j < id; j++) {
|
for (lfs_ssize_t j = 0; j < id; j++) {
|
||||||
id__ += sim_weights[j];
|
weighted_id += sim_weights[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
int err = lfsr_rbyd_predictedlookup(
|
int err = lfsr_rbyd_predictedlookup(
|
||||||
&lfs, &rbyd, unwritten,
|
&lfs, &rbyd, unwritten,
|
||||||
LFSR_TAG_MKREG, id__,
|
LFSR_TAG_MKREG, weighted_id,
|
||||||
&tag_, &id_, &data_);
|
&tag_, &id_, &data_);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
lfs_ssize_t size = lfsr_rbyd_predictedget(
|
lfs_ssize_t size = lfsr_rbyd_predictedget(
|
||||||
@@ -13256,13 +13257,13 @@ code = '''
|
|||||||
|
|
||||||
for (lfs_ssize_t id = 0; id < (lfs_ssize_t)count; id++) {
|
for (lfs_ssize_t id = 0; id < (lfs_ssize_t)count; id++) {
|
||||||
// calculate actual id in rbyd space
|
// calculate actual id in rbyd space
|
||||||
lfs_ssize_t id__ = 0;
|
lfs_ssize_t weighted_id = 0;
|
||||||
for (lfs_ssize_t j = 0; j < id; j++) {
|
for (lfs_ssize_t j = 0; j < id; j++) {
|
||||||
id__ += sim_weights[j];
|
weighted_id += sim_weights[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
lfsr_rbyd_predictedlookup(&lfs, &rbyd, unwritten,
|
lfsr_rbyd_predictedlookup(&lfs, &rbyd, unwritten,
|
||||||
LFSR_TAG_MKREG, id__,
|
LFSR_TAG_MKREG, weighted_id,
|
||||||
&tag_, &id_, &data_) => 0;
|
&tag_, &id_, &data_) => 0;
|
||||||
lfsr_rbyd_predictedget(&lfs, &rbyd, unwritten,
|
lfsr_rbyd_predictedget(&lfs, &rbyd, unwritten,
|
||||||
tag_, id_, buffer, 4) => 1;
|
tag_, id_, buffer, 4) => 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user