summaryrefslogtreecommitdiffstats
path: root/src/mergesort.c
diff options
context:
space:
mode:
authorGravatar Gediminas Jakutis <gediminas@varciai.lt> 2021-02-21 13:16:54 +0200
committerGravatar Gediminas Jakutis <gediminas@varciai.lt> 2021-02-21 13:19:06 +0200
commit29712a5098842ea3930ec00ddd1c0b9d264ba9b5 (patch)
tree3744b445acb971342be18fa6d2c9c4c20a470e1d /src/mergesort.c
parent26ab990a747ab675bcff32a40734dcb61468f652 (diff)
downloadalgos-ld1-29712a5098842ea3930ec00ddd1c0b9d264ba9b5.tar.gz
algos-ld1-29712a5098842ea3930ec00ddd1c0b9d264ba9b5.tar.bz2
algos-ld1-29712a5098842ea3930ec00ddd1c0b9d264ba9b5.zip
in-memory array sorting: GET!
lists need a bit more work and after that, in-file should shortly follow. Signed-off-by: Gediminas Jakutis <gediminas@varciai.lt>
Diffstat (limited to 'src/mergesort.c')
-rw-r--r--src/mergesort.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/src/mergesort.c b/src/mergesort.c
index c431b31..7391544 100644
--- a/src/mergesort.c
+++ b/src/mergesort.c
@@ -5,42 +5,49 @@
#include <errno.h>
#include <stdlib.h>
#include "defs.h"
-#include "io.h"
+#include "stream.h"
#include "mergesort.h"
+static int merge(struct stream * const dest, struct stream * const A, struct stream * const B);
+
/* bottom-up variantas */
int merge_sort(struct stream * const src, struct stream * const dest)
{
int ret = 0;
- struct stream tmp[4]; /* I can't into stream reuse, hence four. A yeet, followed by a dab. */
+ struct stream tmp[4] = {0}; /* I can't into stream reuse, hence four. A yeet, followed by a dab. */
size_t i;
try(!src || !dest, err, EINVAL, "cannot sort what's not there");
- if (src->n > 1) { /* stream of size one is inherently sorted */
+ try_s((ret = stream_shallow_copy(src, dest)), err);
+
+ if (src->n > 1) {
src->split(src, tmp, tmp + 2); /* split stream in half */
- merge_sort(tmp + 1, tmp); /* recurse-sort first half */
- merge_sort(tmp + 3, tmp + 2); /* recurse-sort second half */
- merge(dest, tmp, tmp + 2); /* merge the two halves back */
- }
+ merge_sort(tmp, tmp + 1); /* recurse-sort first half */
+ merge_sort(tmp + 2, tmp + 3); /* recurse-sort second half */
+ merge(dest, tmp + 1, tmp + 3); /* merge the two halves back */
+ dest->rewind(dest);
- for (i = 0; i < (sizeof(tmp) / sizeof(*tmp)); ++i) {
- stream_close(tmp + i);
+ for (i = 0; i < (sizeof(tmp) / sizeof(*tmp)); ++i) {
+ stream_close(tmp + i);
+ }
+ } else { /* stream of size one is inherently sorted, simply src with dest */
+ *tmp = *dest;
+ *dest = *src;
+ *src = *tmp;
}
err:
return ret;
}
-int merge(struct stream * const dest, struct stream * const A, struct stream * const B)
+static int merge(struct stream * const dest, struct stream * const A, struct stream * const B)
{
int ret = 0;
struct entry_l *a;
struct entry_l *b;
- try(A->parentid != B->parentid, err, EINVAL, "cannot merge blocks: uncommon parent!");
-
a = get(A);
b = get(B);
@@ -54,7 +61,6 @@ int merge(struct stream * const dest, struct stream * const A, struct stream * c
}
}
-err:
return ret;
}