forked from enlightenment/efl
evas/common: added a generic cache in evas common.
This commit is contained in:
parent
76e75dc105
commit
d4a2b2025b
|
@ -494,7 +494,9 @@ lib/evas/common/language/evas_language_utils.h \
|
|||
lib/evas/common/language/evas_script_table.h \
|
||||
lib/evas/common/evas_text_utils.h \
|
||||
lib/evas/common/evas_font_ot.h \
|
||||
lib/evas/common/evas_font_draw.h
|
||||
lib/evas/common/evas_font_draw.h \
|
||||
lib/evas/common/evas_common_generic_cache.c
|
||||
|
||||
|
||||
lib_evas_libevas_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/evas/canvas \
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
#include "evas_common_private.h"
|
||||
|
||||
EAPI Generic_Cache*
|
||||
generic_cache_new(void *user_data, Generic_Cache_Free func)
|
||||
{
|
||||
Generic_Cache *cache;
|
||||
cache = calloc(1, sizeof(Generic_Cache));
|
||||
cache->hash = eina_hash_int32_new(NULL);
|
||||
cache->user_data = user_data;
|
||||
cache->free_func = func;
|
||||
return cache;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
generic_cache_destroy(Generic_Cache *cache)
|
||||
{
|
||||
generic_cache_dump(cache);
|
||||
eina_hash_free(cache->hash);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
generic_cache_dump(Generic_Cache *cache)
|
||||
{
|
||||
Generic_Cache_Entry *entry;
|
||||
if (cache)
|
||||
{
|
||||
eina_hash_free_buckets(cache->hash);
|
||||
EINA_LIST_FREE(cache->lru_list, entry)
|
||||
{
|
||||
cache->free_func(cache->user_data, entry->data);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EAPI void
|
||||
generic_cache_set(Generic_Cache *cache, void *key, void *surface)
|
||||
{
|
||||
Generic_Cache_Entry *entry = NULL;
|
||||
int count;
|
||||
|
||||
entry = calloc(1, sizeof(Generic_Cache_Entry));
|
||||
entry->key = key;
|
||||
entry->data = surface;
|
||||
entry->ref = 1;
|
||||
eina_hash_add(cache->hash, &key, entry);
|
||||
cache->lru_list = eina_list_prepend(cache->lru_list, entry);
|
||||
count = eina_list_count(cache->lru_list);
|
||||
if (count > 50)
|
||||
{
|
||||
entry = eina_list_data_get(eina_list_last(cache->lru_list));
|
||||
// if its still being ref.
|
||||
if (entry->ref) return;
|
||||
eina_hash_del(cache->hash, &entry->key, entry);
|
||||
cache->lru_list = eina_list_remove_list(cache->lru_list, eina_list_last(cache->lru_list));
|
||||
cache->free_func(cache->user_data, entry->data);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
|
||||
EAPI void *
|
||||
generic_cache_get(Generic_Cache *cache, void *key)
|
||||
{
|
||||
Generic_Cache_Entry *entry = NULL, *lru_data;
|
||||
Eina_List *l;
|
||||
|
||||
entry = eina_hash_find(cache->hash, &key);
|
||||
if (entry)
|
||||
{
|
||||
// update the ref
|
||||
entry->ref += 1;
|
||||
// promote in lru
|
||||
EINA_LIST_FOREACH(cache->lru_list, l, lru_data)
|
||||
{
|
||||
if (lru_data == entry)
|
||||
{
|
||||
cache->lru_list = eina_list_promote_list(cache->lru_list, l);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return entry->data;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
generic_cache_drop(Generic_Cache *cache, void *key)
|
||||
{
|
||||
Generic_Cache_Entry *entry = NULL;
|
||||
|
||||
entry = eina_hash_find(cache->hash, &key);
|
||||
if (entry)
|
||||
{
|
||||
entry->ref -= 1;
|
||||
// if its still being ref.
|
||||
if (entry->ref) return;
|
||||
eina_hash_del(cache->hash, &entry->key, entry);
|
||||
// find and remove from lru list
|
||||
cache->lru_list = eina_list_remove(cache->lru_list, entry);
|
||||
cache->free_func(cache->user_data, entry->data);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue