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: Kent Overstreet <koverstreet@google.com>
This commit is contained in:
Родитель
85b1492ee1
Коммит
6ded34d1a5
|
@ -828,6 +828,7 @@ struct cache_set {
|
||||||
*/
|
*/
|
||||||
struct mutex sort_lock;
|
struct mutex sort_lock;
|
||||||
struct bset *sort;
|
struct bset *sort;
|
||||||
|
unsigned sort_crit_factor;
|
||||||
|
|
||||||
/* List of buckets we're currently writing data to */
|
/* List of buckets we're currently writing data to */
|
||||||
struct list_head data_buckets;
|
struct list_head data_buckets;
|
||||||
|
|
|
@ -1092,33 +1092,39 @@ void bch_btree_sort_into(struct btree *b, struct btree *new)
|
||||||
new->sets->size = 0;
|
new->sets->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SORT_CRIT (4096 / sizeof(uint64_t))
|
||||||
|
|
||||||
void bch_btree_sort_lazy(struct btree *b)
|
void bch_btree_sort_lazy(struct btree *b)
|
||||||
{
|
{
|
||||||
if (b->nsets) {
|
unsigned crit = SORT_CRIT;
|
||||||
unsigned i, j, keys = 0, total;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i <= b->nsets; i++)
|
/* Don't sort if nothing to do */
|
||||||
keys += b->sets[i].data->keys;
|
if (!b->nsets)
|
||||||
|
goto out;
|
||||||
|
|
||||||
total = keys;
|
/* If not a leaf node, always sort */
|
||||||
|
if (b->level) {
|
||||||
for (j = 0; j < b->nsets; j++) {
|
|
||||||
if (keys * 2 < total ||
|
|
||||||
keys < 1000) {
|
|
||||||
bch_btree_sort_partial(b, j);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
keys -= b->sets[j].data->keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Must sort if b->nsets == 3 or we'll overflow */
|
|
||||||
if (b->nsets >= (MAX_BSETS - 1) - b->level) {
|
|
||||||
bch_btree_sort(b);
|
bch_btree_sort(b);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sort if we'd overflow */
|
||||||
|
if (b->nsets + 1 == MAX_BSETS) {
|
||||||
|
bch_btree_sort(b);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
bset_build_written_tree(b);
|
bset_build_written_tree(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
c->btree_pages = max_t(int, c->btree_pages / 4,
|
||||||
BTREE_MAX_PAGES);
|
BTREE_MAX_PAGES);
|
||||||
|
|
||||||
|
c->sort_crit_factor = int_sqrt(c->btree_pages);
|
||||||
|
|
||||||
mutex_init(&c->bucket_lock);
|
mutex_init(&c->bucket_lock);
|
||||||
mutex_init(&c->sort_lock);
|
mutex_init(&c->sort_lock);
|
||||||
spin_lock_init(&c->sort_time_lock);
|
spin_lock_init(&c->sort_time_lock);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче