+2018-09-03 Alexander Monakov <amonakov@ispras.ru>
+
+ * sort.cc (struct sort_ctx): New field 'nlim'. Use it...
+ (mergesort): ... here as maximum count for using netsort.
+ (gcc_qsort): Set nlim to 3 if stable sort is requested.
+ (gcc_stablesort): New.
+ * system.h (gcc_stablesort): Declare.
+
2018-09-03 Alexander Monakov <amonakov@ispras.ru>
* sort.cc (gcc_qsort) [CHECKING_P]: Call qsort_chk.
char *out; // output buffer
size_t n; // number of elements
size_t size; // element size
+ size_t nlim; // limit for network sort
};
/* Helper for netsort. Permute, possibly in-place, 2 or 3 elements,
static void
mergesort (char *in, sort_ctx *c, size_t n, char *out, char *tmp)
{
- if (likely (n <= 5))
+ if (likely (n <= c->nlim))
{
c->out = out;
c->n = n;
{
if (n < 2)
return;
+ size_t nlim = 5;
+ bool stable = (ssize_t) size < 0;
+ if (stable)
+ nlim = 3, size = ~size;
char *base = (char *)vbase;
- sort_ctx c = {cmp, base, n, size};
+ sort_ctx c = {cmp, base, n, size, nlim};
long long scratch[32];
size_t bufsz = (n / 2) * size;
void *buf = bufsz <= sizeof scratch ? scratch : xmalloc (bufsz);
qsort_chk (vbase, n, size, cmp);
#endif
}
+
+void
+gcc_stablesort (void *vbase, size_t n, size_t size, cmp_fn *cmp)
+{
+ gcc_qsort (vbase, n, ~size, cmp);
+}
corresponding to vec::qsort (cmp): they use C qsort internally anyway. */
void qsort_chk (void *, size_t, size_t, int (*)(const void *, const void *));
void gcc_qsort (void *, size_t, size_t, int (*)(const void *, const void *));
+void gcc_stablesort (void *, size_t, size_t,
+ int (*)(const void *, const void *));
#define PP_5th(a1, a2, a3, a4, a5, ...) a5
#undef qsort
#define qsort(...) PP_5th (__VA_ARGS__, gcc_qsort, 3, 2, qsort, 0) (__VA_ARGS__)