bcache: Improve lazy sorting
authorKent Overstreet <koverstreet@google.com>
Sat, 11 May 2013 22:59:37 +0000 (15:59 -0700)
committerKent Overstreet <koverstreet@google.com>
Thu, 27 Jun 2013 00:09:16 +0000 (17:09 -0700)
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>
drivers/md/bcache/bcache.h
drivers/md/bcache/bset.c
drivers/md/bcache/super.c

index 59c15e09e4dde04c989e9750789e5212caa32747..6fa5a1e33c49228339d0291b06e5d70698f47376 100644 (file)
@@ -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;
index e9399ed7f688538cc0692b63c5a4201de1977466..a0f190ac17a4bdc6fef206769577f386269a4554 100644 (file)
@@ -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);
-                               return;
-                       }
+       /* 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;
 
-               /* Must sort if b->nsets == 3 or we'll overflow */
-               if (b->nsets >= (MAX_BSETS - 1) - b->level) {
-                       bch_btree_sort(b);
+               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);
 }
 
index f24c2e0cbb1c199755894817f05a2f29c07d42ac..3c8474161e8eaa46603af66aa49ce22c40a64382 100644 (file)
@@ -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);