Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ded34d1 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcache: Improve lazy sorting



The old lazy sorting code was kind of hacky - rewrite in a way that
mathematically makes more sense; the idea is that the size of the sets
of keys in a btree node should increase by a more or less fixed ratio
from smallest to biggest.

Signed-off-by: default avatarKent Overstreet <koverstreet@google.com>
parent 85b1492e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -828,6 +828,7 @@ struct cache_set {
	 */
	struct mutex		sort_lock;
	struct bset		*sort;
	unsigned		sort_crit_factor;

	/* List of buckets we're currently writing data to */
	struct list_head	data_buckets;
+23 −17
Original line number Diff line number Diff line
@@ -1092,33 +1092,39 @@ void bch_btree_sort_into(struct btree *b, struct btree *new)
	new->sets->size = 0;
}

#define SORT_CRIT	(4096 / sizeof(uint64_t))

void bch_btree_sort_lazy(struct btree *b)
{
	if (b->nsets) {
		unsigned i, j, keys = 0, total;

		for (i = 0; i <= b->nsets; i++)
			keys += b->sets[i].data->keys;
	unsigned crit = SORT_CRIT;
	int i;

		total = keys;
	/* Don't sort if nothing to do */
	if (!b->nsets)
		goto out;

		for (j = 0; j < b->nsets; j++) {
			if (keys * 2 < total ||
			    keys < 1000) {
				bch_btree_sort_partial(b, j);
	/* If not a leaf node, always sort */
	if (b->level) {
		bch_btree_sort(b);
		return;
	}

			keys -= b->sets[j].data->keys;
	for (i = b->nsets - 1; i >= 0; --i) {
		crit *= b->c->sort_crit_factor;

		if (b->sets[i].data->keys < crit) {
			bch_btree_sort_partial(b, i);
			return;
		}
	}

		/* Must sort if b->nsets == 3 or we'll overflow */
		if (b->nsets >= (MAX_BSETS - 1) - b->level) {
	/* Sort if we'd overflow */
	if (b->nsets + 1 == MAX_BSETS) {
		bch_btree_sort(b);
		return;
	}
	}

out:
	bset_build_written_tree(b);
}

+2 −0
Original line number Diff line number Diff line
@@ -1375,6 +1375,8 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb)
		c->btree_pages = max_t(int, c->btree_pages / 4,
				       BTREE_MAX_PAGES);

	c->sort_crit_factor = int_sqrt(c->btree_pages);

	mutex_init(&c->bucket_lock);
	mutex_init(&c->sort_lock);
	spin_lock_init(&c->sort_time_lock);