From ba1e67fcd8c112d1cf98fb7853b18f1e6aef7bf2 Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Tue, 3 Mar 2009 22:38:21 +0000 Subject: [PATCH] Add LRU to mime icons cache. This should really remove unused items that would age forever in the last, forcing old but not so to be evicted before them. Fortunately it was not so complex to add, and should wait just 3 pointers more of space per node. SVN revision: 39350 --- legacy/efreet/src/lib/efreet_mime.c | 117 +++++++++++++++------------- 1 file changed, 61 insertions(+), 56 deletions(-) diff --git a/legacy/efreet/src/lib/efreet_mime.c b/legacy/efreet/src/lib/efreet_mime.c index 2868802cd4..412229d4ee 100644 --- a/legacy/efreet/src/lib/efreet_mime.c +++ b/legacy/efreet/src/lib/efreet_mime.c @@ -13,6 +13,7 @@ static Eina_List *magics = NULL; /* contains Efreet_Mime_Magic structs */ static Eina_Hash *wild = NULL; /* contains *.ext and mime.types globs*/ static Eina_Hash *monitors = NULL; /* contains file monitors */ static Eina_Hash *mime_icons = NULL; /* contains cache with mime->icons */ +static Eina_Inlist *mime_icons_lru = NULL; static unsigned int _init_count = 0; /** @@ -95,6 +96,7 @@ struct Efreet_Mime_Magic_Entry typedef struct Efreet_Mime_Icon_Entry_Head Efreet_Mime_Icon_Entry_Head; struct Efreet_Mime_Icon_Entry_Head { + EINA_INLIST; /* node of mime_icons_lru */ Eina_Inlist *list; const char *mime; time_t timestamp; @@ -318,7 +320,10 @@ EAPI void efreet_mime_type_cache_clear(void) { if (mime_icons) + { eina_hash_free(mime_icons); + mime_icons_lru = NULL; + } mime_icons = eina_hash_pointer_new(EINA_FREE_CB(efreet_mime_icon_entry_head_free)); } @@ -1327,53 +1332,31 @@ efreet_mime_glob_case_match(char *str, const char *glob) return 0; } -struct Efreet_Mime_Icons_Flush_Data -{ - time_t now; - int todo; - Eina_List *removal; -}; - -static Eina_Bool -efreet_mime_icons_flush_cb(const Eina_Hash *hash __UNUSED__, - const void *key __UNUSED__, - void *data, - void *fdata) -{ - struct Efreet_Mime_Icons_Flush_Data *d = fdata; - Efreet_Mime_Icon_Entry_Head *entry = data; - - if (d->now - entry->timestamp < EFREET_MIME_ICONS_EXPIRE_TIMEOUT) - return 1; - - d->removal = eina_list_append(d->removal, entry->mime); - d->todo--; - - return d->todo > 0; -} - static void efreet_mime_icons_flush(time_t now) { - struct Efreet_Mime_Icons_Flush_Data data; + Eina_Inlist *l; static time_t old = 0; int todo; - const char *key; if (now - old < EFREET_MIME_ICONS_FLUSH_TIMEOUT) return; + old = now; todo = eina_hash_population(mime_icons) - EFREET_MIME_ICONS_MAX_POPULATION; if (todo <= 0) return; - data.now = now; - data.todo = todo; - data.removal = NULL; - eina_hash_foreach(mime_icons, efreet_mime_icons_flush_cb, &data); + l = mime_icons_lru->last; /* mime_icons_lru is not NULL, since todo > 0 */ + for (; todo > 0; todo--) + { + Efreet_Mime_Icon_Entry_Head *entry = (Efreet_Mime_Icon_Entry_Head *)l; + Eina_Inlist *prev = l->prev; - EINA_LIST_FREE(data.removal, key) - eina_hash_del_by_key(mime_icons, key); + mime_icons_lru = eina_inlist_remove(mime_icons_lru, l); + eina_hash_del_by_key(mime_icons, entry->mime); + l = prev; + } efreet_mime_icons_debug(); } @@ -1433,18 +1416,33 @@ efreet_mime_icon_entry_add(const char *mime, entry = eina_hash_find(mime_icons, mime); if (entry) - entry->list = eina_inlist_prepend(entry->list, EINA_INLIST_GET(n)); + { + Eina_Inlist *l; + + l = EINA_INLIST_GET(n); + entry->list = eina_inlist_prepend(entry->list, l); + + l = EINA_INLIST_GET(entry); + mime_icons_lru = eina_inlist_promote(mime_icons_lru, l); + } else { + Eina_Inlist *l; + entry = malloc(sizeof(*entry)); if (!entry) { efreet_mime_icon_entry_free(n); return; } - entry->list = eina_inlist_prepend(NULL, EINA_INLIST_GET(n)); + + l = EINA_INLIST_GET(n); + entry->list = eina_inlist_prepend(NULL, l); entry->mime = mime; eina_hash_direct_add(mime_icons, mime, entry); + + l = EINA_INLIST_GET(entry); + mime_icons_lru = eina_inlist_prepend(mime_icons_lru, l); } entry->timestamp = (time_t)ecore_loop_time_get(); @@ -1467,9 +1465,16 @@ efreet_mime_icon_entry_find(const char *mime, { if ((n->theme == theme) && (n->size == size)) { - Eina_Inlist *l = EINA_INLIST_GET(n); + Eina_Inlist *l; + + l = EINA_INLIST_GET(n); if (entry->list != l) entry->list = eina_inlist_promote(entry->list, l); + + l = EINA_INLIST_GET(entry); + if (mime_icons_lru != l) + mime_icons_lru = eina_inlist_promote(mime_icons_lru, l); + entry->timestamp = (time_t)ecore_loop_time_get(); return n->icon; } @@ -1479,29 +1484,29 @@ efreet_mime_icon_entry_find(const char *mime, } #ifdef EFREET_MIME_ICONS_DEBUG -static Eina_Bool -efreet_mime_icons_debug_cb(const Eina_Hash *hash __UNUSED__, - const void *key __UNUSED__, - void *data, - void *fdata __UNUSED__) -{ - Efreet_Mime_Icon_Entry_Head *entry = data; - Efreet_Mime_Icon_Entry *n; - - printf("mime-icon entry: '%s' last used: %s", - entry->mime, ctime(&entry->timestamp)); - - EINA_INLIST_FOREACH(entry->list, n) - printf("\tsize: %3u theme: '%s' icon: '%s'\n", - n->theme, n->size, n->icon); - - return 1; -} - static void efreet_mime_icons_debug(void) { - eina_hash_foreach(mime_icons, efreet_mime_icons_debug_cb, NULL); + time_t now = (time_t)ecore_loop_time_get(); + Efreet_Mime_Icon_Entry_Head *entry; + EINA_INLIST_FOREACH(mime_icons_lru, entry) + { + Efreet_Mime_Icon_Entry *n; + + if ((now > 0) && + (now - entry->timestamp >= EFREET_MIME_ICONS_EXPIRE_TIMEOUT)) + { + puts("*** FOLLOWING ENTRIES ARE AGED AND CAN BE EXPIRED ***"); + now = 0; + } + + printf("mime-icon entry: '%s' last used: %s", + entry->mime, ctime(&entry->timestamp)); + + EINA_INLIST_FOREACH(entry->list, n) + printf("\tsize: %3u theme: '%s' icon: '%s'\n", + n->theme, n->size, n->icon); + } } #else static void