diff --git a/legacy/efreet/ChangeLog b/legacy/efreet/ChangeLog index 1b74bf366b..1af56c63ab 100644 --- a/legacy/efreet/ChangeLog +++ b/legacy/efreet/ChangeLog @@ -79,3 +79,8 @@ 2011-01-XX Sebastian Dransfeld * Remove FIXME, already done + +2011-01-XX Sebastian Dransfeld + + * Add local icon cache, so we wont hit the cache file for each icon + to be retrieved diff --git a/legacy/efreet/src/bin/efreet_icon_cache_create.c b/legacy/efreet/src/bin/efreet_icon_cache_create.c index 9f701738ec..c5b85f777d 100644 --- a/legacy/efreet/src/bin/efreet_icon_cache_create.c +++ b/legacy/efreet/src/bin/efreet_icon_cache_create.c @@ -840,7 +840,7 @@ main(int argc, char **argv) } eina_hash_free(themes); - efreet_hash_free(icons, EINA_FREE_CB(efreet_cache_icon_free)); + eina_hash_free(icons); if (theme->changed || changed) { @@ -914,7 +914,7 @@ main(int argc, char **argv) } } - efreet_hash_free(icons, EINA_FREE_CB(efreet_cache_icon_fallback_free)); + eina_hash_free(icons); eet_data_write(theme_ef, theme_edd, EFREET_CACHE_ICON_FALLBACK, theme, 1); icon_theme_free(theme); diff --git a/legacy/efreet/src/lib/efreet_cache.c b/legacy/efreet/src/lib/efreet_cache.c index e4698a393d..c17fe88264 100644 --- a/legacy/efreet/src/lib/efreet_cache.c +++ b/legacy/efreet/src/lib/efreet_cache.c @@ -2,7 +2,10 @@ # include #endif -/* TODO: Add local hash cache for icons */ +/* TODO: Consider flushing local icons cache after idling. + * Icon requests will probably come in batches, f.ex. during menu + * browsing. + */ /* TODO: Pass extra icon dirs to cache process */ /* TODO: Pass icon extensions to cache process */ @@ -49,6 +52,9 @@ static Eet_File *icon_cache = NULL; static Eet_File *fallback_cache = NULL; static Eet_File *icon_theme_cache = NULL; +static Eina_Hash *icons = NULL; +static Eina_Hash *fallbacks = NULL; + static const char *icon_theme_cache_file = NULL; static const char *theme_name = NULL; @@ -76,6 +82,8 @@ static int desktop_cache_exe_lock = -1; static Eina_List *old_desktop_caches = NULL; static void efreet_cache_edd_shutdown(void); +static void efreet_cache_icon_free(Efreet_Cache_Icon *icon); +static void efreet_cache_icon_fallback_free(Efreet_Cache_Fallback_Icon *icon); static Eina_Bool cache_exe_cb(void *data, int type, void *event); static void cache_update_cb(void *data, Ecore_File_Monitor *em, @@ -101,6 +109,9 @@ efreet_cache_init(void) EFREET_EVENT_ICON_CACHE_UPDATE = ecore_event_type_new(); EFREET_EVENT_DESKTOP_CACHE_UPDATE = ecore_event_type_new(); + icons = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_free)); + fallbacks = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_fallback_free)); + snprintf(buf, sizeof(buf), "%s/efreet", efreet_cache_home_get()); if (!ecore_file_mkpath(buf)) goto error; @@ -139,6 +150,9 @@ efreet_cache_shutdown(void) icon_cache = efreet_cache_close(icon_cache); icon_theme_cache = efreet_cache_close(icon_theme_cache); + IF_FREE_HASH(icons); + IF_FREE_HASH(fallbacks); + desktop_cache = efreet_cache_close(desktop_cache); IF_RELEASE(desktop_cache_file); IF_RELEASE(desktop_cache_dirs); @@ -554,15 +568,13 @@ efreet_desktop_edd(void) return desktop_edd; } -/* - * Needs EAPI because of helper binaries - */ -EAPI void +static void efreet_cache_icon_free(Efreet_Cache_Icon *icon) { unsigned int i; if (!icon) return; + if (icon == NON_EXISTING) return; for (i = 0; i < icon->icons_count; ++i) { @@ -574,10 +586,11 @@ efreet_cache_icon_free(Efreet_Cache_Icon *icon) free(icon); } -EAPI void +static void efreet_cache_icon_fallback_free(Efreet_Cache_Fallback_Icon *icon) { if (!icon) return; + if (icon == NON_EXISTING) return; free(icon->icons); free(icon); @@ -586,27 +599,51 @@ efreet_cache_icon_fallback_free(Efreet_Cache_Fallback_Icon *icon) Efreet_Cache_Icon * efreet_cache_icon_find(Efreet_Icon_Theme *theme, const char *icon) { + Efreet_Cache_Icon *cache = NULL; + if (theme_name && strcmp(theme_name, theme->name.internal)) { /* FIXME: this is bad if people have pointer to this cache, things will go wrong */ INFO("theme_name change from `%s` to `%s`", theme_name, theme->name.internal); IF_RELEASE(theme_name); icon_cache = efreet_cache_close(icon_cache); + eina_hash_free(icons); + icons = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_free)); } if (!efreet_cache_check(&icon_cache, efreet_icon_cache_file(theme->name.internal), EFREET_ICON_CACHE_MAJOR)) return NULL; if (!theme_name) theme_name = eina_stringshare_add(theme->name.internal); - return eet_data_read(icon_cache, efreet_icon_edd(), icon); + cache = eina_hash_find(icons, icon); + if (cache == NON_EXISTING) return NULL; + if (cache) return cache; + + cache = eet_data_read(icon_cache, efreet_icon_edd(), icon); + if (cache) + eina_hash_add(icons, icon, cache); + else + eina_hash_add(icons, icon, NON_EXISTING); + return cache; } Efreet_Cache_Fallback_Icon * efreet_cache_icon_fallback_find(const char *icon) { + Efreet_Cache_Fallback_Icon *cache; + if (!efreet_cache_check(&fallback_cache, efreet_icon_cache_file(EFREET_CACHE_ICON_FALLBACK), EFREET_ICON_CACHE_MAJOR)) return NULL; - return eet_data_read(fallback_cache, efreet_icon_fallback_edd(), icon); + cache = eina_hash_find(fallbacks, icon); + if (cache == NON_EXISTING) return NULL; + if (cache) return cache; + + cache = eet_data_read(fallback_cache, efreet_icon_fallback_edd(), icon); + if (cache) + eina_hash_add(fallbacks, icon, cache); + else + eina_hash_add(fallbacks, icon, NON_EXISTING); + return cache; } Efreet_Icon_Theme * diff --git a/legacy/efreet/src/lib/efreet_icon.c b/legacy/efreet/src/lib/efreet_icon.c index 7b8cfde6ee..cb4a71ed3b 100644 --- a/legacy/efreet/src/lib/efreet_icon.c +++ b/legacy/efreet/src/lib/efreet_icon.c @@ -342,7 +342,6 @@ efreet_icon_path_find(const char *theme_name, const char *icon, unsigned int siz cache = efreet_cache_icon_fallback_find(icon); value = efreet_cache_icon_fallback_lookup_path(cache); if (!value) INFO("lookup for `%s` failed in fallback too with %p.", icon, cache); - efreet_cache_icon_fallback_free(cache); } if (value == NON_EXISTING) value = NULL; @@ -398,7 +397,6 @@ efreet_icon_list_find(const char *theme_name, Eina_List *icons, if (!strcmp(cache->theme, theme->name.internal)) { value = efreet_cache_icon_lookup_icon(cache, size); - efreet_cache_icon_free(cache); break; } else @@ -409,8 +407,7 @@ efreet_icon_list_find(const char *theme_name, Eina_List *icons, { if (!value) value = efreet_cache_icon_list_lookup_icon(theme, tmps2, size); - EINA_LIST_FREE(tmps2, cache) - efreet_cache_icon_free(cache); + eina_list_free(tmps2); } #ifdef SLOPPY_SPEC @@ -429,7 +426,6 @@ efreet_icon_list_find(const char *theme_name, Eina_List *icons, { cache = efreet_cache_icon_fallback_find(icon); value = efreet_cache_icon_fallback_lookup_path(cache); - efreet_cache_icon_fallback_free(cache); if (value && (value != NON_EXISTING)) break; } diff --git a/legacy/efreet/src/lib/efreet_private.h b/legacy/efreet/src/lib/efreet_private.h index 4649dab87b..487d9b1857 100644 --- a/legacy/efreet/src/lib/efreet_private.h +++ b/legacy/efreet/src/lib/efreet_private.h @@ -236,8 +236,6 @@ Efreet_Desktop *efreet_cache_desktop_find(const char *file); EAPI const char *efreet_icon_cache_file(const char *theme); EAPI const char *efreet_icon_theme_cache_file(void); -EAPI void efreet_cache_icon_free(Efreet_Cache_Icon *icon); -EAPI void efreet_cache_icon_fallback_free(Efreet_Cache_Fallback_Icon *icon); Efreet_Cache_Icon *efreet_cache_icon_find(Efreet_Icon_Theme *theme, const char *icon); Efreet_Cache_Fallback_Icon *efreet_cache_icon_fallback_find(const char *icon); Efreet_Icon_Theme *efreet_cache_icon_theme_find(const char *theme); diff --git a/legacy/efreet/src/tests/efreet_icon_cache_dump.c b/legacy/efreet/src/tests/efreet_icon_cache_dump.c index 5f8d7c9595..c11b210704 100644 --- a/legacy/efreet/src/tests/efreet_icon_cache_dump.c +++ b/legacy/efreet/src/tests/efreet_icon_cache_dump.c @@ -51,7 +51,6 @@ dump(Efreet_Icon_Theme *theme) for (j = 0; j < icon->icons_count; ++j) count += icon->icons[j]->paths_count; - efreet_cache_icon_free(icon); } free(keys);