Commit 8d1f2390 authored by Tom Lane's avatar Tom Lane

Replace insertion sort in contrib/intarray with qsort().

It's all very well to claim that a simplistic sort is fast in easy
cases, but O(N^2) in the worst case is not good ... especially if the
worst case is as easy to hit as "descending order input".  Replace that
bit with our standard qsort.

Per bug #12866 from Maksym Boguk.  Back-patch to all active branches.
parent 7b8b8a43
...@@ -184,40 +184,34 @@ rt__int_size(ArrayType *a, float *size) ...@@ -184,40 +184,34 @@ rt__int_size(ArrayType *a, float *size)
*size = (float) ARRNELEMS(a); *size = (float) ARRNELEMS(a);
} }
/* qsort_arg comparison function for isort() */
static int
isort_cmp(const void *a, const void *b, void *arg)
{
int32 aval = *((const int32 *) a);
int32 bval = *((const int32 *) b);
if (aval < bval)
return -1;
if (aval > bval)
return 1;
/*
* Report if we have any duplicates. If there are equal keys, qsort must
* compare them at some point, else it wouldn't know whether one should go
* before or after the other.
*/
*((bool *) arg) = true;
return 0;
}
/* Sort the given data (len >= 2). Return true if any duplicates found */ /* Sort the given data (len >= 2). Return true if any duplicates found */
bool bool
isort(int32 *a, int len) isort(int32 *a, int len)
{ {
int32 cur, bool r = false;
prev;
int32 *pcur,
*pprev,
*end;
bool r = FALSE;
/* qsort_arg(a, len, sizeof(int32), isort_cmp, (void *) &r);
* We use a simple insertion sort. While this is O(N^2) in the worst
* case, it's quite fast if the input is already sorted or nearly so.
* Also, for not-too-large inputs it's faster than more complex methods
* anyhow.
*/
end = a + len;
for (pcur = a + 1; pcur < end; pcur++)
{
cur = *pcur;
for (pprev = pcur - 1; pprev >= a; pprev--)
{
prev = *pprev;
if (prev <= cur)
{
if (prev == cur)
r = TRUE;
break;
}
pprev[1] = prev;
}
pprev[1] = cur;
}
return r; return r;
} }
......
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