summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby Bingham <koorogi@koorogi.info>2014-06-30 00:19:10 -0500
committerBobby Bingham <koorogi@koorogi.info>2014-06-30 00:19:10 -0500
commite0dfea0a485fbf3bdeaed3634dd65797a3c67397 (patch)
treee33b0a5bc74822f82432294b0b235cab6a8a3ff7
parent342e801b02f7d8c0ac70b18f74d2686e61f0a6ce (diff)
Use an array structure to track the temp buffer
-rw-r--r--wikisort.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/wikisort.c b/wikisort.c
index 4b01e9b..47e1def 100644
--- a/wikisort.c
+++ b/wikisort.c
@@ -168,22 +168,23 @@ void wikisort(void *unsorted, size_t nmel, size_t width, cmpfun cmp)
size_t bcount = nmel / bnmel;
size_t bwidth = bnmel * width;
- /* temporary buffer is at base. carve remainder of input into a and b subarrays.
- * the nmels for these subarrays is specified in terms of blocks. */
- size_t bufnmel = bnmel + nmel % bnmel;
- struct array a = { .base = base + width * bufnmel, .nmel = (bcount - 1) / 2 };
- struct array b = { .base = a.base + bwidth * a.nmel, .nmel = bcount - 1 - a.nmel };
+ /* temporary buffer: nmel is measured in array elements */
+ struct array buf = { .base = base, .nmel = bnmel + nmel % bnmel };
+
+ /* A and B subarrays: nmel is measured in blocks of bnmel elements each */
+ struct array a = { .base = buf.base + width * buf.nmel, .nmel = (bcount - 1) / 2 };
+ struct array b = { .base = a.base + bwidth * a.nmel, .nmel = bcount - 1 - a.nmel };
/* sort the buffer as if it were part of the a array */
- wikisort( base, nmel - b.nmel * bnmel, width, cmp);
- wikisort(b.base, b.nmel * bnmel, width, cmp);
+ wikisort(buf.base, buf.nmel + a.nmel * bnmel, width, cmp);
+ wikisort(b.base, b.nmel * bnmel, width, cmp);
/* if already sorted, nothing to do */
if (cmp(b.base - width, b.base) <= 0) return;
/* if blocks in b are all less than those in a, just need a rotate */
if (cmp(base + (nmel - 1) * width, base) <= 0) {
- rotate(base, nmel, width, a.nmel * bnmel + bufnmel);
+ rotate(base, nmel, width, a.nmel * bnmel + buf.nmel);
return;
}
@@ -205,7 +206,7 @@ void wikisort(void *unsorted, size_t nmel, size_t width, cmpfun cmp)
/* merge any previous pending as and bs */
nmel_pend_b -= offset;
if (nmel_pend_a && nmel_pend_b) {
- merge_blocks(base, penda, nmel_pend_a, nmel_pend_b, width, cmp);
+ merge_blocks(buf.base, penda, nmel_pend_a, nmel_pend_b, width, cmp);
}
nmel_pend_a = bnmel;
@@ -224,9 +225,9 @@ void wikisort(void *unsorted, size_t nmel, size_t width, cmpfun cmp)
}
if (nmel_pend_a) {
- merge_blocks(base, penda, nmel_pend_a, b.nmel * bnmel + nmel_pend_b, width, cmp);
+ merge_blocks(buf.base, penda, nmel_pend_a, b.nmel * bnmel + nmel_pend_b, width, cmp);
}
- wikisort(base, bufnmel, width, cmp);
- distribute_buffer(base, bufnmel, nmel - bufnmel, width, cmp);
+ wikisort(buf.base, buf.nmel, width, cmp);
+ distribute_buffer(buf.base, buf.nmel, nmel - buf.nmel, width, cmp);
}