Eagerly discard attr-list in lfsr_mdir_commit__
This is an interesting optimization made possible by our attr-lists now
only operating on one mid. We can now discard the entire attr-list based
on if that mid is in the commit's filter range.
Unfortunately, while I had hoped this would lead to more
simplifications, we can't really push this up through many functions:
- While this eager discard works for splits, lfsr_btree_commit can also
merge, which affects two separate bids. The attrs on these bids need
to be split over the new btree inner-nodes, so we end up still needing
filtering in lfsr_rbyd_appendattrs.
We could move the filtering up into lfsr_btree_commit, but would that
really gain anything?
- lfsr_mdir_commit_ needs the filter range because we leverage this in
higher-layers to for lfsr_mdir_commit_ to omit non--1 attrs when
committing to newly hollow mroots.
In theory it might still be possible to push this up into
lfsr_mdir_commit, but we would still need to unconditionally commit
during mdir splits to append the cksum. This ends up with duplicate
function calls which ends up annoyingly expensive. Though maybe there
is a conditional count trick that could avoid this?
At least the code changes are ok:
code stack
before: 33884 2896
after: 33808 (-0.2%) 2896 (+0.0%)
This commit is contained in:
@@ -5498,16 +5498,18 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
lfsr_smid_t mid, const lfsr_attr_t *attrs, lfs_size_t attr_count) {
|
lfsr_smid_t mid, const lfsr_attr_t *attrs, lfs_size_t attr_count) {
|
||||||
// try to append a commit
|
// try to append a commit
|
||||||
lfsr_rbyd_t rbyd_ = mdir->rbyd;
|
lfsr_rbyd_t rbyd_ = mdir->rbyd;
|
||||||
lfsr_srid_t rid = lfsr_mid_rid(lfs, mid);
|
|
||||||
// mark as erased in case of failure
|
// mark as erased in case of failure
|
||||||
mdir->rbyd.eoff = -1;
|
mdir->rbyd.eoff = -1;
|
||||||
for (lfs_size_t i = 0; i < attr_count; i++) {
|
|
||||||
// don't write tags outside of the requested range
|
// since we only ever commit to one mid or split, we can ignore the
|
||||||
if (rid >= start_rid
|
// entire attr-list if our mid is out of range
|
||||||
// note the use of rid+1 and unsigned comparison here to
|
lfsr_srid_t rid = lfsr_mid_rid(lfs, mid);
|
||||||
// treat end_rid=-1 as "unbounded" in such a way that rid=-1
|
if (rid >= start_rid
|
||||||
// is still included
|
// note the use of rid+1 and unsigned comparison here to
|
||||||
&& (lfs_size_t)(rid + 1) <= (lfs_size_t)end_rid) {
|
// treat end_rid=-1 as "unbounded" in such a way that rid=-1
|
||||||
|
// is still included
|
||||||
|
&& (lfs_size_t)(rid + 1) <= (lfs_size_t)end_rid) {
|
||||||
|
for (lfs_size_t i = 0; i < attr_count; i++) {
|
||||||
// adjust for inserts
|
// adjust for inserts
|
||||||
if (!lfsr_tag_isgrow(attrs[i].tag) && attrs[i].delta > 0) {
|
if (!lfsr_tag_isgrow(attrs[i].tag) && attrs[i].delta > 0) {
|
||||||
rid -= 1;
|
rid -= 1;
|
||||||
@@ -5703,26 +5705,8 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust for inserts
|
// adjust rid
|
||||||
if (!lfsr_tag_isgrow(attrs[i].tag) && attrs[i].delta > 0) {
|
rid += attrs[i].delta;
|
||||||
rid += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need to make sure we keep start_rid/end_rid updated with
|
|
||||||
// weight changes
|
|
||||||
if (rid < start_rid) {
|
|
||||||
start_rid += attrs[i].delta;
|
|
||||||
}
|
|
||||||
if (rid < end_rid) {
|
|
||||||
end_rid += attrs[i].delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
// adjust rid
|
|
||||||
rid += attrs[i].delta;
|
|
||||||
// adjust for inserts
|
|
||||||
if (!lfsr_tag_isgrow(attrs[i].tag) && attrs[i].delta > 0) {
|
|
||||||
rid -= 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user