Compare commits

...

1 Commits

Author SHA1 Message Date
Zach Brown
af893e8888 Drop totl items that merge to zero
As totl items are merged they're supposed to be dropped if both their
count and total are zero.  It's a slight mechanical simplification
because it means deletions can emit the same delta items as non-deletion
changes.

The btree code that does this has a day-one bug where it clobbers the
return value of the delta combination before checking it.  The resulting
items are still correct but they don't need to exist.  Readers ignore
them.

The easy fix doesn't clobber the delta combination result in the merge
loop so the zero items won't be written by the merge.  Since these were
ignored by readers there won't be a user-facing change.  We'll do less
work in the future as zero items aren't written and the next merge will
drop all the existing items that were left behind by previous merges.

Signed-off-by: Zach Brown <zab@versity.com>
2023-06-16 13:52:52 -07:00

View File

@@ -2179,15 +2179,18 @@ static int next_resolved_mpos(struct super_block *sb, struct rb_root *pos_root,
struct merge_pos *mpos;
struct merge_pos *next;
struct scoutfs_key key;
int delta;
int ret = 0;
while ((mpos = first_mpos(pos_root)) && (next = next_mpos(mpos)) &&
!scoutfs_key_compare(mpos->key, next->key)) {
ret = scoutfs_forest_combine_deltas(mpos->key, mpos->val, mpos->val_len,
next->val, next->val_len);
if (ret < 0)
delta = scoutfs_forest_combine_deltas(mpos->key, mpos->val, mpos->val_len,
next->val, next->val_len);
if (delta < 0) {
ret = delta;
break;
}
/* reset advances to the next item */
key = *mpos->key;
@@ -2198,9 +2201,9 @@ static int next_resolved_mpos(struct super_block *sb, struct rb_root *pos_root,
if (ret < 0)
break;
if (ret == SCOUTFS_DELTA_COMBINED) {
if (delta == SCOUTFS_DELTA_COMBINED) {
scoutfs_inc_counter(sb, btree_merge_delta_combined);
} else if (ret == SCOUTFS_DELTA_COMBINED_NULL) {
} else if (delta == SCOUTFS_DELTA_COMBINED_NULL) {
scoutfs_inc_counter(sb, btree_merge_delta_null);
/* if merging resulted in no info, skip current */
ret = reset_mpos(sb, pos_root, mpos, &key, end);