diff --git a/benches/bench_mtree.toml b/benches/bench_mtree.toml index ab5f274f..2dd81b71 100644 --- a/benches/bench_mtree.toml +++ b/benches/bench_mtree.toml @@ -133,3 +133,69 @@ code = ''' lfsr_unmount(&lfs) => 0; ''' + +[cases.bench_mtree_traversal] +defines.N = [8, 16, 32, 64, 128, 256, 1024] +# 0 = in-order +# 1 = reversed-order +# 2 = random-order +defines.ORDER = [0, 1, 2] +defines.SEED = 42 +defines.VALIDATE = [false, true] +in = 'lfs.c' +code = ''' + uint32_t prng = SEED; + const char *alphas = "abcdefghijklmnopqrstuvwxyz"; + + lfs_t lfs; + lfsr_format(&lfs, cfg) => 0; + lfsr_mount(&lfs, cfg) => 0; + + // create an mtree with N entries + for (lfs_size_t i = 0; i < N; i++) { + // choose an mid + lfs_ssize_t mid + = lfsr_mtree_weight(&lfs) == 0 ? -1 + : (ORDER == 0) ? (lfs_ssize_t)(lfsr_mtree_weight(&lfs)-1) + : (ORDER == 1) ? 0 + : (lfs_ssize_t)(BENCH_PRNG(&prng) % lfsr_mtree_weight(&lfs)); + // fetch mdir + lfsr_mdir_t mdir; + lfsr_mtree_lookup(&lfs, mid, &mdir) => 0; + + // choose rid + lfs_ssize_t rid + = (ORDER == 0) ? lfsr_mdir_weight(&mdir) + : (ORDER == 1) ? 0 + : BENCH_PRNG(&prng) % (lfsr_mdir_weight(&mdir)+1); + + // create an entry + lfsr_mdir_commit(&lfs, &mdir, &rid, LFSR_ATTRS( + LFSR_ATTR(rid, MKINLINED, +1, &alphas[i % 26], 1))) => 0; + } + + // traverse the mtree + BENCH_START(); + lfsr_mtree_traversal_t traversal = LFSR_MTREE_TRAVERSAL_INIT( + VALIDATE ? LFSR_MTREE_TRAVERSAL_VALIDATE : 0); + + for (lfs_block_t i = 0;; i++) { + // a bit hacky, but this catches infinite loops + assert(i < 2*(1+N)); + + lfs_size_t mid_; + lfsr_tag_t tag_; + lfsr_data_t data_; + int err = lfsr_mtree_traversal_next(&lfs, &traversal, + &mid_, &tag_, &data_); + assert(!err || err == LFS_ERR_NOENT); + if (err == LFS_ERR_NOENT) { + break; + } + + assert(tag_ == LFSR_TAG_BTREE || tag_ == LFSR_TAG_MDIR); + } + BENCH_STOP(); + + lfsr_unmount(&lfs) => 0; +'''