Files
libaaruformat/src/lru.c

83 lines
2.7 KiB
C
Raw Normal View History

2022-10-02 16:05:25 +01:00
#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, 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, char* key, void* value)
{
struct CacheEntry *entry, *tmp_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)
{
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(entry);
break;
}
}
}
FORCE_INLINE char* int64_to_string(uint64_t number)
{
char* charKey;
charKey = malloc(17);
charKey[0] = (char)(number >> 60);
charKey[1] = (char)((number & 0xF00000000000000ULL) >> 56);
charKey[2] = (char)((number & 0xF0000000000000ULL) >> 52);
charKey[3] = (char)((number & 0xF000000000000ULL) >> 48);
charKey[4] = (char)((number & 0xF00000000000ULL) >> 44);
charKey[5] = (char)((number & 0xF0000000000ULL) >> 40);
charKey[6] = (char)((number & 0xF000000000ULL) >> 36);
charKey[7] = (char)((number & 0xF00000000ULL) >> 32);
charKey[8] = (char)((number & 0xF0000000ULL) >> 28);
charKey[9] = (char)((number & 0xF000000ULL) >> 24);
charKey[10] = (char)((number & 0xF00000ULL) >> 20);
charKey[11] = (char)((number & 0xF0000ULL) >> 16);
charKey[12] = (char)((number & 0xF000ULL) >> 12);
charKey[13] = (char)((number & 0xF00ULL) >> 8);
charKey[14] = (char)((number & 0xF0ULL) >> 4);
charKey[15] = (char)(number & 0xFULL);
charKey[16] = 0;
return charKey;
}
void* find_in_cache_uint64(struct CacheHeader* cache, uint64_t key)
{
return find_in_cache(cache, int64_to_string(key));
}
void add_to_cache_uint64(struct CacheHeader* cache, uint64_t key, void* value)
{
return add_to_cache(cache, int64_to_string(key), value);
}