aboutsummaryrefslogtreecommitdiffstats
path: root/P1/src/reducer.c
blob: 7c5e8f221f25e416181cde135c95b5dbec628462 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "reducer.h"

finalKeyValueDS DS;

// create a key value node
finalKeyValueDS *createFinalKeyValueNode(char *word, int count){
	finalKeyValueDS *newNode = (finalKeyValueDS *)malloc (sizeof(finalKeyValueDS));
	strcpy(newNode -> key, word);
	newNode -> value = count;
	newNode -> next = NULL;
	return newNode;
}

// insert or update an key value
finalKeyValueDS *insertNewKeyValue(finalKeyValueDS *root, char *word, int count){
	finalKeyValueDS *tempNode = root;
	if(root == NULL)
		return createFinalKeyValueNode(word, count);
	while(tempNode -> next != NULL){
		if(strcmp(tempNode -> key, word) == 0){
			tempNode -> value += count;
			return root;
		}
		tempNode = tempNode -> next;
	}
	if(strcmp(tempNode -> key, word) == 0){
		tempNode -> value += count;
	} else{
		tempNode -> next = createFinalKeyValueNode(word, count);
	}
	return root;
}

// free the DS after usage. Call this once you are done with the writing of DS into file
void freeFinalDS(finalKeyValueDS *root) {
	if(root == NULL) return;

	finalKeyValueDS *tempNode = NULL;
	while (root != NULL) {
		tempNode = root;
		root = root -> next;
		free(tempNode);
	}
}

// reduce function
void reduce(char *key) {
	// Calculate the total count of values (1's) for the word from [the_word].txt
	// Store the total count in finalKeyValueDS
	// Lather, rinse, repeat for all the words
	FILE* fptr = fopen(key, "r");
	
	char word[BUFFSIZE] = ""; 
	fgets(word, BUFFSIZE, fptr); // Buffer is currently entire [the_word].txt file
	
	char *parsedKey = strtok(word, " "); // Parses input by whitespaces
	char *parsedWord = parsedKey; // Save the first token, which is the word. It's a surprise tool that will help us later.

	int count = 0;
	while(parsedKey != NULL) {
		count += atoi(parsedKey);
		parsedKey = strtok(NULL, " ");
	}

	fclose(fptr);
	insertNewKeyValue(&DS, parsedWord, count);
}

// write the contents of the final intermediate structure
// to output/ReduceOut/Reduce_reducerID.txt
void writeFinalDS(int reducerID){
	
	finalKeyValueDS *root = &DS;
	finalKeyValueDS *tempNode = root -> next;

	while(tempNode != NULL) {
		// Shove word and number of occurances in a file named word.txt
		char filename[BUFFSIZE] = "";
		sprintf(filename, "output/ReduceOut/Reduce_%d.txt", reducerID);
		FILE* fptr = fopen(filename, "a");
		fprintf(fptr, "%s %d\n", tempNode -> key, tempNode -> value);
		fclose(fptr);
		tempNode = tempNode -> next;
	}
	freeFinalDS(root -> next);
}

int main(int argc, char *argv[]) {

	if(argc < 2){
		printf("Less number of arguments.\n");
		printf("./reducer reducerID");
	}

	// ###### DO NOT REMOVE ######
	// initialize 
	int reducerID = strtol(argv[1], NULL, 10);

	// ###### DO NOT REMOVE ######
	// master will continuously send the word.txt files
	// alloted to the reducer
	char key[MAXKEYSZ];
	while(getInterData(key, reducerID))
		reduce(key);

	// You may write this logic. You can somehow store the
	// <key, value> count and write to Reduce_reducerID.txt file
	// So you may delete this function and add your logic
	writeFinalDS(reducerID);

	return 0;
}