-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcache.c
More file actions
200 lines (174 loc) · 4.61 KB
/
cache.c
File metadata and controls
200 lines (174 loc) · 4.61 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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
//
// Created by Cyrus Ghazanfar and Kulvinder Lotay on 10/28/18.
//
#include "cache.h"
/* Declare head and tail nodes */
cnode_t *tail;
cnode_t *head;
/* Define cache count - items in cache */
int items_in_cache;
/* Define volatile values for concurrency protection */
volatile size_t total_cache_size;
volatile int read_count;
/* Define read and write locks */
sem_t read_lock, write_lock;
/* Construct new node */
cnode_t *new(char *host, int port, char *path, char *body, size_t size) {
cnode_t * res = Malloc(sizeof(cnode_t));
res->host = Malloc(strlen(host) + 1);
strcpy(res->host, host);
res->path = Malloc(strlen(path) + 1);
strcpy(res->path, path);
res->port = port;
res->payload = Malloc(strlen(body) + 1);
strcpy(res->payload, body);
res->size = size;
return res;
}
/* Define cache initialization function */
void cache_init() {
tail = NULL;
head = NULL;
/* Set total_cache_size, read_count, items_in_cache to 0 */
items_in_cache = 0;
read_count = 0;
total_cache_size = 0;
/* Initialize read and write locks */
Sem_init(&read_lock, 0 , 1);
Sem_init(&write_lock, 0, 1);
}
/* Define function to to check for item already in cache */
/* If item exists, return 1, else return 0 */
int compare_item(cnode_t *node, char *host, int port, char *path) {
/* Check if host matches host in memory */
if (strcasecmp(node->host, host))
return 0;
/* Check if port matches port in memory */
if (node->port != port)
return 0;
/* Check if path matches path in memory*/
if (strcasecmp(node->path, path))
return 0;
/* If all three match, return true */
return 1;
}
/* Define delete function */
void delete(cnode_t *node) {
if (head == tail) {
head = NULL;
tail = NULL;
} else if (node->prev == NULL) {
head = node->next;
(node->next)->prev = NULL;
} else if (node->next == NULL) {
tail = node->prev;
(node->prev)->next = NULL;
} else {
(node->prev)->next = node->next;
(node->next)->prev = node->prev;
}
total_cache_size -= node->size;
items_in_cache--;
}
/* Add to deque */
void add_to_deque(cnode_t *node) {
if (items_in_cache == 0) {
head = node;
tail = node;
node->next = NULL;
node->prev = NULL;
} else {
tail->next = node;
node->prev = tail;
node->next = NULL;
tail = node;
}
total_cache_size += node->size;
items_in_cache++;
}
/* Remove from deque */
void remove_from_deque() {
cnode_t * res;
if (items_in_cache == 0)
return;
else if (items_in_cache == 1) {
res = head;
head = NULL;
tail = NULL;
} else {
res = head;
(head->next)->prev = NULL;
head = head->next;
}
total_cache_size -= res->size;
items_in_cache--;
Free(res->host);
Free(res->path);
Free(res->payload);
Free(res);
}
/* Check for match in node */
cnode_t *elem_match(char *host, int port, char *path) {
cnode_t * res = tail;
for (; res != NULL; res = res->prev) {
if (compare_item(res, host, port, path)) {
return res;
}
}
return NULL;
}
/* Check cache for item */
int cache_check() {
cnode_t * block;
int count = 0;
if (items_in_cache == 0)
return 1;
if (items_in_cache == 1) {
if (head != tail) {
printf("When count === 1, head should equal tail\n");
return 0;
}
if (head->prev != NULL) {
printf("The prev of head should be NULL\n");
return 0;
}
if (tail->next != NULL) {
printf("The next of tail should be NULL\n");
return 0;
}
return 1;
}
if (tail->next != NULL) {
printf("The next of tail should be NULL\n");
return 0;
}
count++;
for (block = tail; block->prev != NULL; block = block->prev) {
count++;
if (block != (block->prev)->next) {
printf("Adjacent blocks' ptr should be consistent\n");
return 0;
}
}
if (block != head) {
printf("Head is not reachable\n");
return 0;
}
if (head->prev != NULL) {
printf("The prev of head should be NULL\n");
return 0;
}
if (count != items_in_cache) {
printf("Cache count error, count = %d, cache_count = %d\n",
count, items_in_cache);
return 0;
}
return 1;
}
/* Wrapper function for cache check */
/* If item exists in cache, exit */
void Cache_check() {
if (!cache_check())
exit(0);
return;
}