diff options
author | subhransu mohanty <sub.mohanty@samsung.com> | 2017-11-09 10:34:01 +0900 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2017-11-10 11:20:38 +0900 |
commit | d4a2b2025bd1e7396de74c0becb09d4ecbf3b6b9 (patch) | |
tree | 31443b3f73fe8b0b53bc036c9ff01223f4ebe0ee | |
parent | 76e75dc105ce98b29d5fd9026a0bc2fd18e41acd (diff) | |
download | efl-d4a2b2025bd1e7396de74c0becb09d4ecbf3b6b9.tar.gz |
evas/common: added a generic cache in evas common.
-rw-r--r-- | src/Makefile_Evas.am | 4 | ||||
-rw-r--r-- | src/lib/evas/common/evas_common_generic_cache.c | 104 |
2 files changed, 107 insertions, 1 deletions
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); + } +} + |