-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
154 lines (120 loc) · 3.96 KB
/
main.c
File metadata and controls
154 lines (120 loc) · 3.96 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
* Copyright (c) 2024, Andrei Otetea <andreiotetea23@gmail.com>
* Copyright (c) 2024, Eduard Marin <marin.eduard.c@gmail.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "constants.h"
#include "load_balancer.h"
#include "lru_cache.h"
#include "utils.h"
void read_quoted_string(char *buffer, int buffer_len, int *start, int *end) {
*end = -1;
for (int i = 0; i < buffer_len && buffer[i] != '\0'; ++i) {
if (buffer[i] != '"') continue;
if (*start == -1) {
*start = i;
} else {
*end = i;
break;
}
}
}
request_type read_request_arguments(FILE *input_file, char *buffer,
int *maybe_server_id, int *maybe_cache_size,
char **maybe_doc_name,
char **maybe_doc_content) {
request_type req_type;
int word_start = -1;
int word_end = -1;
DIE(fgets(buffer, REQUEST_LENGTH + 1, input_file) == NULL,
"insufficient requests");
req_type = get_request_type(buffer);
if (req_type == ADD_SERVER) {
*maybe_server_id = atoi(buffer + strlen(ADD_SERVER_REQUEST) + 1);
*maybe_cache_size =
atoi(strchr(buffer + strlen(ADD_SERVER_REQUEST) + 1, ' '));
} else if (req_type == REMOVE_SERVER) {
*maybe_server_id = atoi(buffer + strlen(REMOVE_SERVER_REQUEST) + 1);
} else {
*maybe_doc_name = calloc(1, DOC_NAME_LENGTH + 1);
DIE(*maybe_doc_name == NULL, "calloc failed");
read_quoted_string(buffer, REQUEST_LENGTH, &word_start, &word_end);
memcpy(*maybe_doc_name, buffer + word_start + 1,
word_end - word_start - 1);
if (req_type == EDIT_DOCUMENT) {
char *tmp_buffer = buffer + word_end + 1;
*maybe_doc_content = calloc(1, DOC_CONTENT_LENGTH + 1);
DIE(*maybe_doc_content == NULL, "calloc failed");
/* Read the content, which might be a multiline quoted string */
word_start = -1;
read_quoted_string(tmp_buffer, DOC_CONTENT_LENGTH, &word_start,
&word_end);
if (word_end == -1)
strcpy(*maybe_doc_content, tmp_buffer + word_start + 1);
else
strncpy(*maybe_doc_content, tmp_buffer + word_start + 1,
word_end - word_start - 1);
while (word_end == -1) {
DIE(fgets(buffer, DOC_CONTENT_LENGTH + 1, input_file) == NULL,
"document content is not properly quoted");
read_quoted_string(buffer, DOC_CONTENT_LENGTH, &word_start,
&word_end);
memcpy(*maybe_doc_content + strlen(*maybe_doc_content), buffer,
word_end == -1 ? strlen(buffer) : (unsigned)word_end);
}
} else {
*maybe_doc_content = NULL;
}
}
return req_type;
}
void apply_requests(FILE *input_file, char *buffer, int requests_num,
bool enable_vnodes) {
char *doc_name, *doc_content;
int server_id, cache_size;
load_balancer *main = init_load_balancer(enable_vnodes);
for (int i = 0; i < requests_num; i++) {
request_type req_type =
read_request_arguments(input_file, buffer, &server_id, &cache_size,
&doc_name, &doc_content);
if (req_type == ADD_SERVER) {
DIE(cache_size < 0, "cache size must be positive");
loader_add_server(main, server_id, (unsigned int)cache_size);
} else if (req_type == REMOVE_SERVER) {
loader_remove_server(main, server_id);
} else {
request server_request = {
.type = req_type,
.doc_name = doc_name,
};
if (req_type == EDIT_DOCUMENT) {
server_request.doc_content = doc_content;
}
response *response = loader_forward_request(main, &server_request);
free(server_request.doc_name);
free(server_request.doc_content);
PRINT_RESPONSE(response);
}
}
free_load_balancer(&main);
}
int main(int argc, char **argv) {
FILE *input;
int requests_num;
bool enable_vnodes;
char buffer[REQUEST_LENGTH + 1];
if (argc < 2) {
printf("Usage: %s <input_file>\n", argv[0]);
return -1;
}
input = fopen(argv[1], "rt");
DIE(input == NULL, "missing input file");
DIE(fgets(buffer, REQUEST_LENGTH + 1, input) == 0, "empty input file");
requests_num = atoi(buffer);
enable_vnodes = strstr(buffer, "ENABLE_VNODES");
apply_requests(input, buffer, requests_num, enable_vnodes);
fclose(input);
return 0;
}