root / mainbox / cache.c @ 88570136
History | View | Annotate | Download (2.15 KB)
1 |
#include "cache.h" |
---|---|
2 |
#include "log.h" |
3 |
#include <stdlib.h> |
4 |
#include <time.h> |
5 |
|
6 |
struct entry_t {
|
7 |
unsigned int key; |
8 |
unsigned int value; |
9 |
time_t retrieved; |
10 |
struct entry_t *next;
|
11 |
}; |
12 |
|
13 |
static struct entry_t *cache[CACHE_SIZE]; |
14 |
static int n_entries; |
15 |
|
16 |
static void cache_remove_lru() { |
17 |
struct entry_t *entry, **ptr;
|
18 |
struct entry_t *lru, **lru_ptr;
|
19 |
int i;
|
20 |
|
21 |
lru = NULL;
|
22 |
for (i = 0; i < CACHE_SIZE; i++) { |
23 |
ptr = &cache[i]; |
24 |
for (entry = cache[i]; entry; entry = entry->next) {
|
25 |
if (lru == NULL || entry->retrieved < lru->retrieved) { |
26 |
lru = entry; |
27 |
lru_ptr = ptr; |
28 |
} |
29 |
ptr = &entry->next; |
30 |
} |
31 |
} |
32 |
|
33 |
if (lru != NULL) { |
34 |
*lru_ptr = lru->next; |
35 |
free(lru); |
36 |
n_entries--; |
37 |
} |
38 |
} |
39 |
|
40 |
void cache_foreach(cache_func f) {
|
41 |
struct entry_t *entry;
|
42 |
int i;
|
43 |
|
44 |
for (i = 0; i < CACHE_SIZE; i++) { |
45 |
for (entry = cache[i]; entry; entry = entry->next)
|
46 |
f(entry->key); |
47 |
} |
48 |
} |
49 |
|
50 |
void cache_clear() {
|
51 |
struct entry_t *entry, *next;
|
52 |
int i;
|
53 |
|
54 |
for (i = 0; i < CACHE_SIZE; i++) { |
55 |
for (entry = cache[i]; entry; entry = next) {
|
56 |
next = entry->next; |
57 |
free(entry); |
58 |
} |
59 |
cache[i] = NULL;
|
60 |
} |
61 |
|
62 |
n_entries = 0;
|
63 |
} |
64 |
|
65 |
struct entry_t *cache_find(unsigned int key) { |
66 |
struct entry_t *entry;
|
67 |
|
68 |
for (entry = cache[key % CACHE_SIZE]; entry; entry = entry->next) {
|
69 |
if (entry->key == key) {
|
70 |
entry->retrieved = time(NULL);
|
71 |
return entry;
|
72 |
} |
73 |
} |
74 |
|
75 |
return NULL; |
76 |
} |
77 |
|
78 |
void cache_add(unsigned int key, unsigned int value) { |
79 |
struct entry_t *entry;
|
80 |
int i;
|
81 |
|
82 |
entry = malloc(sizeof(struct entry_t)); |
83 |
if (!entry) {
|
84 |
log_print("ERROR: Out of memory");
|
85 |
return;
|
86 |
} |
87 |
|
88 |
if (n_entries == CACHE_MAX_ENTRIES) {
|
89 |
cache_remove_lru(); |
90 |
} |
91 |
n_entries++; |
92 |
|
93 |
i = key % CACHE_SIZE; |
94 |
entry->key = key; |
95 |
entry->value = value; |
96 |
entry->next = cache[i]; |
97 |
cache[i] = entry; |
98 |
} |
99 |
|
100 |
int cache_lookup(unsigned int key, unsigned int *value) { |
101 |
struct entry_t *entry;
|
102 |
|
103 |
entry = cache_find(key); |
104 |
if (entry) {
|
105 |
*value = entry->value; |
106 |
return 1; |
107 |
} else
|
108 |
return 0; |
109 |
} |
110 |
|
111 |
void cache_update(unsigned int key, unsigned int value) { |
112 |
struct entry_t *entry;
|
113 |
|
114 |
entry = cache_find(key); |
115 |
if (entry)
|
116 |
entry->value = value; |
117 |
else
|
118 |
cache_add(key, value); |
119 |
} |