jpeg pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=d4a2b2025bd1e7396de74c0becb09d4ecbf3b6b9
commit d4a2b2025bd1e7396de74c0becb09d4ecbf3b6b9 Author: subhransu mohanty <[email protected]> Date: Thu Nov 9 10:34:01 2017 +0900 evas/common: added a generic cache in evas common. --- src/Makefile_Evas.am | 4 +- src/lib/evas/common/evas_common_generic_cache.c | 104 ++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index f1d0148667..408c0c7583 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -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 \ diff --git a/src/lib/evas/common/evas_common_generic_cache.c b/src/lib/evas/common/evas_common_generic_cache.c new file mode 100644 index 0000000000..55fd6e06b2 --- /dev/null +++ b/src/lib/evas/common/evas_common_generic_cache.c @@ -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); + } +} + --
