Commit 62beacd3 by Russell Belfer

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).
parent a5eea2d7
...@@ -24,7 +24,7 @@ ...@@ -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( ...@@ -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 { ...@@ -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, ...@@ -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];
......
...@@ -610,7 +610,7 @@ size_t git__unescape(char *str) ...@@ -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( ...@@ -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);
} }
...@@ -146,15 +146,17 @@ typedef int (*git__tsort_cmp)(const void *a, const void *b); ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment