Loading...
Searching...
No Matches
lru.c
Go to the documentation of this file.
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <uthash.h>
#include <aaruformat.h>
// this is an example of how to do a LRU cache in C using uthash
// http://uthash.sourceforge.net/
// by Jehiah Czebotar 2011 - jehiah@gmail.com
// this code is in the public domain http://unlicense.org/
void *find_in_cache(struct CacheHeader *cache, const char *key)
{
struct CacheEntry *entry;
HASH_FIND_STR(cache->cache, key, entry);
if(entry)
{
// remove it (so the subsequent add will throw it on the front of the list)
HASH_DELETE(hh, cache->cache, entry);
HASH_ADD_KEYPTR(hh, cache->cache, entry->key, strlen(entry->key), entry);
return entry->value;
}
return NULL;
}
void add_to_cache(struct CacheHeader *cache, const char *key, void *value)
{
struct CacheEntry *entry;
// TODO: Is this needed or we're just losing cycles? uthash does not free the entry
entry = malloc(sizeof(struct CacheEntry));
entry->key = strdup(key);
entry->value = value;
HASH_ADD_KEYPTR(hh, cache->cache, entry->key, strlen(entry->key), entry);
// prune the cache to MAX_CACHE_SIZE
if(HASH_COUNT(cache->cache) >= cache->max_items)
{
struct CacheEntry *tmp_entry;
HASH_ITER(hh, cache->cache, entry, tmp_entry)
{
// prune the first entry (loop is based on insertion order so this deletes the oldest item)
HASH_DELETE(hh, cache->cache, entry);
free(entry->key);
// Free the cached value if a free function is registered
if(cache->free_func && entry->value)
cache->free_func(entry->value);
free(entry);
break;
}
}
}
FORCE_INLINE char *uint64_to_string(const uint64_t number)
{
char *char_key = malloc(17); // 16 hex digits + null terminator
if(!char_key) return NULL;
snprintf(char_key, 17, "%016" PRIX64, number);
return char_key;
}
void *find_in_cache_uint64(struct CacheHeader *cache, const uint64_t key)
{
char *char_key = uint64_to_string(key);
if(!char_key) return NULL;
void *result = find_in_cache(cache, char_key);
free(char_key); // Free the temporary string to prevent memory leak
return result;
}
void add_to_cache_uint64(struct CacheHeader *cache, const uint64_t key, void *value)
{
char *char_key = uint64_to_string(key);
if(!char_key) return;
add_to_cache(cache, char_key, value);
free(char_key); // Free the temporary string (add_to_cache makes its own copy with strdup)
}
void free_cache(struct CacheHeader *cache)
{
struct CacheEntry *entry, *tmp;
if(!cache || !cache->cache) return;
HASH_ITER(hh, cache->cache, entry, tmp)
{
HASH_DELETE(hh, cache->cache, entry);
free(entry->key);
// Free the cached value if a free function is registered
if(cache->free_func && entry->value)
cache->free_func(entry->value);
free(entry);
}
cache->cache = NULL;
}
aaruformat.h
FORCE_INLINE
#define FORCE_INLINE
Definition decls.h:64
add_to_cache_uint64
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:113
free_cache
void free_cache(struct CacheHeader *cache)
Frees all entries in the cache and clears it.
Definition lru.c:130
add_to_cache
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
find_in_cache
void * find_in_cache(struct CacheHeader *cache, const char *key)
Finds a value in the cache by string key.
Definition lru.c:24
find_in_cache_uint64
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:93
CacheEntry
Single hash entry in the in-memory cache.
Definition lru.h:27
CacheEntry::value
void * value
Opaque value pointer associated with key (not freed automatically on eviction/clear).
Definition lru.h:29
CacheEntry::hh
UT_hash_handle hh
uthash handle linking this entry into the hash table (must remain last or per uthash docs).
Definition lru.h:30
CacheEntry::key
char * key
Null-terminated key string (unique within the cache). May encode numeric keys.
Definition lru.h:28
CacheHeader
Cache top-level descriptor encapsulating the hash table root and capacity limit.
Definition lru.h:46
CacheHeader::cache
struct CacheEntry * cache
Hash root (uthash). NULL when empty.
Definition lru.h:48
CacheHeader::max_items
uint64_t max_items
Hard limit for number of entries (policy: enforce/ignore depends on implementation).
Definition lru.h:47
CacheHeader::free_func
void(* free_func)(void *)
Optional callback to free cached values. NULL if values don't need freeing.
Definition lru.h:49