Skip to content

Commit 8582ae7

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 309ff2a commit 8582ae7

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+
int4 aval = *((const int4 *) a);
192+
int4 bval = *((const int4 *) 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(int4 *a, int len)
190211
{
191-
int4 cur,
192-
prev;
193-
int4 *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(int4), 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