summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-08-30 15:18:31 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2021-08-30 15:18:31 -0400
commitee975017314d4bd7f03564f6ba5018dc3b0089cd (patch)
tree7491f5c98cd5efda781c9f89f0a2d0cdb24dcc9e
parentcce8a60ab1f5e2d1fee084ad55eee2a01560caeb (diff)
bcachefs: Kill bpos_diff()
This improves the btree iterator lookup code by using trans_for_each_iter_inorder(). Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/bkey.h31
-rw-r--r--fs/bcachefs/btree_iter.c33
2 files changed, 17 insertions, 47 deletions
diff --git a/fs/bcachefs/bkey.h b/fs/bcachefs/bkey.h
index 2e45d88fab03..c4a66f28ef4b 100644
--- a/fs/bcachefs/bkey.h
+++ b/fs/bcachefs/bkey.h
@@ -163,37 +163,6 @@ static inline struct bpos bpos_max(struct bpos l, struct bpos r)
return bpos_cmp(l, r) > 0 ? l : r;
}
-#define sbb(a, b, borrow) \
-do { \
- typeof(a) d1, d2; \
- \
- d1 = a - borrow; \
- borrow = d1 > a; \
- \
- d2 = d1 - b; \
- borrow += d2 > d1; \
- a = d2; \
-} while (0)
-
-/* returns a - b: */
-static inline struct bpos bpos_sub(struct bpos a, struct bpos b)
-{
- int borrow = 0;
-
- sbb(a.snapshot, b.snapshot, borrow);
- sbb(a.offset, b.offset, borrow);
- sbb(a.inode, b.inode, borrow);
- return a;
-}
-
-static inline struct bpos bpos_diff(struct bpos l, struct bpos r)
-{
- if (bpos_cmp(l, r) > 0)
- swap(l, r);
-
- return bpos_sub(r, l);
-}
-
void bch2_bpos_swab(struct bpos *);
void bch2_bkey_swab_key(const struct bkey_format *, struct bkey_packed *);
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index 9ba0dc402d89..cdd6f6c81fb2 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -2299,8 +2299,9 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans,
unsigned depth,
unsigned flags)
{
- struct btree_iter *iter, *best = NULL;
+ struct btree_iter *iter, *list_pos = NULL, *best = NULL;
struct bpos real_pos, pos_min = POS_MIN;
+ int cmp;
EBUG_ON(trans->restarted);
@@ -2324,27 +2325,27 @@ struct btree_iter *__bch2_trans_get_iter(struct btree_trans *trans,
bkey_cmp(pos, POS_MAX))
real_pos = bpos_nosnap_successor(pos);
- trans_for_each_iter(trans, iter) {
- if (btree_iter_type(iter) != (flags & BTREE_ITER_TYPE))
- continue;
+ trans_for_each_iter_inorder(trans, iter) {
+ list_pos = iter;
- if (iter->btree_id != btree_id)
+ if (btree_iter_type(iter) != (flags & BTREE_ITER_TYPE) ||
+ iter->btree_id != btree_id)
continue;
- if (best) {
- int cmp = bkey_cmp(bpos_diff(best->real_pos, real_pos),
- bpos_diff(iter->real_pos, real_pos));
-
- if (cmp < 0 ||
- ((cmp == 0 && btree_iter_keep(trans, iter))))
- continue;
- }
-
- best = iter;
+ /*
+ * Since advancing iterators is cheaper than rewinding them, we
+ * prefer a path <= the search pos
+ */
+ cmp = bpos_cmp(iter->real_pos, real_pos) ?:
+ cmp_int(iter->level, depth);
+ if (!best || cmp <= 0)
+ best = iter;
+ if (cmp >= 0)
+ break;
}
if (!best) {
- iter = btree_trans_iter_alloc(trans, NULL);
+ iter = btree_trans_iter_alloc(trans, list_pos);
bch2_btree_iter_init(trans, iter, btree_id);
} else if (btree_iter_keep(trans, best)) {
iter = btree_trans_iter_alloc(trans, best);