]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: convert eytzinger sort to be 1-based (2)
authorAndreas Gruenbacher <agruenba@redhat.com>
Mon, 27 Jan 2025 19:54:52 +0000 (20:54 +0100)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 15 Mar 2025 01:02:14 +0000 (21:02 -0400)
In this second step, transform the eytzinger indexes i, j, and k in
eytzinger1_sort_r() from 0-based to 1-based.  This step looks a bit
messy, but the resulting code is slightly better.

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

index 4fe02c93bfb3dee89131af75e2dbd2caef5ff63b..0e742555cb0af98f197af6d7cb295a1a80a52687 100644 (file)
@@ -171,7 +171,7 @@ static void eytzinger1_sort_r(void *base1, size_t n, size_t size,
                              swap_r_func_t swap_func,
                              const void *priv)
 {
-       int i, j, k;
+       unsigned i, j, k;
 
        /* called from 'sort' without swap function, let's pick the default */
        if (swap_func == SWAP_WRAPPER && !((struct wrapper *)priv)->swap_func)
@@ -187,46 +187,46 @@ static void eytzinger1_sort_r(void *base1, size_t n, size_t size,
        }
 
        /* heapify */
-       for (i = n / 2 - 1; i >= 0; --i) {
+       for (i = n / 2; i >= 1; --i) {
                /* Find the sift-down path all the way to the leaves. */
-               for (j = i; k = j * 2 + 1, k + 1 < n;)
-                       j = eytzinger1_do_cmp(base1, n, size, cmp_func, priv, k + 1, k + 2) > 0 ? k : k + 1;
+               for (j = i; k = j * 2, k < n;)
+                       j = eytzinger1_do_cmp(base1, n, size, cmp_func, priv, k, k + 1) > 0 ? k : k + 1;
 
                /* Special case for the last leaf with no sibling. */
-               if (j * 2 + 2 == n)
-                       j = j * 2 + 1;
+               if (j * 2 == n)
+                       j *= 2;
 
                /* Backtrack to the correct location. */
-               while (j != i && eytzinger1_do_cmp(base1, n, size, cmp_func, priv, i + 1, j + 1) >= 0)
-                       j = (j - 1) / 2;
+               while (j != i && eytzinger1_do_cmp(base1, n, size, cmp_func, priv, i, j) >= 0)
+                       j /= 2;
 
                /* Shift the element into its correct place. */
                for (k = j; j != i;) {
-                       j = (j - 1) / 2;
-                       eytzinger1_do_swap(base1, n, size, swap_func, priv, j + 1, k + 1);
+                       j /= 2;
+                       eytzinger1_do_swap(base1, n, size, swap_func, priv, j, k);
                }
        }
 
        /* sort */
-       for (i = n - 1; i > 0; --i) {
-               eytzinger1_do_swap(base1, n, size, swap_func, priv, 1, i + 1);
+       for (i = n; i > 1; --i) {
+               eytzinger1_do_swap(base1, n, size, swap_func, priv, 1, i);
 
                /* Find the sift-down path all the way to the leaves. */
-               for (j = 0; k = j * 2 + 1, k + 1 < i;)
-                       j = eytzinger1_do_cmp(base1, n, size, cmp_func, priv, k + 1, k + 2) > 0 ? k : k + 1;
+               for (j = 1; k = j * 2, k + 1 < i;)
+                       j = eytzinger1_do_cmp(base1, n, size, cmp_func, priv, k, k + 1) > 0 ? k : k + 1;
 
                /* Special case for the last leaf with no sibling. */
-               if (j * 2 + 2 == i)
-                       j = j * 2 + 1;
+               if (j * 2 + 1 == i)
+                       j *= 2;
 
                /* Backtrack to the correct location. */
-               while (j && eytzinger1_do_cmp(base1, n, size, cmp_func, priv, 1, j + 1) >= 0)
-                       j = (j - 1) / 2;
+               while (j >= 1 && eytzinger1_do_cmp(base1, n, size, cmp_func, priv, 1, j) >= 0)
+                       j /= 2;
 
                /* Shift the element into its correct place. */
-               for (k = j; j;) {
-                       j = (j - 1) / 2;
-                       eytzinger1_do_swap(base1, n, size, swap_func, priv, j + 1, k + 1);
+               for (k = j; j > 1;) {
+                       j /= 2;
+                       eytzinger1_do_swap(base1, n, size, swap_func, priv, j, k);
                }
        }
 }