-
Notifications
You must be signed in to change notification settings - Fork 0
/
blockcache.c
242 lines (207 loc) · 4.68 KB
/
blockcache.c
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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/*
* Generic singly linked list implementation.
*
*/
#include "blockcache.h"
#include <stdlib.h>
#include <stdio.h>
#define LIMIT 50
//Items in the blockcache
struct blockcacheNode {
void* data; //Pointer to item
int key;
struct blockcacheNode* next; //Next blockcacheNode in blockcache
};
//blockcache
struct blockcache {
int size; //Size of blockcache
struct blockcacheNode *front; //First blockcache in queue
};
/*
* Return an empty blockcache.
* blockcache will be size 0.
*/
blockcache_t blockcache_new()
{
blockcache_t blockcache = (blockcache_t) malloc(sizeof(struct blockcache));
//Makes sure blockcache was made sucessfully
if (blockcache == NULL)
return NULL;
//else
blockcache->size = 0;
blockcache->front = NULL;
return (blockcache_t) blockcache;
}
/*
* Prepend a void* to a blockcache (both specifed as parameters). Return
* 0 (success) or -1 (failure).
*/
int blockcache_insert(blockcache_t blockcache, int key, void* item)
{
blockcacheNode_t listNode = (blockcacheNode_t) malloc(sizeof(struct blockcacheNode));
//Check that blockcache and item exists and that listNode was properly created
if (blockcache != NULL && item != NULL && listNode != NULL)
{
listNode->data = item;
listNode->key = key;
listNode->next = blockcache->front;
blockcache->front = listNode;
//Reflect that blockcache grew in size
blockcache->size++;
if (blockcache->size > LIMIT)
{
blockcache_delete_last(blockcache);
}
return 0;
}
//else
return -1;
}
/*
* Dequeue and return the first void* from the blockcache or NULL if blockcache
* is empty. Return 0 (success) or -1 (failure).
*/
int blockcache_dequeue(blockcache_t blockcache, void** item)
{
blockcacheNode_t frontNode;
//Check that blockcache and item exists
if (blockcache != NULL && item != NULL)
{
frontNode = blockcache->front;
if (frontNode != NULL)
{
*item = blockcache->front->data;
//Reassign front
blockcache->front = blockcache->front->next;
free(frontNode);
//Reflect that blockcache shrunk in size
blockcache->size--;
return 0;
}
}
//else return null and -1 if the blockcache is empty or item doesnt exist
*item = NULL;
return -1;
}
/*
* Free the blockcache and return 0 (success) or -1 (failure).
*/
int blockcache_free(blockcache_t blockcache)
{
blockcacheNode_t frontNode;
blockcacheNode_t tempNode;
//Make sure blockcache exists
if (blockcache != NULL)
{
frontNode = blockcache->front;
while (frontNode != NULL)
{
tempNode = frontNode;
frontNode = frontNode->next;
free(tempNode);
}
free(blockcache);
return 0;
}
//else
return -1;
}
/*
* Check if the blockcache is empty. Return 1 (empty) 0 (not empty)
*/
int blockcache_isEmpty(blockcache_t blockcache)
{
return (blockcache == NULL || blockcache->size == 0);
}
/*
* Return the number of items in the blockcache.
*/
int blockcache_length(blockcache_t blockcache)
{
//If queue is not empty
if (blockcache != NULL)
return blockcache->size;
//else
return 0;
}
void blockcache_delete_last(blockcache_t blockcache)
{
blockcacheNode_t lastPtr = NULL;
blockcacheNode_t currentPtr;
blockcacheNode_t secondLastPtr = NULL;
if (blockcache != NULL && blockcache->size > 2)
{
currentPtr = blockcache->front;
while (currentPtr != NULL)
{
secondLastPtr = lastPtr;
lastPtr = currentPtr;
currentPtr = currentPtr->next;
}
secondLastPtr->next = NULL;
free(lastPtr->data);
free(lastPtr);
blockcache->size--;
}
}
/*
* Delete the specified item from the given blockcache.
* Return 0 on success. Return -1 on error.
*/
int blockcache_delete(blockcache_t blockcache, int id)
{
blockcacheNode_t nodeToDelete;
blockcacheNode_t lastPtr = NULL;
blockcacheNode_t currentPtr;
if (blockcache != NULL)
{
currentPtr = blockcache->front;
while (currentPtr != NULL)
{
//Item Found
if(currentPtr->key == id)
{
if (lastPtr != NULL)
lastPtr->next = currentPtr->next;
if (blockcache->front == currentPtr)
blockcache->front = currentPtr->next;
nodeToDelete = currentPtr;
currentPtr = currentPtr->next;
blockcache->size--;
free(nodeToDelete);
return 0;
}
//Item not found
else
{
lastPtr = currentPtr;
currentPtr = currentPtr->next;
}
}
}
return -1;
}
int blockcache_get(blockcache_t list, int id, void **item)
{
blockcacheNode_t currentPtr;
if (list != NULL && list->size > 0)
{
currentPtr = list->front;
while (currentPtr != NULL)
{
//Item Found
if(currentPtr->key == id)
{
*item = currentPtr->data;
return 1;
}
//Item not found
else
{
currentPtr = currentPtr->next;
}
}
}
*item = NULL;
return -1;
}