mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-09 07:51:16 -04:00
bcachefs: convert eytzinger sort to be 1-based (1)
In this first step, convert the eytzinger sort functions to use 1-based primitives. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
committed by
Kent Overstreet
parent
3849bcab4d
commit
3ff0dd28d6
@@ -148,28 +148,28 @@ static int do_cmp(const void *a, const void *b, cmp_r_func_t cmp, const void *pr
|
||||
return cmp(a, b, priv);
|
||||
}
|
||||
|
||||
static inline int eytzinger0_do_cmp(void *base, size_t n, size_t size,
|
||||
static inline int eytzinger1_do_cmp(void *base1, size_t n, size_t size,
|
||||
cmp_r_func_t cmp_func, const void *priv,
|
||||
size_t l, size_t r)
|
||||
{
|
||||
return do_cmp(base + inorder_to_eytzinger0(l, n) * size,
|
||||
base + inorder_to_eytzinger0(r, n) * size,
|
||||
return do_cmp(base1 + inorder_to_eytzinger1(l, n) * size,
|
||||
base1 + inorder_to_eytzinger1(r, n) * size,
|
||||
cmp_func, priv);
|
||||
}
|
||||
|
||||
static inline void eytzinger0_do_swap(void *base, size_t n, size_t size,
|
||||
static inline void eytzinger1_do_swap(void *base1, size_t n, size_t size,
|
||||
swap_r_func_t swap_func, const void *priv,
|
||||
size_t l, size_t r)
|
||||
{
|
||||
do_swap(base + inorder_to_eytzinger0(l, n) * size,
|
||||
base + inorder_to_eytzinger0(r, n) * size,
|
||||
do_swap(base1 + inorder_to_eytzinger1(l, n) * size,
|
||||
base1 + inorder_to_eytzinger1(r, n) * size,
|
||||
size, swap_func, priv);
|
||||
}
|
||||
|
||||
void eytzinger0_sort_r(void *base, size_t n, size_t size,
|
||||
cmp_r_func_t cmp_func,
|
||||
swap_r_func_t swap_func,
|
||||
const void *priv)
|
||||
static void eytzinger1_sort_r(void *base1, size_t n, size_t size,
|
||||
cmp_r_func_t cmp_func,
|
||||
swap_r_func_t swap_func,
|
||||
const void *priv)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
@@ -178,9 +178,9 @@ void eytzinger0_sort_r(void *base, size_t n, size_t size,
|
||||
swap_func = NULL;
|
||||
|
||||
if (!swap_func) {
|
||||
if (is_aligned(base, size, 8))
|
||||
if (is_aligned(base1, size, 8))
|
||||
swap_func = SWAP_WORDS_64;
|
||||
else if (is_aligned(base, size, 4))
|
||||
else if (is_aligned(base1, size, 4))
|
||||
swap_func = SWAP_WORDS_32;
|
||||
else
|
||||
swap_func = SWAP_BYTES;
|
||||
@@ -190,47 +190,57 @@ void eytzinger0_sort_r(void *base, size_t n, size_t size,
|
||||
for (i = n / 2 - 1; i >= 0; --i) {
|
||||
/* Find the sift-down path all the way to the leaves. */
|
||||
for (j = i; k = j * 2 + 1, k + 1 < n;)
|
||||
j = eytzinger0_do_cmp(base, n, size, cmp_func, priv, k, k + 1) > 0 ? k : k + 1;
|
||||
j = eytzinger1_do_cmp(base1, n, size, cmp_func, priv, k + 1, k + 2) > 0 ? k : k + 1;
|
||||
|
||||
/* Special case for the last leaf with no sibling. */
|
||||
if (j * 2 + 2 == n)
|
||||
j = j * 2 + 1;
|
||||
|
||||
/* Backtrack to the correct location. */
|
||||
while (j != i && eytzinger0_do_cmp(base, n, size, cmp_func, priv, i, j) >= 0)
|
||||
while (j != i && eytzinger1_do_cmp(base1, n, size, cmp_func, priv, i + 1, j + 1) >= 0)
|
||||
j = (j - 1) / 2;
|
||||
|
||||
/* Shift the element into its correct place. */
|
||||
for (k = j; j != i;) {
|
||||
j = (j - 1) / 2;
|
||||
eytzinger0_do_swap(base, n, size, swap_func, priv, j, k);
|
||||
eytzinger1_do_swap(base1, n, size, swap_func, priv, j + 1, k + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* sort */
|
||||
for (i = n - 1; i > 0; --i) {
|
||||
eytzinger0_do_swap(base, n, size, swap_func, priv, 0, i);
|
||||
eytzinger1_do_swap(base1, n, size, swap_func, priv, 1, i + 1);
|
||||
|
||||
/* Find the sift-down path all the way to the leaves. */
|
||||
for (j = 0; k = j * 2 + 1, k + 1 < i;)
|
||||
j = eytzinger0_do_cmp(base, n, size, cmp_func, priv, k, k + 1) > 0 ? k : k + 1;
|
||||
j = eytzinger1_do_cmp(base1, n, size, cmp_func, priv, k + 1, k + 2) > 0 ? k : k + 1;
|
||||
|
||||
/* Special case for the last leaf with no sibling. */
|
||||
if (j * 2 + 2 == i)
|
||||
j = j * 2 + 1;
|
||||
|
||||
/* Backtrack to the correct location. */
|
||||
while (j && eytzinger0_do_cmp(base, n, size, cmp_func, priv, 0, j) >= 0)
|
||||
while (j && eytzinger1_do_cmp(base1, n, size, cmp_func, priv, 1, j + 1) >= 0)
|
||||
j = (j - 1) / 2;
|
||||
|
||||
/* Shift the element into its correct place. */
|
||||
for (k = j; j;) {
|
||||
j = (j - 1) / 2;
|
||||
eytzinger0_do_swap(base, n, size, swap_func, priv, j, k);
|
||||
eytzinger1_do_swap(base1, n, size, swap_func, priv, j + 1, k + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void eytzinger0_sort_r(void *base, size_t n, size_t size,
|
||||
cmp_r_func_t cmp_func,
|
||||
swap_r_func_t swap_func,
|
||||
const void *priv)
|
||||
{
|
||||
void *base1 = base - size;
|
||||
|
||||
return eytzinger1_sort_r(base1, n, size, cmp_func, swap_func, priv);
|
||||
}
|
||||
|
||||
void eytzinger0_sort(void *base, size_t n, size_t size,
|
||||
cmp_func_t cmp_func,
|
||||
swap_func_t swap_func)
|
||||
|
||||
Reference in New Issue
Block a user