Changed becksum lookup to not re-traverse the whole btree

We already get the leaf rbyd as a part of btree lookup, and since ids
can't be split across rbyd boundaries, we can be sure any bptr attrs
live in the same rbyd.

This can be extended to any future bptr attrs.

Aside from the small performance gain, this also means we can drop the
btree bid+tag lookups. All extra attr lookups to lookup the rbyd first.
This saves a bit of code but also avoids a set of issues with the btree
semantics where lookupnexting an extra attr can return ENOENT
prematurely when on an rbyd boundary.

As I'm typing this I realize this means we have no way to iterate over
all _tags_ in a btree, only over all _bids_. Fortunately I don't think
we will ever need the former.

            code          stack
  before:  32136           2880
  after:   31956 (-0.6%)   2880 (+0.0%)
This commit is contained in:
Christopher Haster
2023-12-14 11:55:23 -06:00
parent 34b1e3ef00
commit 3e45fc739d
2 changed files with 52 additions and 71 deletions
+31 -50
View File
@@ -3863,59 +3863,29 @@ static int lfsr_btree_lookupnext_(lfs_t *lfs, const lfsr_btree_t *btree,
}
static int lfsr_btree_lookupnext(lfs_t *lfs, const lfsr_btree_t *btree,
lfsr_bid_t bid, lfsr_tag_t tag,
lfsr_bid_t bid,
lfsr_bid_t *bid_, lfsr_tag_t *tag_, lfsr_bid_t *weight_,
lfsr_data_t *data_) {
lfsr_rbyd_t rbyd;
lfsr_srid_t rid;
lfsr_tag_t tag__;
int err = lfsr_btree_lookupnext_(lfs, btree, bid,
bid_, &rbyd, &rid, &tag__, weight_, data_);
if (err) {
return err;
}
// we need to do a bit of extra work if requested tag is not struct
if (lfsr_tag_key(tag__) != LFSR_TAG_STRUCT) {
err = lfsr_rbyd_lookupnext(lfs, &rbyd, rid, tag,
NULL, &tag__, weight_, data_);
if (err) {
return err;
}
}
if (tag_) {
*tag_ = tag__;
}
return 0;
return lfsr_btree_lookupnext_(lfs, btree, bid,
bid_, NULL, NULL, tag_, weight_, data_);
}
static int lfsr_btree_lookup(lfs_t *lfs, const lfsr_btree_t *btree,
lfsr_bid_t bid, lfsr_tag_t tag,
lfsr_bid_t bid,
lfsr_tag_t *tag_, lfsr_bid_t *weight_, lfsr_data_t *data_) {
lfsr_bid_t bid_;
lfsr_tag_t tag__;
int err = lfsr_btree_lookupnext(lfs, btree, bid, tag,
&bid_, &tag__, weight_, data_);
int err = lfsr_btree_lookupnext(lfs, btree, bid,
&bid_, tag_, weight_, data_);
if (err) {
return err;
}
// lookup finds the next-smallest tag, all we need to do is fail if it
// picks up the wrong tag
//
// we accept either exact matches or suptype matches depending on the
// wide bit
if (bid_ != bid
|| (lfsr_tag_iswide(tag)
? lfsr_tag_suptype(tag__) != (tag & ~LFSR_TAG_WIDE)
: tag__ != tag)) {
// lookup finds the next-smallest bid, all we need to do is fail if it
// picks up the wrong bid
if (bid_ != bid) {
return LFS_ERR_NOENT;
}
if (tag_) {
*tag_ = tag__;
}
return 0;
}
@@ -4791,22 +4761,32 @@ static int lfsr_bshrub_fetch(lfs_t *lfs,
return 0;
}
static int lfsr_bshrub_lookupnext_(lfs_t *lfs,
const lfsr_mdir_t *mdir, const lfsr_bshrub_t *bshrub,
lfsr_bid_t bid,
lfsr_bid_t *bid_, lfsr_rbyd_t *rbyd_, lfsr_srid_t *rid_,
lfsr_tag_t *tag_, lfsr_bid_t *weight_, lfsr_data_t *data_) {
(void)mdir;
return lfsr_btree_lookupnext_(lfs, &bshrub->rbyd, bid,
bid_, rbyd_, rid_, tag_, weight_, data_);
}
static int lfsr_bshrub_lookupnext(lfs_t *lfs,
const lfsr_mdir_t *mdir, const lfsr_bshrub_t *bshrub,
lfsr_bid_t bid, lfsr_tag_t tag,
lfsr_bid_t bid,
lfsr_bid_t *bid_, lfsr_tag_t *tag_, lfsr_bid_t *weight_,
lfsr_data_t *data_) {
(void)mdir;
return lfsr_btree_lookupnext(lfs, &bshrub->rbyd, bid, tag,
return lfsr_btree_lookupnext(lfs, &bshrub->rbyd, bid,
bid_, tag_, weight_, data_);
}
static int lfsr_bshrub_lookup(lfs_t *lfs,
const lfsr_mdir_t *mdir, const lfsr_bshrub_t *bshrub,
lfsr_bid_t bid, lfsr_tag_t tag,
lfsr_bid_t bid,
lfsr_tag_t *tag_, lfsr_bid_t *weight_, lfsr_data_t *data_) {
(void)mdir;
return lfsr_btree_lookup(lfs, &bshrub->rbyd, bid, tag,
return lfsr_btree_lookup(lfs, &bshrub->rbyd, bid,
tag_, weight_, data_);
}
@@ -5495,7 +5475,7 @@ static int lfsr_mtree_lookup(lfs_t *lfs, lfsr_smid_t mid,
lfsr_tag_t tag;
lfsr_data_t data;
int err = lfsr_btree_lookupnext(lfs, &lfs->mtree.u.btree,
mid, LFSR_TAG_STRUCT,
mid,
&bid, &tag, NULL, &data);
if (err) {
return err;
@@ -9360,12 +9340,14 @@ static int lfsr_ftree_lookupnext(lfs_t *lfs,
// bshrub/btree?
} else {
lfsr_bid_t bid;
lfsr_rbyd_t rbyd;
lfsr_srid_t rid;
lfsr_tag_t tag;
lfsr_bid_t weight;
lfsr_data_t data;
int err = lfsr_bshrub_lookupnext(lfs, mdir, &ftree->u.bshrub,
pos, LFSR_TAG_STRUCT,
&bid, &tag, &weight, &data);
int err = lfsr_bshrub_lookupnext_(lfs, mdir, &ftree->u.bshrub,
pos,
&bid, &rbyd, &rid, &tag, &weight, &data);
if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT);
return err;
@@ -9396,9 +9378,8 @@ static int lfsr_ftree_lookupnext(lfs_t *lfs,
}
if (becksum_) {
// need an extra lookup to find becksums
err = lfsr_bshrub_lookup(lfs, mdir, &ftree->u.bshrub,
bid, LFSR_TAG_BECKSUM,
NULL, NULL, &data);
err = lfsr_rbyd_lookup(lfs, &rbyd, rid, LFSR_TAG_BECKSUM,
NULL, &data);
if (err && err != LFS_ERR_NOENT) {
return err;
}
+21 -21
View File
@@ -15,7 +15,7 @@ code = '''
lfsr_tag_t *tag_, lfs_size_t *weight_,
void *buffer, lfs_size_t size) {
lfsr_data_t data;
int err = lfsr_btree_lookup(lfs, btree, bid, LFSR_TAG_STRUCT,
int err = lfsr_btree_lookup(lfs, btree, bid,
tag_, weight_, &data);
if (err) {
return err;
@@ -40,7 +40,7 @@ code = '''
// lookup weight to compute deltas
lfs_size_t weight_;
int err = lfsr_btree_lookupnext(lfs, btree, bid, LFSR_TAG_STRUCT,
int err = lfsr_btree_lookupnext(lfs, btree, bid,
NULL, NULL, &weight_, NULL);
if (err) {
return err;
@@ -60,7 +60,7 @@ code = '''
// lookup weight to compute deltas
lfs_size_t weight_;
int err = lfsr_btree_lookupnext(lfs, btree, bid, LFSR_TAG_STRUCT,
int err = lfsr_btree_lookupnext(lfs, btree, bid,
NULL, NULL, &weight_, NULL);
if (err) {
return err;
@@ -79,7 +79,7 @@ code = '''
// lookup weight to compute deltas
lfs_size_t weight_;
int err = lfsr_btree_lookupnext(lfs, btree, bid, LFSR_TAG_STRUCT,
int err = lfsr_btree_lookupnext(lfs, btree, bid,
NULL, NULL, &weight_, NULL);
if (err) {
return err;
@@ -630,7 +630,7 @@ code = '''
lfs_size_t bid_ = -1;
lfsr_data_t data_;
for (lfs_size_t i = 0; i < n; i++) {
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => 0;
assert(bid_ == i*W+W-1);
assert(tag_ == LFSR_TAG_DATA);
@@ -639,7 +639,7 @@ code = '''
lfsr_data_read(&lfs, &data_, buffer, 4) => 1;
assert(memcmp(buffer, &alphas[i % 26], 1) == 0);
}
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => LFS_ERR_NOENT;
'''
@@ -767,7 +767,7 @@ code = '''
weighted_bid += sim_weights[j];
}
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => 0;
assert(bid_ == weighted_bid+sim_weights[i]-1);
assert(tag_ == LFSR_TAG_DATA);
@@ -776,7 +776,7 @@ code = '''
lfsr_data_read(&lfs, &data_, buffer, 4) => 1;
assert(memcmp(buffer, &sim[i], 1) == 0);
}
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => LFS_ERR_NOENT;
// clean up sim
@@ -1186,7 +1186,7 @@ code = '''
lfs_size_t bid_ = -1;
lfsr_data_t data_;
for (lfs_size_t i = 0; i < N; i++) {
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => 0;
assert(bid_ == i*W+W-1);
assert(tag_ == LFSR_TAG_DATA);
@@ -1195,7 +1195,7 @@ code = '''
lfsr_data_read(&lfs, &data_, buffer, 4) => 1;
assert(memcmp(buffer, &uppers[i % 26], 1) == 0);
}
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => LFS_ERR_NOENT;
'''
@@ -1334,7 +1334,7 @@ code = '''
weighted_bid += sim_weights[j];
}
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => 0;
assert(bid_ == weighted_bid+sim_weights[i]-1);
assert(tag_ == LFSR_TAG_DATA);
@@ -1343,7 +1343,7 @@ code = '''
lfsr_data_read(&lfs, &data_, buffer, 4) => 1;
assert(memcmp(buffer, &sim[i], 1) == 0);
}
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => LFS_ERR_NOENT;
// clean up sim
@@ -2005,7 +2005,7 @@ code = '''
lfs_size_t bid_ = -1;
lfsr_data_t data_;
for (lfs_size_t i = 0; i < REMAINING; i++) {
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => 0;
assert(bid_ == i*W+W-1);
assert(tag_ == LFSR_TAG_DATA);
@@ -2015,7 +2015,7 @@ code = '''
assert(memcmp(buffer, &alphas[i % 26], 1) == 0);
}
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => 0;
assert(bid_ == REMAINING*W+W-1);
assert(tag_ == LFSR_TAG_DATA);
@@ -2024,7 +2024,7 @@ code = '''
lfsr_data_read(&lfs, &data_, buffer, 4) => 1;
assert(memcmp(buffer, "R", 1) == 0);
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => LFS_ERR_NOENT;
'''
@@ -2176,7 +2176,7 @@ code = '''
weighted_bid += sim_weights[j];
}
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => 0;
assert(bid_ == weighted_bid+sim_weights[i]-1);
assert(tag_ == LFSR_TAG_DATA);
@@ -2185,7 +2185,7 @@ code = '''
lfsr_data_read(&lfs, &data_, buffer, 4) => 1;
assert(memcmp(buffer, &sim[i], 1) == 0);
}
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => LFS_ERR_NOENT;
// clean up sim
@@ -2558,7 +2558,7 @@ code = '''
weighted_bid += sim_weights[j];
}
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => 0;
assert(bid_ == weighted_bid+sim_weights[i]-1);
assert(tag_ == LFSR_TAG_DATA);
@@ -2567,7 +2567,7 @@ code = '''
lfsr_data_read(&lfs, &data_, buffer, 4) => 1;
assert(memcmp(buffer, &sim[i], 1) == 0);
}
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => LFS_ERR_NOENT;
// clean up sim
@@ -3114,7 +3114,7 @@ code = '''
weighted_bid += sim_weights[j];
}
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => 0;
assert(bid_ == weighted_bid+sim_weights[i]-1);
assert(tag_ == LFSR_TAG_DATA);
@@ -3123,7 +3123,7 @@ code = '''
lfsr_data_read(&lfs, &data_, buffer, 4) => 1;
assert(memcmp(buffer, &sim[i], 1) == 0);
}
lfsr_btree_lookupnext(&lfs, &btree, bid_+1, LFSR_TAG_STRUCT,
lfsr_btree_lookupnext(&lfs, &btree, bid_+1,
&bid_, &tag_, &weight_, &data_) => LFS_ERR_NOENT;
// clean up sim