summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bcache/bset.c61
1 files changed, 44 insertions, 17 deletions
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c
index 7510e2e66d6f..fb559e3f2115 100644
--- a/drivers/md/bcache/bset.c
+++ b/drivers/md/bcache/bset.c
@@ -1252,6 +1252,17 @@ static inline bool btree_node_iter_cmp(struct btree_node_iter *iter,
__btree_node_offset_to_key(b, r.k));
}
+static void __bch_btree_node_iter_push(struct btree_node_iter *iter,
+ struct btree_keys *b,
+ const struct bkey_packed *k,
+ const struct bkey_packed *end)
+{
+ if (k != end)
+ iter->data[iter->used++] = (struct btree_node_iter_set) {
+ __btree_node_key_to_offset(b, k),
+ __btree_node_key_to_offset(b, end)
+ };
+}
void bch_btree_node_iter_push(struct btree_node_iter *iter,
struct btree_keys *b,
const struct bkey_packed *k,
@@ -1344,12 +1355,13 @@ void bch_btree_node_iter_init(struct btree_node_iter *iter,
__bch_btree_node_iter_init(iter, b);
for (t = b->set; t <= b->set + b->nsets; t++)
- bch_btree_node_iter_push(iter, b,
- bch_bset_search(b, t, search,
- packed_search,
- lossy_packed_search,
- strictly_greater),
- bset_bkey_last(t->data));
+ __bch_btree_node_iter_push(iter, b,
+ bch_bset_search(b, t, search,
+ packed_search,
+ lossy_packed_search,
+ strictly_greater),
+ bset_bkey_last(t->data));
+ bch_btree_node_iter_sort(iter, b);
}
EXPORT_SYMBOL(bch_btree_node_iter_init);
@@ -1361,9 +1373,10 @@ void bch_btree_node_iter_init_from_start(struct btree_node_iter *iter,
__bch_btree_node_iter_init(iter, b);
for (t = b->set; t <= b->set + b->nsets; t++)
- bch_btree_node_iter_push(iter, b,
- t->data->start,
- bset_bkey_last(t->data));
+ __bch_btree_node_iter_push(iter, b,
+ t->data->start,
+ bset_bkey_last(t->data));
+ bch_btree_node_iter_sort(iter, b);
}
EXPORT_SYMBOL(bch_btree_node_iter_init_from_start);
@@ -1389,7 +1402,7 @@ static inline void btree_node_iter_sift(struct btree_node_iter *iter,
{
unsigned i;
- BUG_ON(iter->used > MAX_BSETS);
+ EBUG_ON(iter->used > MAX_BSETS);
for (i = start;
i + 1 < iter->used &&
@@ -1398,15 +1411,28 @@ static inline void btree_node_iter_sift(struct btree_node_iter *iter,
swap(iter->data[i], iter->data[i + 1]);
}
+static inline void btree_node_iter_sort_two(struct btree_node_iter *iter,
+ struct btree_keys *b,
+ unsigned first)
+{
+ if (btree_node_iter_cmp(iter, b, iter->data[first], iter->data[first + 1]))
+ swap(iter->data[first], iter->data[first + 1]);
+}
+
void bch_btree_node_iter_sort(struct btree_node_iter *iter,
struct btree_keys *b)
{
- int i;
+ EBUG_ON(iter->used > 3);
- BUG_ON(iter->used > MAX_BSETS);
+ /* unrolled bubble sort: */
- for (i = iter->used - 1; i >= 0; --i)
- btree_node_iter_sift(iter, b, i);
+ if (iter->used > 2) {
+ btree_node_iter_sort_two(iter, b, 0);
+ btree_node_iter_sort_two(iter, b, 1);
+ }
+
+ if (iter->used > 1)
+ btree_node_iter_sort_two(iter, b, 0);
}
EXPORT_SYMBOL(bch_btree_node_iter_sort);
@@ -1654,9 +1680,10 @@ struct btree_nr_keys bch_sort_bsets(struct bset *dst, struct btree_keys *b,
__bch_btree_node_iter_init(iter, b);
for (t = b->set + from; t <= b->set + b->nsets; t++)
- bch_btree_node_iter_push(iter, b,
- t->data->start,
- bset_bkey_last(t->data));
+ __bch_btree_node_iter_push(iter, b,
+ t->data->start,
+ bset_bkey_last(t->data));
+ bch_btree_node_iter_sort(iter, b);
}
/*