Skip to content

Commit 8d1f239

Browse files
committed
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.
1 parent 7b8b8a4 commit 8d1f239

File tree

1 file changed

+23
-29
lines changed

1 file changed

+23
-29
lines changed

contrib/intarray/_int_tool.c

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -184,40 +184,34 @@ rt__int_size(ArrayType *a, float *size)
184184
*size = (float) ARRNELEMS(a);
185185
}
186186

187+
/* qsort_arg comparison function for isort() */
188+
static int
189+
isort_cmp(const void *a, const void *b, void *arg)
190+
{
191+
int32 aval = *((const int32 *) a);
192+
int32 bval = *((const int32 *) b);
193+
194+
if (aval < bval)
195+
return -1;
196+
if (aval > bval)
197+
return 1;
198+
199+
/*
200+
* Report if we have any duplicates. If there are equal keys, qsort must
201+
* compare them at some point, else it wouldn't know whether one should go
202+
* before or after the other.
203+
*/
204+
*((bool *) arg) = true;
205+
return 0;
206+
}
207+
187208
/* Sort the given data (len >= 2). Return true if any duplicates found */
188209
bool
189210
isort(int32 *a, int len)
190211
{
191-
int32 cur,
192-
prev;
193-
int32 *pcur,
194-
*pprev,
195-
*end;
196-
bool r = FALSE;
212+
bool r = false;
197213

198-
/*
199-
* We use a simple insertion sort. While this is O(N^2) in the worst
200-
* case, it's quite fast if the input is already sorted or nearly so.
201-
* Also, for not-too-large inputs it's faster than more complex methods
202-
* anyhow.
203-
*/
204-
end = a + len;
205-
for (pcur = a + 1; pcur < end; pcur++)
206-
{
207-
cur = *pcur;
208-
for (pprev = pcur - 1; pprev >= a; pprev--)
209-
{
210-
prev = *pprev;
211-
if (prev <= cur)
212-
{
213-
if (prev == cur)
214-
r = TRUE;
215-
break;
216-
}
217-
pprev[1] = prev;
218-
}
219-
pprev[1] = cur;
220-
}
214+
qsort_arg(a, len, sizeof(int32), isort_cmp, (void *) &r);
221215
return r;
222216
}
223217

0 commit comments

Comments
 (0)