From: Andreas Gruenbacher <[email protected]>

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 <[email protected]>
---
 fs/bcachefs/eytzinger.h | 18 ++++--------------
 fs/bcachefs/util.c      | 12 ------------
 2 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/fs/bcachefs/eytzinger.h b/fs/bcachefs/eytzinger.h
index 6a363b12bd21..e600a7d52001 100644
--- a/fs/bcachefs/eytzinger.h
+++ b/fs/bcachefs/eytzinger.h
@@ -59,24 +59,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;
@@ -87,12 +77,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 {
diff --git a/fs/bcachefs/util.c b/fs/bcachefs/util.c
index e75329399c6e..0257a4c3bb4e 100644
--- a/fs/bcachefs/util.c
+++ b/fs/bcachefs/util.c
@@ -713,12 +713,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);
@@ -747,12 +741,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);
-- 
2.48.1


Reply via email to