Project

General

Profile

Statistics
| Branch: | Revision:

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
}