summaryrefslogtreecommitdiffstats
path: root/hw3/merger.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw3/merger.c')
-rw-r--r--hw3/merger.c82
1 files changed, 76 insertions, 6 deletions
diff --git a/hw3/merger.c b/hw3/merger.c
index 32ddc9e..18f383e 100644
--- a/hw3/merger.c
+++ b/hw3/merger.c
@@ -7,9 +7,11 @@
#include <inttypes.h>
#include <pthread.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#define SORT_DATA(x) ((SortData*)(x))
@@ -22,10 +24,9 @@ typedef struct {
#define MERGE_DATA(x) ((MergeData*)(x))
typedef struct {
int_least32_t* s;
- int start1;
- int len1;
- int start2;
- int len2;
+ int start;
+ int mid;
+ int end;
} MergeData;
static int_least32_t read_32b_integer (FILE* fp) {
@@ -62,7 +63,54 @@ static void* task_sort (void* sd_generic) {
return NULL;
}
-static void* task_merge (void* sd_generic) {
+static void* task_merge (void* md_generic) {
+ MergeData* md = MERGE_DATA (md_generic);
+ int_least32_t* t = xmalloc (sizeof (int_least32_t) * (md->end - md->start));
+ int_least32_t* s = md->s;
+
+ int i = md->start, iend = md->mid;
+ int j = md->mid, jend = md->end;
+ int k = 0;
+
+ int dup_count = 0;
+ bool is_dup;
+
+ while (i < iend && j < jend) {
+ if (s[i] > s[j]) {
+ t[k] = s[j];
+ j++, k++;
+ is_dup = false;
+ } else if (s[i] < s[j]) {
+ t[k] = s[i];
+ i++, k++;
+ is_dup = false;
+ } else {
+ if (!is_dup) {
+ dup_count++;
+ }
+ t[k] = s[i];
+ i++, k++;
+ t[k] = s[j];
+ j++, k++;
+ is_dup = true;
+ }
+ }
+
+ while (i < iend) {
+ t[k] = s[i];
+ i++, k++;
+ }
+ while (j < jend) {
+ t[k] = s[j];
+ j++, k++;
+ }
+
+ memcpy (s + md->start, t, sizeof (int_least32_t) * (md->end - md->start));
+ fprintf (msg_dev, "Merged %d and %d elements with %d duplicates.\n",
+ md->mid - md->start, md->end - md->mid, dup_count);
+
+ free (t);
+ return NULL;
}
int main (int argc, char* argv[]) {
@@ -123,7 +171,29 @@ int main (int argc, char* argv[]) {
/* Merge */
MergeData* md_list = xmalloc (sizeof (MergeData) * t);
-
+ for (long mss = ss; mss < n; mss *= 2) {
+ t = n / mss;
+ if (t * mss != n) {
+ t++;
+ }
+ t /= 2;
+ for (int i = 0, st = 0; i < t; i++, st += mss * 2) {
+ md_list[i] = (MergeData) {
+ .s = s,
+ .start = st,
+ .mid = st + mss,
+ .end = (st + mss * 2 > n) ? n : (st + mss * 2)
+ };
+ r = pthread_create (&tid[i], NULL, task_merge, &md_list[i]);
+ if (r != 0) {
+ perror ("merge: pthread_create");
+ exit (5);
+ }
+ }
+ for (int i = 0; i < t; i++) {
+ pthread_join (tid[i], NULL);
+ }
+ }
/* Output */
for (int i = 0; i < n; i++) {