mirror of
https://github.com/postgres/postgres.git
synced 2025-04-20 00:42:27 +03: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
2cb76fa6ff
commit
83587a075d
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user