Add a general key-value caching framework
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
be673f93c6
commit
c08fd08ea4
|
@ -0,0 +1,62 @@
|
||||||
|
#include <uthash.h>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "cache.h"
|
||||||
|
|
||||||
|
struct cache_entry {
|
||||||
|
char *key;
|
||||||
|
void *value;
|
||||||
|
UT_hash_handle hh;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cache {
|
||||||
|
cache_getter_t getter;
|
||||||
|
cache_free_t free;
|
||||||
|
void *user_data;
|
||||||
|
struct cache_entry *entries;
|
||||||
|
};
|
||||||
|
|
||||||
|
void *cache_get(struct cache *c, const char *key) {
|
||||||
|
struct cache_entry *e;
|
||||||
|
HASH_FIND_STR(c->entries, key, e);
|
||||||
|
if (e) {
|
||||||
|
return e->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = ccalloc(1, struct cache_entry);
|
||||||
|
e->key = strdup(key);
|
||||||
|
e->value = c->getter(c->user_data, key);
|
||||||
|
HASH_ADD_STR(c->entries, key, e);
|
||||||
|
return e->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void _cache_invalidate(struct cache *c, struct cache_entry *e) {
|
||||||
|
if (c->free) {
|
||||||
|
c->free(c->user_data, e->value);
|
||||||
|
}
|
||||||
|
HASH_DEL(c->entries, e);
|
||||||
|
free(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cache_invalidate(struct cache *c, const char *key) {
|
||||||
|
struct cache_entry *e;
|
||||||
|
HASH_FIND_STR(c->entries, key, e);
|
||||||
|
|
||||||
|
if (e) {
|
||||||
|
_cache_invalidate(c, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cache_invalidate_all(struct cache *c) {
|
||||||
|
struct cache_entry *e, *tmpe;
|
||||||
|
HASH_ITER(hh, c->entries, e, tmpe) {
|
||||||
|
_cache_invalidate(c, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *cache_free(struct cache *c) {
|
||||||
|
void *ret = c->user_data;
|
||||||
|
cache_invalidate_all(c);
|
||||||
|
free(c);
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct cache;
|
||||||
|
|
||||||
|
typedef void *(*cache_getter_t)(void *user_data, const char *key);
|
||||||
|
typedef void (*cache_free_t)(void *user_data, void *data);
|
||||||
|
struct cache *new_cache(void *user_data, cache_getter_t getter, cache_free_t f);
|
||||||
|
|
||||||
|
void *cache_get(struct cache *, const char *key);
|
||||||
|
void cache_invalidate(struct cache *, const char *key);
|
||||||
|
void cache_invalidate_all(struct cache *);
|
||||||
|
|
||||||
|
/// Returns the user data passed to `new_cache`
|
||||||
|
void *cache_free(struct cache *);
|
|
@ -10,7 +10,7 @@ base_deps = [
|
||||||
|
|
||||||
srcs = [ files('compton.c', 'win.c', 'c2.c', 'x.c', 'config.c', 'vsync.c', 'utils.c',
|
srcs = [ files('compton.c', 'win.c', 'c2.c', 'x.c', 'config.c', 'vsync.c', 'utils.c',
|
||||||
'diagnostic.c', 'string_utils.c', 'render.c', 'kernel.c', 'log.c',
|
'diagnostic.c', 'string_utils.c', 'render.c', 'kernel.c', 'log.c',
|
||||||
'options.c', 'event.c') ]
|
'options.c', 'event.c', 'cache.c') ]
|
||||||
compton_inc = include_directories('.')
|
compton_inc = include_directories('.')
|
||||||
|
|
||||||
cflags = []
|
cflags = []
|
||||||
|
|
Loading…
Reference in New Issue