+#if defined(SORT_REGULAR) && !defined(SORT_UNIFY)
+
+/* If we are doing a simple sort on a regular file, we can use a faster presorting strategy */
+
+static SORT_KEY *P(array);
+
+#define ASORT_PREFIX(x) SORT_PREFIX(x##_array)
+#define ASORT_KEY_TYPE SORT_KEY
+#define ASORT_ELT(i) P(array)[i]
+#define ASORT_LT(x,y) (P(compare)(&(x),&(y)) < 0)
+
+#include "lib/arraysort.h"
+
+static void
+P(presort)(struct fastbuf **fb1, struct fastbuf **fb2)
+{
+ struct fastbuf *in = *fb1;
+ struct fastbuf *out1 = NULL;
+ struct fastbuf *out2 = NULL;
+ struct fastbuf *tbuf;
+ uns buf_items = sorter_presort_bufsize / sizeof(SORT_KEY);
+ uns run_count = 0;
+ SORT_KEY last_out = { }, *array;
+
+ ASSERT(!*fb2);
+ if (buf_items < 2)
+ die("PresortBuffer set too low");
+ P(array) = array = xmalloc(buf_items * sizeof(SORT_KEY));
+
+ for(;;)
+ {
+ uns s = bread(in, array, buf_items * sizeof(SORT_KEY));
+ uns n = s / sizeof(SORT_KEY);
+ ASSERT(!(s % sizeof(SORT_KEY)));
+ if (!n)
+ break;
+ P(sort_array)(n);
+#ifdef SORT_ASSERT_UNIQUE
+ for (uns i=0; i<n-1; i++)
+ if (unlikely(P(compare)(&array[i], &array[i+1]) >= 0))
+ ASSERT(0);
+ ASSERT(!run_count || P(compare)(&last_out, &array[0]));
+#endif
+ if (!run_count || P(compare)(&last_out, &array[0]) > 0)
+ {
+ run_count++;
+#ifdef SORT_UP_TO
+ if (sorter_presort_bufsize < (uns) SORT_UP_TO)
+#endif
+ SWAP(out1, out2, tbuf);
+ if (!out1)
+ out1 = bopen_tmp(sorter_stream_bufsize);
+ }
+ last_out = array[n-1];
+ bwrite(out1, array, n * sizeof(SORT_KEY));
+ }
+
+ bclose(in);
+ if (sorter_trace)
+ log(L_INFO, "Pass 0: %d runs, %d+%d KB",
+ run_count,
+ (out1 ? (int)((btell(out1) + 1023) / 1024) : 0),
+ (out2 ? (int)((btell(out2) + 1023) / 1024) : 0));
+ *fb1 = P(flush_out)(out1);
+ *fb2 = P(flush_out)(out2);
+ xfree(array);
+}
+
+#else
+