libaaruformat 1.0
Aaru Data Preservation Suite - Format Library
Loading...
Searching...
No Matches
lru.c
Go to the documentation of this file.
1#include <inttypes.h>
2#include <stddef.h>
3#include <stdint.h>
4#include <stdlib.h>
5#include <string.h>
6#include <uthash.h>
7
8#include <aaruformat.h>
9
10// this is an example of how to do a LRU cache in C using uthash
11// http://uthash.sourceforge.net/
12// by Jehiah Czebotar 2011 - jehiah@gmail.com
13// this code is in the public domain http://unlicense.org/
14
24void *find_in_cache(struct CacheHeader *cache, const char *key)
25{
26 struct CacheEntry *entry;
27 HASH_FIND_STR(cache->cache, key, entry);
28 if(entry)
29 {
30 // remove it (so the subsequent add will throw it on the front of the list)
31 HASH_DELETE(hh, cache->cache, entry);
32 HASH_ADD_KEYPTR(hh, cache->cache, entry->key, strlen(entry->key), entry);
33 return entry->value;
34 }
35 return NULL;
36}
37
47void add_to_cache(struct CacheHeader *cache, const char *key, void *value)
48{
49 struct CacheEntry *entry;
50 // TODO: Is this needed or we're just losing cycles? uthash does not free the entry
51 entry = malloc(sizeof(struct CacheEntry));
52 entry->key = strdup(key);
53 entry->value = value;
54 HASH_ADD_KEYPTR(hh, cache->cache, entry->key, strlen(entry->key), entry);
55
56 // prune the cache to MAX_CACHE_SIZE
57 if(HASH_COUNT(cache->cache) >= cache->max_items)
58 {
59 struct CacheEntry *tmp_entry;
60 HASH_ITER(hh, cache->cache, entry, tmp_entry)
61 {
62 // prune the first entry (loop is based on insertion order so this deletes the oldest item)
63 HASH_DELETE(hh, cache->cache, entry);
64 free(entry->key);
65 free(entry);
66 break;
67 }
68 }
69}
70
71FORCE_INLINE char *uint64_to_string(const uint64_t number)
72{
73 char *char_key = malloc(17); // 16 hex digits + null terminator
74 if(!char_key) return NULL;
75 snprintf(char_key, 17, "%016" PRIX64, number);
76 return char_key;
77}
78
88void *find_in_cache_uint64(struct CacheHeader *cache, const uint64_t key)
89{
90 return find_in_cache(cache, uint64_to_string(key));
91}
92
102void add_to_cache_uint64(struct CacheHeader *cache, const uint64_t key, void *value)
103{
104 return add_to_cache(cache, uint64_to_string(key), value);
105}
#define FORCE_INLINE
Definition decls.h:63
void add_to_cache_uint64(struct CacheHeader *cache, const uint64_t key, void *value)
Adds a value to the cache with a uint64_t key, using string conversion.
Definition lru.c:102
void add_to_cache(struct CacheHeader *cache, const char *key, void *value)
Adds a value to the cache with a string key, pruning if necessary.
Definition lru.c:47
void * find_in_cache(struct CacheHeader *cache, const char *key)
Finds a value in the cache by string key.
Definition lru.c:24
void * find_in_cache_uint64(struct CacheHeader *cache, const uint64_t key)
Finds a value in the cache by uint64_t key, using string conversion.
Definition lru.c:88
Single hash entry in the in-memory cache.
Definition lru.h:27
void * value
Opaque value pointer associated with key (not freed automatically on eviction/clear).
Definition lru.h:29
UT_hash_handle hh
uthash handle linking this entry into the hash table (must remain last or per uthash docs).
Definition lru.h:30
char * key
Null-terminated key string (unique within the cache). May encode numeric keys.
Definition lru.h:28
Cache top-level descriptor encapsulating the hash table root and capacity limit.
Definition lru.h:46
struct CacheEntry * cache
Hash root (uthash). NULL when empty.
Definition lru.h:48
uint64_t max_items
Hard limit for number of entries (policy: enforce/ignore depends on implementation).
Definition lru.h:47