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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy