Sorting output
This commit is contained in:
+104
-39
@@ -187,54 +187,70 @@ void *receiverFunc(void *args)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void map(size_t worker_count, char **worker_ports, char *filename){
|
||||
void map(size_t worker_count, char **worker_ports, char *filename) {
|
||||
FILE *fp = fopen(filename, "r");
|
||||
char *file_content_chunks;
|
||||
int worker_index = 0;
|
||||
int thread_count = 0;
|
||||
if (!fp) {
|
||||
perror("[MAIN - map] Failed to open file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pthread_t *threads = (pthread_t*)malloc(sizeof(pthread_t) * worker_count);
|
||||
if(!threads){
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size_t file_size = ftell(fp);
|
||||
rewind(fp);
|
||||
|
||||
size_t worker_index = 0;
|
||||
size_t thread_count = 0;
|
||||
|
||||
pthread_t *threads = (pthread_t*)malloc(sizeof(pthread_t) * worker_count * 2);
|
||||
if (!threads) {
|
||||
perror("[MAIN - map] Failed to allocate memory for threads");
|
||||
fclose(fp);
|
||||
pthread_mutex_destroy(&words_mutex);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (thread_count < worker_count && (file_content_chunks = get_file_content(fp)) != NULL)
|
||||
{
|
||||
char buffer[MESSAGE_LENGTH + 1];
|
||||
|
||||
while (!feof(fp)) {
|
||||
size_t bytes_read = fread(buffer, sizeof(char), MESSAGE_LENGTH, fp);
|
||||
if (bytes_read == 0) break;
|
||||
|
||||
buffer[bytes_read] = '\0';
|
||||
|
||||
THREAD_ARGS *args = (THREAD_ARGS*)malloc(sizeof(THREAD_ARGS));
|
||||
if(!args){
|
||||
if (!args) {
|
||||
perror("[MAIN - map] Failed to allocate memory for args");
|
||||
free(threads);
|
||||
fclose(fp);
|
||||
pthread_mutex_destroy(&words_mutex);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
args->port = atol(worker_ports[worker_index]);
|
||||
args->data = strdup(file_content_chunks);
|
||||
args->data = strdup(buffer);
|
||||
args->type = MAP;
|
||||
|
||||
if(pthread_create(&threads[thread_count], NULL, receiverFunc, (void*)args) != 0){
|
||||
if (pthread_create(&threads[thread_count], NULL, receiverFunc, (void*)args) != 0) {
|
||||
perror("[MAIN - map] Failed to create thread");
|
||||
free(args->data);
|
||||
free(args);
|
||||
continue;
|
||||
}
|
||||
|
||||
free(file_content_chunks);
|
||||
worker_index++;
|
||||
worker_index = (worker_index + 1) % worker_count;
|
||||
thread_count++;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
// wait for workers to finish
|
||||
for(int i = 0; i < thread_count; i++){
|
||||
for (size_t i = 0; i < thread_count; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
free(threads);
|
||||
}
|
||||
|
||||
|
||||
char *extract_reduce_string(const char * toExtract){
|
||||
if(!toExtract) return NULL;
|
||||
size_t toExtract_len = strlen(toExtract);
|
||||
@@ -253,54 +269,66 @@ char *extract_reduce_string(const char * toExtract){
|
||||
return extracted;
|
||||
}
|
||||
|
||||
void reduce(char *toReduce, size_t worker_count, char **worker_ports){
|
||||
pthread_t *threads = malloc(sizeof(pthread_t) * worker_count);
|
||||
if(!threads){
|
||||
perror("[MAIN- reduce] Failed to allocate memory for threads");
|
||||
|
||||
void reduce(char *toReduce, size_t worker_count, char **worker_ports) {
|
||||
if (!toReduce || worker_count == 0) {
|
||||
fprintf(stderr, "[MAIN - reduce] Invalid input parameters.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_t *threads = malloc(sizeof(pthread_t) * worker_count * 2);
|
||||
if (!threads) {
|
||||
perror("[MAIN - reduce] Failed to allocate memory for threads");
|
||||
pthread_mutex_destroy(&words_mutex);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
size_t toReduce_len = strlen(toReduce);
|
||||
size_t offset = 0;
|
||||
size_t worker_index = 0;
|
||||
size_t thread_count = 0;
|
||||
char *extraction_ptr = toReduce;
|
||||
|
||||
for(int i = 0; i < worker_count; i++){
|
||||
while (offset < toReduce_len) {
|
||||
size_t chunk_size = (toReduce_len - offset) >= MESSAGE_LENGTH ? MESSAGE_LENGTH : (toReduce_len - offset);
|
||||
|
||||
THREAD_ARGS *args = (THREAD_ARGS*)malloc(sizeof(THREAD_ARGS));
|
||||
if(!args){
|
||||
if (!args) {
|
||||
perror("[MAIN - reduce] Failed to allocate memory for args");
|
||||
free(threads);
|
||||
pthread_mutex_destroy(&words_mutex);
|
||||
exit(1);
|
||||
}
|
||||
args->port = atol(worker_ports[i]);
|
||||
args->data = extract_reduce_string(extraction_ptr);
|
||||
|
||||
args->port = atol(worker_ports[worker_index]);
|
||||
args->data = strndup(toReduce + offset, chunk_size);
|
||||
args->type = RED;
|
||||
|
||||
if (!args->data) {
|
||||
fprintf(stderr, "[MAIN - reduce] Warning: extract_reduce_string() returned NULL\n");
|
||||
perror("[MAIN - reduce] Failed to allocate memory for chunk data");
|
||||
free(args);
|
||||
continue;
|
||||
}
|
||||
|
||||
extraction_ptr = toReduce + strlen(args->data);
|
||||
|
||||
if(pthread_create(&threads[thread_count], NULL, receiverFunc, (void*)args) != 0){
|
||||
if (pthread_create(&threads[thread_count], NULL, receiverFunc, (void*)args) != 0) {
|
||||
perror("[MAIN - reduce] Failed to create thread");
|
||||
free(args->data); // NULL frees are safe
|
||||
free(args->data);
|
||||
free(args);
|
||||
continue;
|
||||
}
|
||||
|
||||
offset += chunk_size;
|
||||
worker_index = (worker_index + 1) % worker_count;
|
||||
thread_count++;
|
||||
}
|
||||
|
||||
// wait for workers to finish
|
||||
for(int i = 0; i < thread_count; i++){
|
||||
for (size_t i = 0; i < thread_count; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
free(threads);
|
||||
}
|
||||
|
||||
|
||||
void rip(size_t worker_count, char **worker_ports){
|
||||
pthread_t *threads = malloc(sizeof(pthread_t) * worker_count);
|
||||
if(!threads){
|
||||
@@ -346,17 +374,53 @@ void rip(size_t worker_count, char **worker_ports){
|
||||
free(threads);
|
||||
}
|
||||
|
||||
void print_words_list(char *list){
|
||||
key_value_pair *kv, *head = NULL, *tail = NULL;
|
||||
extract_key_value_pairs(list, &head, &tail, false);
|
||||
kv = head;
|
||||
int qsort_sort_comparer(const void *kv1, const void *kv2){
|
||||
key_value_pair *k1 = *(key_value_pair**)kv1;
|
||||
key_value_pair *k2 = *(key_value_pair**)kv2;
|
||||
|
||||
printf("word,frequency\n");
|
||||
while(kv){
|
||||
printf("%s,%s\n", kv->key, kv->value);
|
||||
kv = kv->next;
|
||||
if (!k1->value) return 1;
|
||||
if (!k2->value) return -1;
|
||||
|
||||
int freq1 = atol(k1->value);
|
||||
int freq2 = atol(k2->value);
|
||||
|
||||
if(freq1 != freq2) return freq2 - freq1;
|
||||
return strcmp(k1->key, k2->key);
|
||||
}
|
||||
|
||||
void print_words_list(char *list){
|
||||
key_value_pair *head = NULL, *tail = NULL;
|
||||
extract_key_value_pairs(list, &head, &tail, false);
|
||||
|
||||
size_t count = 0;
|
||||
for (key_value_pair *it = head; it != NULL; it = it->next) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
printf("word,frequency\n");
|
||||
return;
|
||||
}
|
||||
|
||||
key_value_pair **kv_array = malloc(count * sizeof(key_value_pair *));
|
||||
if (!kv_array) {
|
||||
perror("[MAIN - print_words_list] Failed to allocate memory for sorting");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t index = 0;
|
||||
for (key_value_pair *it = head; it != NULL; it = it->next) {
|
||||
kv_array[index++] = it;
|
||||
}
|
||||
|
||||
qsort(kv_array, count, sizeof(key_value_pair*), qsort_sort_comparer);
|
||||
|
||||
printf("word,frequency\n");
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
printf("%s,%s\n", kv_array[i]->key, kv_array[i]->value);
|
||||
}
|
||||
|
||||
free(kv_array);
|
||||
free_key_value_pairs(&head, &tail);
|
||||
}
|
||||
|
||||
@@ -390,6 +454,7 @@ int main(const int argc, char **argv) {
|
||||
rip(argc - 2, argv + 2);
|
||||
|
||||
// print words_list
|
||||
// TODO: sort by frequency and alphabetically
|
||||
print_words_list(word_list_reduced);
|
||||
free(word_list_reduced);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user