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[DIRSIZE] = "";
sprintf(filename, "output/ReduceOut/Reduce_%d.txt", reducerID);
FILE* fptr = fopen(filename, "a"); //append, not overwrite.
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;
}
|