-
Notifications
You must be signed in to change notification settings - Fork 0
/
cache.c
146 lines (130 loc) · 3.04 KB
/
cache.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
#include "cache.h"
#define CACHE_SIZE 2
int mod = 100007;
int hash[100007]={-1};
int cache_size = 0;
int djb2Hash(const char *str)
{
int hash = 5381;
int c;
while ((c = *str++))
{
hash = ((hash << 5) + hash) + c; // hash * 33 + c
hash %= mod;
}
// printf("%d\n", hash);
return hash % mod;
}
// Function to create a new cache node
cache *createCacheNode(const char *path, int server_num)
{
cache *newNode = (cache *)malloc(sizeof(cache));
if (newNode != NULL)
{
strncpy(newNode->path, path, 1024 - 1);
newNode->path[1024 - 1] = '\0'; // Ensure null-terminated string
newNode->server_num = server_num;
newNode->next = NULL;
}
return newNode;
}
// Function to insert a new cache node at the beginning of the linked list
cache *insertCacheNode(const char *path, int server_num)
{
cache *newNode = createCacheNode(path, server_num);
if (newNode != NULL)
{
newNode->next = head;
head = newNode;
}
cache_size++;
return head;
}
cache *deleteLastElement()
{
if (head == NULL)
{
// List is empty
return NULL;
}
if (head->next == NULL)
{
// Only one element in the list
free(head);
return NULL;
}
cache *current = head;
while (current->next->next != NULL)
{
current = current->next;
}
hash[djb2Hash(current->next->path)] = -1;
cache_size--;
free(current->next);
current->next = NULL;
return head;
}
cache *insert_cache(const char *path, int server_num)
{
if (cache_size == CACHE_SIZE)
{
head = deleteLastElement(head);
}
head = insertCacheNode(path, server_num);
hash[djb2Hash(path)] = server_num;
return head;
}
cache *deleteNodeByPath(const char *pathToDelete)
{
cache *current = head;
cache *prev = NULL;
while (current != NULL)
{
if (strcmp(current->path, pathToDelete) == 0)
{
// Node with the specified path found
if (prev == NULL)
{
// Node to delete is the head
head = current->next;
}
else
{
// Update the previous node's next pointer
prev->next = current->next;
}
// Free the node
free(current);
return head;
}
// Move to the next node
prev = current;
current = current->next;
}
// Node with the specified path not found
return head;
}
void printCacheList()
{
cache *current = head;
while (current != NULL)
{
printf("Path: %s, Server Number: %d\n", current->path, current->server_num);
current = current->next;
}
}
int get_cache(char *path)
{
if (hash[djb2Hash(path)] != -1)
{
printf("Cache hit\n");
deleteNodeByPath(path);
head = insertCacheNode(path, hash[djb2Hash(path)]);
return hash[djb2Hash(path)];
}
else
{
printf("Cache miss\n");
return -1;
}
}