Browse Source

Disable the "switch to insertion sort" optimization to avoid quadratic

behavior for certain inputs.  From NetBSD.  OK tedu@
OPENBSD_5_6
millert 10 years ago
parent
commit
3c0d2bba38
1 changed files with 2 additions and 13 deletions
  1. +2
    -13
      src/lib/libc/stdlib/qsort.c

+ 2
- 13
src/lib/libc/stdlib/qsort.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: qsort.c,v 1.11 2010/02/08 11:04:07 otto Exp $ */
/* $OpenBSD: qsort.c,v 1.12 2014/06/12 14:54:25 millert Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
@ -84,12 +84,11 @@ void
qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *)) qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *))
{ {
char *pa, *pb, *pc, *pd, *pl, *pm, *pn; char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
int cmp_result, swaptype, swap_cnt;
int cmp_result, swaptype;
size_t d, r; size_t d, r;
char *a = aa; char *a = aa;
loop: SWAPINIT(a, es); loop: SWAPINIT(a, es);
swap_cnt = 0;
if (n < 7) { if (n < 7) {
for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es) for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
@ -116,7 +115,6 @@ loop: SWAPINIT(a, es);
for (;;) { for (;;) {
while (pb <= pc && (cmp_result = cmp(pb, a)) <= 0) { while (pb <= pc && (cmp_result = cmp(pb, a)) <= 0) {
if (cmp_result == 0) { if (cmp_result == 0) {
swap_cnt = 1;
swap(pa, pb); swap(pa, pb);
pa += es; pa += es;
} }
@ -124,7 +122,6 @@ loop: SWAPINIT(a, es);
} }
while (pb <= pc && (cmp_result = cmp(pc, a)) >= 0) { while (pb <= pc && (cmp_result = cmp(pc, a)) >= 0) {
if (cmp_result == 0) { if (cmp_result == 0) {
swap_cnt = 1;
swap(pc, pd); swap(pc, pd);
pd -= es; pd -= es;
} }
@ -133,17 +130,9 @@ loop: SWAPINIT(a, es);
if (pb > pc) if (pb > pc)
break; break;
swap(pb, pc); swap(pb, pc);
swap_cnt = 1;
pb += es; pb += es;
pc -= es; pc -= es;
} }
if (swap_cnt == 0) { /* Switch to insertion sort */
for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
pl -= es)
swap(pl, pl - es);
return;
}
pn = (char *)a + n * es; pn = (char *)a + n * es;
r = min(pa - (char *)a, pb - pa); r = min(pa - (char *)a, pb - pa);


Loading…
Cancel
Save