]> www.infradead.org Git - users/hch/misc.git/commitdiff
bcachefs: eytzinger1_{next,prev} cleanup
authorAndreas Gruenbacher <agruenba@redhat.com>
Tue, 28 Jan 2025 17:24:15 +0000 (18:24 +0100)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 15 Mar 2025 01:02:14 +0000 (21:02 -0400)
The eytzinger code was previously relying on the following wrap-around
properties and their "eytzinger0" equivalents:

  eytzinger1_prev(0, size) == eytzinger1_last(size)
  eytzinger1_next(0, size) == eytzinger1_first(size)

However, these properties are no longer relied upon and no longer
necessary, so remove the corresponding asserts and forbid the use of
eytzinger1_prev(0, size) and eytzinger1_next(0, size).

This allows to further simplify the code in eytzinger1_next() and
eytzinger1_prev(): where the left shifting happens, eytzinger1_next() is
trying to move i to the lowest child on the left, which is equivalent to
doubling i until the next doubling would cause it to be greater than
size.  This is implemented by shifting i to the left so that the most
significant bits align and then shifting i to the right by one if the
result is greater than size.

Likewise, eytzinger1_prev() is trying to move to the lowest child on the
right; the same applies here.

The 1-offset in (size - 1) in eytzinger1_next() isn't needed at all, but
the equivalent offset in eytzinger1_prev() is surprisingly needed to
preserve the 'eytzinger1_prev(0, size) == eytzinger1_last(size)'
property.  However, since we no longer support that property, we can get
rid of these offsets as well.  This saves one addition in each function
and makes the code less confusing.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/eytzinger.h
fs/bcachefs/util.c

index 90cd5648b17776f06f636bd4494cc51599a00c56..643c1f7160615d673100bb56426e34706f220cb6 100644 (file)
@@ -57,24 +57,14 @@ static inline unsigned eytzinger1_last(unsigned size)
        return rounddown_pow_of_two(size + 1) - 1;
 }
 
-/*
- * eytzinger1_next() and eytzinger1_prev() have the nice properties that
- *
- * eytzinger1_next(0) == eytzinger1_first())
- * eytzinger1_prev(0) == eytzinger1_last())
- *
- * eytzinger1_prev(eytzinger1_first()) == 0
- * eytzinger1_next(eytzinger1_last()) == 0
- */
-
 static inline unsigned eytzinger1_next(unsigned i, unsigned size)
 {
-       EYTZINGER_BUG_ON(i > size);
+       EYTZINGER_BUG_ON(i == 0 || i > size);
 
        if (eytzinger1_right_child(i) <= size) {
                i = eytzinger1_right_child(i);
 
-               i <<= __fls(size + 1) - __fls(i);
+               i <<= __fls(size) - __fls(i);
                i >>= i > size;
        } else {
                i >>= ffz(i) + 1;
@@ -85,12 +75,12 @@ static inline unsigned eytzinger1_next(unsigned i, unsigned size)
 
 static inline unsigned eytzinger1_prev(unsigned i, unsigned size)
 {
-       EYTZINGER_BUG_ON(i > size);
+       EYTZINGER_BUG_ON(i == 0 || i > size);
 
        if (eytzinger1_left_child(i) <= size) {
                i = eytzinger1_left_child(i) + 1;
 
-               i <<= __fls(size + 1) - __fls(i);
+               i <<= __fls(size) - __fls(i);
                i -= 1;
                i >>= i > size;
        } else {
index 525734528f3534d77ecbe9f72434cceed8b9a163..a7edbcca1a849a8b28031efa7f36e3af96685a95 100644 (file)
@@ -719,12 +719,6 @@ void eytzinger1_test(void)
                if (!(size % 4096))
                        pr_info("tree size %u\n", size);
 
-               BUG_ON(eytzinger1_prev(0, size) != eytzinger1_last(size));
-               BUG_ON(eytzinger1_next(0, size) != eytzinger1_first(size));
-
-               BUG_ON(eytzinger1_prev(eytzinger1_first(size), size)    != 0);
-               BUG_ON(eytzinger1_next(eytzinger1_last(size), size)     != 0);
-
                inorder = 1;
                eytzinger1_for_each(eytz, size) {
                        BUG_ON(__inorder_to_eytzinger1(inorder, size, extra) != eytz);
@@ -753,12 +747,6 @@ void eytzinger0_test(void)
                if (!(size % 4096))
                        pr_info("tree size %u\n", size);
 
-               BUG_ON(eytzinger0_prev(-1, size) != eytzinger0_last(size));
-               BUG_ON(eytzinger0_next(-1, size) != eytzinger0_first(size));
-
-               BUG_ON(eytzinger0_prev(eytzinger0_first(size), size)    != -1);
-               BUG_ON(eytzinger0_next(eytzinger0_last(size), size)     != -1);
-
                inorder = 0;
                eytzinger0_for_each(eytz, size) {
                        BUG_ON(__inorder_to_eytzinger0(inorder, size, extra) != eytz);