2019-05-03 15:20:47 +00:00
|
|
|
#include <uthash.h>
|
|
|
|
|
|
|
|
#include "cache.h"
|
|
|
|
|
2024-02-15 21:08:48 +00:00
|
|
|
struct cache_handle *cache_get(struct cache *c, const char *key) {
|
|
|
|
struct cache_handle *e;
|
2020-12-26 07:25:34 +00:00
|
|
|
HASH_FIND_STR(c->entries, key, e);
|
2024-02-15 20:05:09 +00:00
|
|
|
return e;
|
|
|
|
}
|
2020-12-26 07:25:34 +00:00
|
|
|
|
2024-02-16 00:31:53 +00:00
|
|
|
int cache_get_or_fetch(struct cache *c, const char *key, struct cache_handle **value,
|
|
|
|
void *user_data, cache_getter_t getter) {
|
2024-02-15 21:08:48 +00:00
|
|
|
*value = cache_get(c, key);
|
|
|
|
if (*value) {
|
|
|
|
return 0;
|
2019-05-03 15:20:47 +00:00
|
|
|
}
|
|
|
|
|
2024-02-16 00:31:53 +00:00
|
|
|
int err = getter(c, key, value, user_data);
|
2024-02-15 21:08:48 +00:00
|
|
|
assert(err <= 0);
|
|
|
|
if (err < 0) {
|
|
|
|
return err;
|
2019-05-05 23:28:22 +00:00
|
|
|
}
|
2024-02-15 21:08:48 +00:00
|
|
|
(*value)->key = strdup(key);
|
2019-05-05 23:28:22 +00:00
|
|
|
|
2024-02-15 21:08:48 +00:00
|
|
|
HASH_ADD_STR(c->entries, key, *value);
|
|
|
|
return 1;
|
2019-05-03 15:20:47 +00:00
|
|
|
}
|
|
|
|
|
2024-02-15 21:08:48 +00:00
|
|
|
static inline void
|
|
|
|
cache_invalidate_impl(struct cache *c, struct cache_handle *e, cache_free_t free_fn) {
|
2019-05-05 03:55:42 +00:00
|
|
|
free(e->key);
|
2019-05-03 15:20:47 +00:00
|
|
|
HASH_DEL(c->entries, e);
|
2024-02-15 21:08:48 +00:00
|
|
|
if (free_fn) {
|
|
|
|
free_fn(c, e);
|
|
|
|
}
|
2019-05-03 15:20:47 +00:00
|
|
|
}
|
|
|
|
|
2024-02-15 21:08:48 +00:00
|
|
|
void cache_invalidate_all(struct cache *c, cache_free_t free_fn) {
|
|
|
|
struct cache_handle *e, *tmpe;
|
2019-05-03 15:20:47 +00:00
|
|
|
HASH_ITER(hh, c->entries, e, tmpe) {
|
2024-02-15 21:08:48 +00:00
|
|
|
cache_invalidate_impl(c, e, free_fn);
|
2019-05-03 15:20:47 +00:00
|
|
|
}
|
|
|
|
}
|