mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-12 18:34:36 +08:00
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.
This commit is contained in:
parent
7b8b8a4331
commit
8d1f239003
@ -184,40 +184,34 @@ rt__int_size(ArrayType *a, float *size)
|
||||
*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 */
|
||||
bool
|
||||
isort(int32 *a, int len)
|
||||
{
|
||||
int32 cur,
|
||||
prev;
|
||||
int32 *pcur,
|
||||
*pprev,
|
||||
*end;
|
||||
bool r = FALSE;
|
||||
bool r = false;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
qsort_arg(a, len, sizeof(int32), isort_cmp, (void *) &r);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user