Statistics
| Branch: | Revision:

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
}