mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-07 17:27:40 +00:00
Sorting function cleanup and MinGW fix
Clean up some sorting function stuff including fixing qsort_r on MinGW, common function pointer type for comparison, and basic insertion sort implementation (which we, regrettably, fall back on for MinGW).
This commit is contained in:
parent
a5eea2d7b7
commit
62beacd300
@ -24,7 +24,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int binsearch(
|
static int binsearch(
|
||||||
void **dst, const void *x, size_t size, git__tsort_r_cmp cmp, void *payload)
|
void **dst, const void *x, size_t size, git__sort_r_cmp cmp, void *payload)
|
||||||
{
|
{
|
||||||
int l, c, r;
|
int l, c, r;
|
||||||
void *lx, *cx;
|
void *lx, *cx;
|
||||||
@ -71,7 +71,7 @@ static int binsearch(
|
|||||||
|
|
||||||
/* Binary insertion sort, but knowing that the first "start" entries are sorted. Used in timsort. */
|
/* Binary insertion sort, but knowing that the first "start" entries are sorted. Used in timsort. */
|
||||||
static void bisort(
|
static void bisort(
|
||||||
void **dst, size_t start, size_t size, git__tsort_r_cmp cmp, void *payload)
|
void **dst, size_t start, size_t size, git__sort_r_cmp cmp, void *payload)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
void *x;
|
void *x;
|
||||||
@ -102,7 +102,7 @@ struct tsort_run {
|
|||||||
|
|
||||||
struct tsort_store {
|
struct tsort_store {
|
||||||
size_t alloc;
|
size_t alloc;
|
||||||
git__tsort_r_cmp cmp;
|
git__sort_r_cmp cmp;
|
||||||
void *payload;
|
void *payload;
|
||||||
void **storage;
|
void **storage;
|
||||||
};
|
};
|
||||||
@ -334,7 +334,7 @@ static ssize_t collapse(void **dst, struct tsort_run *stack, ssize_t stack_curr,
|
|||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
void git__tsort_r(
|
void git__tsort_r(
|
||||||
void **dst, size_t size, git__tsort_r_cmp cmp, void *payload)
|
void **dst, size_t size, git__sort_r_cmp cmp, void *payload)
|
||||||
{
|
{
|
||||||
struct tsort_store _store, *store = &_store;
|
struct tsort_store _store, *store = &_store;
|
||||||
struct tsort_run run_stack[128];
|
struct tsort_run run_stack[128];
|
||||||
|
34
src/util.c
34
src/util.c
@ -610,7 +610,7 @@ size_t git__unescape(char *str)
|
|||||||
|
|
||||||
#if defined(GIT_WIN32) || defined(BSD)
|
#if defined(GIT_WIN32) || defined(BSD)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
git__qsort_r_cmp cmp;
|
git__sort_r_cmp cmp;
|
||||||
void *payload;
|
void *payload;
|
||||||
} git__qsort_r_glue;
|
} git__qsort_r_glue;
|
||||||
|
|
||||||
@ -623,17 +623,39 @@ static int GIT_STDLIB_CALL git__qsort_r_glue_cmp(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void git__qsort_r(
|
void git__qsort_r(
|
||||||
void *els, size_t nel, size_t elsize, git__qsort_r_cmp cmp, void *payload)
|
void *els, size_t nel, size_t elsize, git__sort_r_cmp cmp, void *payload)
|
||||||
{
|
{
|
||||||
#if defined(GIT_WIN32)
|
#if defined(__MINGW32__)
|
||||||
|
git__insertsort_r(els, nel, elsize, NULL, cmp, payload);
|
||||||
|
#elif defined(GIT_WIN32)
|
||||||
git__qsort_r_glue glue = { cmp, payload };
|
git__qsort_r_glue glue = { cmp, payload };
|
||||||
qsort_s(els, nel, elsize, git__qsort_r_glue_cmp, &glue);
|
qsort_s(els, nel, elsize, git__qsort_r_glue_cmp, &glue);
|
||||||
#else
|
#elif defined(BSD)
|
||||||
#if defined(BSD)
|
|
||||||
git__qsort_r_glue glue = { cmp, payload };
|
git__qsort_r_glue glue = { cmp, payload };
|
||||||
qsort_r(els, nel, elsize, &glue, git__qsort_r_glue_cmp);
|
qsort_r(els, nel, elsize, &glue, git__qsort_r_glue_cmp);
|
||||||
#else
|
#else
|
||||||
qsort_r(els, nel, elsize, cmp, payload);
|
qsort_r(els, nel, elsize, cmp, payload);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
void git__insertsort_r(
|
||||||
|
void *els, size_t nel, size_t elsize, void *swapel,
|
||||||
|
git__sort_r_cmp cmp, void *payload)
|
||||||
|
{
|
||||||
|
uint8_t *base = els, *end = els + nel * elsize;
|
||||||
|
uint8_t *i, *j;
|
||||||
|
bool freeswap = !swapel;
|
||||||
|
|
||||||
|
if (freeswap)
|
||||||
|
swapel = git__malloc(elsize);
|
||||||
|
|
||||||
|
for (i = base + elsize; i < end; i += elsize)
|
||||||
|
for (j = i; j > base && cmp(j, j - elsize, payload) < 0; j -= elsize) {
|
||||||
|
memcpy(swapel, j, elsize);
|
||||||
|
memcpy(j, j - elsize, elsize);
|
||||||
|
memcpy(j - elsize, swapel, elsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (freeswap)
|
||||||
|
git__free(swapel);
|
||||||
}
|
}
|
||||||
|
12
src/util.h
12
src/util.h
@ -146,15 +146,17 @@ typedef int (*git__tsort_cmp)(const void *a, const void *b);
|
|||||||
|
|
||||||
extern void git__tsort(void **dst, size_t size, git__tsort_cmp cmp);
|
extern void git__tsort(void **dst, size_t size, git__tsort_cmp cmp);
|
||||||
|
|
||||||
typedef int (*git__tsort_r_cmp)(const void *a, const void *b, void *payload);
|
typedef int (*git__sort_r_cmp)(const void *a, const void *b, void *payload);
|
||||||
|
|
||||||
extern void git__tsort_r(
|
extern void git__tsort_r(
|
||||||
void **dst, size_t size, git__tsort_r_cmp cmp, void *payload);
|
void **dst, size_t size, git__sort_r_cmp cmp, void *payload);
|
||||||
|
|
||||||
typedef int (*git__qsort_r_cmp)(const void *a, const void *b, void *payload);
|
|
||||||
|
|
||||||
extern void git__qsort_r(
|
extern void git__qsort_r(
|
||||||
void *els, size_t nel, size_t elsize, git__qsort_r_cmp cmp, void *payload);
|
void *els, size_t nel, size_t elsize, git__sort_r_cmp cmp, void *payload);
|
||||||
|
|
||||||
|
extern void git__insertsort_r(
|
||||||
|
void *els, size_t nel, size_t elsize, void *swapel,
|
||||||
|
git__sort_r_cmp cmp, void *payload);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param position If non-NULL, this will be set to the position where the
|
* @param position If non-NULL, this will be set to the position where the
|
||||||
|
Loading…
Reference in New Issue
Block a user