From: Heng Li Date: Fri, 8 Jun 2012 23:00:25 +0000 (-0400) Subject: improved my implementation of radix sort X-Git-Tag: spawn-final~48 X-Git-Url: http://www.kaiwu.me/postgresql/commit/static/gitweb.js?a=commitdiff_plain;h=a9961e6fd720e610fc0026d859aace2201c6214b;p=klib.git improved my implementation of radix sort --- diff --git a/test/ksort_test.cc b/test/ksort_test.cc index e4c937b..49b08cb 100644 --- a/test/ksort_test.cc +++ b/test/ksort_test.cc @@ -594,41 +594,41 @@ typedef struct { rstype_t *b, *e; } rsbucket_t; -void rs_classify(rstype_t *beg, rstype_t *end, int n_bits, int s, rsbucket_t *b) +void rs_sort(rstype_t *beg, rstype_t *end, int n_bits, int s) { - rstype_t *i, tmp; - int m = (1<b = k->e = beg; for (i = beg; i != end; ++i) ++b[rskey(*i)>>s&m].e; - if (b[0].e == end) return; // no need to sort - for (k = b + 1; k != be; ++k) - k->e += (k-1)->e - beg, k->b = (k-1)->e; - for (k = b; k != be;) { - if (k->b == k->e) { ++k; continue; } - l = b + (rskey(*k->b)>>s&m); - if (k == l) { ++k->b; continue; } - tmp = *l->b; *l->b++ = *k->b; *k->b = tmp; + if (b[0].e != end) { + for (k = b + 1; k != be; ++k) + k->e += (k-1)->e - beg, k->b = (k-1)->e; + for (k = b; k != be;) { + rstype_t t[2]; + rsbucket_t *l; + int curr = 0; + if (k->b == k->e) { ++k; continue; } + l = b + (rskey(*k->b)>>s&m); + if (k == l) { ++k->b; continue; } + t[curr] = *k->b; + do { + t[!curr] = *l->b; *l->b++ = t[curr]; + curr = !curr; + l = b + (rskey(t[curr])>>s&m); + } while (l != k); + *k->b++ = t[curr]; + } + for (b->b = beg, k = b + 1; k != be; ++k) k->b = (k-1)->e; } - for (k = b + 1; k != be; ++k) k->b = (k-1)->e; - b->b = beg; -} - -void rs_sort(rstype_t *beg, rstype_t *end, int n_bits, int s) -{ - if (end - beg > RS_MIN_SIZE) { - rsbucket_t *b; - int i; - b = (rsbucket_t*)alloca(sizeof(rsbucket_t) * (1< n_bits? s - n_bits : 0; - for (i = 0; i != 1< b[i].b + 1) rs_sort(b[i].b, b[i].e, n_bits, s); + if (s) { + s = s > n_bits? s - n_bits : 0; + for (k = b; k != be; ++k) { + if (k->e - k->b > RS_MIN_SIZE) rs_sort(k->b, k->e, n_bits, s); + else if (k->e - k->b > 1) rs_insertsort(k->b, k->e); } - } else if (end - beg > 1) rs_insertsort(beg, end); + } } /*************************************************