mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2025-12-16 19:24:40 +00:00
104 lines
3.3 KiB
C
104 lines
3.3 KiB
C
#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/
|
|
|
|
/**
|
|
* @brief Finds a value in the cache by string key.
|
|
*
|
|
* Searches for a value in the cache using a string key and moves it to the front if found.
|
|
*
|
|
* @param cache Pointer to the cache header.
|
|
* @param key String key to search for.
|
|
* @return Pointer to the value if found, or NULL if not found.
|
|
*/
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* @brief Adds a value to the cache with a string key, pruning if necessary.
|
|
*
|
|
* Adds a new entry to the cache. If the cache exceeds its maximum size, prunes the least recently used entry.
|
|
*
|
|
* @param cache Pointer to the cache header.
|
|
* @param key String key to add.
|
|
* @param value Pointer to the value to store.
|
|
*/
|
|
void add_to_cache(struct CacheHeader *cache, const 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 *uint64_to_string(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;
|
|
}
|
|
|
|
/**
|
|
* @brief Finds a value in the cache by uint64_t key, using string conversion.
|
|
*
|
|
* Converts the uint64_t key to a string and searches for the entry in the cache.
|
|
*
|
|
* @param cache Pointer to the cache header.
|
|
* @param key 64-bit integer key to search for.
|
|
* @return Pointer to the value if found, or NULL if not found.
|
|
*/
|
|
void *find_in_cache_uint64(struct CacheHeader *cache, uint64_t key)
|
|
{
|
|
return find_in_cache(cache, uint64_to_string(key));
|
|
}
|
|
|
|
/**
|
|
* @brief Adds a value to the cache with a uint64_t key, using string conversion.
|
|
*
|
|
* Converts the uint64_t key to a string and adds the entry to the cache.
|
|
*
|
|
* @param cache Pointer to the cache header.
|
|
* @param key 64-bit integer key to add.
|
|
* @param value Pointer to the value to store.
|
|
*/
|
|
void add_to_cache_uint64(struct CacheHeader *cache, uint64_t key, void *value)
|
|
{
|
|
return add_to_cache(cache, uint64_to_string(key), value);
|
|
} |