diff options
author | millert <> | 2014-06-12 14:54:25 +0000 |
---|---|---|
committer | millert <> | 2014-06-12 14:54:25 +0000 |
commit | e2ae8e879310fea586d76887b5b37a06a024001f (patch) | |
tree | 5a930e41526fd1e8db9c66e989951f7aa8eb4878 | |
parent | 529ba790cb39287b1bbac6c35b1623f14b2bbfdb (diff) | |
download | openbsd-e2ae8e879310fea586d76887b5b37a06a024001f.tar.gz openbsd-e2ae8e879310fea586d76887b5b37a06a024001f.tar.bz2 openbsd-e2ae8e879310fea586d76887b5b37a06a024001f.zip |
Disable the "switch to insertion sort" optimization to avoid quadratic
behavior for certain inputs. From NetBSD. OK tedu@
-rw-r--r-- | src/lib/libc/stdlib/qsort.c | 15 |
1 files changed, 2 insertions, 13 deletions
diff --git a/src/lib/libc/stdlib/qsort.c b/src/lib/libc/stdlib/qsort.c index f28449fb5b..2a51c77634 100644 --- a/src/lib/libc/stdlib/qsort.c +++ b/src/lib/libc/stdlib/qsort.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: qsort.c,v 1.11 2010/02/08 11:04:07 otto Exp $ */ | 1 | /* $OpenBSD: qsort.c,v 1.12 2014/06/12 14:54:25 millert Exp $ */ |
2 | /*- | 2 | /*- |
3 | * Copyright (c) 1992, 1993 | 3 | * Copyright (c) 1992, 1993 |
4 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
@@ -84,12 +84,11 @@ void | |||
84 | qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *)) | 84 | qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *)) |
85 | { | 85 | { |
86 | char *pa, *pb, *pc, *pd, *pl, *pm, *pn; | 86 | char *pa, *pb, *pc, *pd, *pl, *pm, *pn; |
87 | int cmp_result, swaptype, swap_cnt; | 87 | int cmp_result, swaptype; |
88 | size_t d, r; | 88 | size_t d, r; |
89 | char *a = aa; | 89 | char *a = aa; |
90 | 90 | ||
91 | loop: SWAPINIT(a, es); | 91 | loop: SWAPINIT(a, es); |
92 | swap_cnt = 0; | ||
93 | if (n < 7) { | 92 | if (n < 7) { |
94 | for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es) | 93 | for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es) |
95 | for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; | 94 | for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; |
@@ -116,7 +115,6 @@ loop: SWAPINIT(a, es); | |||
116 | for (;;) { | 115 | for (;;) { |
117 | while (pb <= pc && (cmp_result = cmp(pb, a)) <= 0) { | 116 | while (pb <= pc && (cmp_result = cmp(pb, a)) <= 0) { |
118 | if (cmp_result == 0) { | 117 | if (cmp_result == 0) { |
119 | swap_cnt = 1; | ||
120 | swap(pa, pb); | 118 | swap(pa, pb); |
121 | pa += es; | 119 | pa += es; |
122 | } | 120 | } |
@@ -124,7 +122,6 @@ loop: SWAPINIT(a, es); | |||
124 | } | 122 | } |
125 | while (pb <= pc && (cmp_result = cmp(pc, a)) >= 0) { | 123 | while (pb <= pc && (cmp_result = cmp(pc, a)) >= 0) { |
126 | if (cmp_result == 0) { | 124 | if (cmp_result == 0) { |
127 | swap_cnt = 1; | ||
128 | swap(pc, pd); | 125 | swap(pc, pd); |
129 | pd -= es; | 126 | pd -= es; |
130 | } | 127 | } |
@@ -133,17 +130,9 @@ loop: SWAPINIT(a, es); | |||
133 | if (pb > pc) | 130 | if (pb > pc) |
134 | break; | 131 | break; |
135 | swap(pb, pc); | 132 | swap(pb, pc); |
136 | swap_cnt = 1; | ||
137 | pb += es; | 133 | pb += es; |
138 | pc -= es; | 134 | pc -= es; |
139 | } | 135 | } |
140 | if (swap_cnt == 0) { /* Switch to insertion sort */ | ||
141 | for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es) | ||
142 | for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; | ||
143 | pl -= es) | ||
144 | swap(pl, pl - es); | ||
145 | return; | ||
146 | } | ||
147 | 136 | ||
148 | pn = (char *)a + n * es; | 137 | pn = (char *)a + n * es; |
149 | r = min(pa - (char *)a, pb - pa); | 138 | r = min(pa - (char *)a, pb - pa); |