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);
+     }
+}
+

-- 


Reply via email to