root / mainbox / cache.c @ 88570136
History | View | Annotate | Download (2.15 KB)
1 | cc7646f9 | Tom Mullins | #include "cache.h" |
---|---|---|---|
2 | #include "log.h" |
||
3 | #include <stdlib.h> |
||
4 | 88570136 | Tom Mullins | #include <time.h> |
5 | cc7646f9 | Tom Mullins | |
6 | struct entry_t {
|
||
7 | unsigned int key; |
||
8 | unsigned int value; |
||
9 | time_t retrieved; |
||
10 | struct entry_t *next;
|
||
11 | }; |
||
12 | |||
13 | 88570136 | Tom Mullins | 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 | cc7646f9 | Tom Mullins | |
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 | 88570136 | Tom Mullins | |
62 | n_entries = 0;
|
||
63 | cc7646f9 | Tom Mullins | } |
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 | 88570136 | Tom Mullins | if (entry->key == key) {
|
70 | entry->retrieved = time(NULL);
|
||
71 | cc7646f9 | Tom Mullins | return entry;
|
72 | 88570136 | Tom Mullins | } |
73 | cc7646f9 | Tom Mullins | } |
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 | 88570136 | Tom Mullins | log_print("ERROR: Out of memory");
|
85 | cc7646f9 | Tom Mullins | return;
|
86 | } |
||
87 | |||
88 | 88570136 | Tom Mullins | if (n_entries == CACHE_MAX_ENTRIES) {
|
89 | cache_remove_lru(); |
||
90 | } |
||
91 | n_entries++; |
||
92 | |||
93 | cc7646f9 | Tom Mullins | 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 | } |