Improve storage of desktop util data

SVN revision: 56588
This commit is contained in:
Sebastian Dransfeld 2011-01-31 11:32:34 +00:00
parent dd3a72dc33
commit 37405fc035
6 changed files with 362 additions and 190 deletions

View File

@ -13,3 +13,7 @@
2011-01-31 Sebastian Dransfeld
* Fix memleak, free cache icons after retrival
2011-01-31 Sebastian Dransfeld
* Improve storage of desktop util data

View File

@ -24,9 +24,19 @@ static Eet_Data_Descriptor *edd = NULL;
static Eet_File *ef = NULL;
static Eet_File *util_ef = NULL;
static Eina_Hash *desktops = NULL;
static Eina_Hash *file_ids = NULL;
static Eina_Hash *paths = NULL;
static Eina_Hash *mime_types = NULL;
static Eina_Hash *categories = NULL;
static Eina_Hash *startup_wm_class = NULL;
static Eina_Hash *name = NULL;
static Eina_Hash *generic_name = NULL;
static Eina_Hash *comment = NULL;
static Eina_Hash *exec = NULL;
static int verbose = 0;
static int
@ -88,67 +98,43 @@ cache_add(const char *path, const char *file_id, int priority __UNUSED__, int *c
if (!desk->hidden && desk->type == EFREET_DESKTOP_TYPE_APPLICATION &&
file_id && !eina_hash_find(file_ids, file_id))
{
int id;
char key[PATH_MAX];
char *data;
int i = 0;
Eina_List *l;
char *data;
Efreet_Cache_Array_String *array;
id = eina_hash_population(file_ids);
i = 0;
EINA_LIST_FOREACH(desk->mime_types, l, data)
{
snprintf(key, sizeof(key), "%d::%d::m", id, i++);
if (!eet_write(util_ef, key, data, strlen(data) + 1, 0)) return 0;
#define ADD_LIST(list, hash) \
EINA_LIST_FOREACH((list), l, data) \
{ \
array = eina_hash_find((hash), data); \
if (!array) \
array = NEW(Efreet_Cache_Array_String, 1); \
array->array = realloc(array->array, sizeof (char *) * (array->array_count + 1)); \
array->array[array->array_count++] = desk->orig_path; \
eina_hash_set((hash), data, array); \
}
i = 0;
EINA_LIST_FOREACH(desk->categories, l, data)
{
snprintf(key, sizeof(key), "%d::%d::ca", id, i++);
if (!eet_write(util_ef, key, data, strlen(data) + 1, 0)) return 0;
#define ADD_ELEM(elem, hash) \
if ((elem)) \
{ \
data = (elem); \
array = eina_hash_find((hash), data); \
if (!array) \
array = NEW(Efreet_Cache_Array_String, 1); \
array->array = realloc(array->array, sizeof (char *) * (array->array_count + 1)); \
array->array[array->array_count++] = desk->orig_path; \
eina_hash_set((hash), data, array); \
}
if (desk->startup_wm_class)
{
data = desk->startup_wm_class;
snprintf(key, sizeof(key), "%d::swc", id);
if (!eet_write(util_ef, key, data, strlen(data) + 1, 0)) return 0;
}
if (desk->name)
{
data = desk->name;
snprintf(key, sizeof(key), "%d::n", id);
if (!eet_write(util_ef, key, data, strlen(data) + 1, 0)) return 0;
}
if (desk->generic_name)
{
data = desk->generic_name;
snprintf(key, sizeof(key), "%d::gn", id);
if (!eet_write(util_ef, key, data, strlen(data) + 1, 0)) return 0;
}
if (desk->comment)
{
data = desk->comment;
snprintf(key, sizeof(key), "%d::co", id);
if (!eet_write(util_ef, key, data, strlen(data) + 1, 0)) return 0;
}
if (desk->exec)
{
data = desk->exec;
snprintf(key, sizeof(key), "%d::e", id);
if (!eet_write(util_ef, key, data, strlen(data) + 1, 0)) return 0;
}
if (desk->orig_path)
{
data = desk->orig_path;
snprintf(key, sizeof(key), "%d::op", id);
if (!eet_write(util_ef, key, data, strlen(data) + 1, 0)) return 0;
}
snprintf(key, sizeof(key), "%d::fi", id);
if (!eet_write(util_ef, key, file_id, strlen(file_id) + 1, 0)) return 0;
eina_hash_add(file_ids, file_id, (void *)1);
ADD_LIST(desk->mime_types, mime_types);
ADD_LIST(desk->categories, categories);
ADD_ELEM(desk->startup_wm_class, startup_wm_class);
ADD_ELEM(desk->name, name);
ADD_ELEM(desk->generic_name, generic_name);
ADD_ELEM(desk->comment, comment);
ADD_ELEM(desk->exec, exec);
eina_hash_add(file_ids, file_id, desk->orig_path);
eina_hash_add(desktops, desk->orig_path, desk);
}
efreet_desktop_free(desk);
else
efreet_desktop_free(desk);
return 1;
}
@ -208,6 +194,7 @@ main(int argc, char **argv)
* during whilst this program runs.
* - Maybe linger for a while to reduce number of cache re-creates.
*/
Efreet_Cache_Hash hash;
Efreet_Cache_Version version;
Eina_List *dirs = NULL, *user_dirs = NULL;
int priority = 0;
@ -265,12 +252,12 @@ main(int argc, char **argv)
/* create dir for desktop cache */
dir = ecore_file_dir_get(efreet_desktop_cache_file());
if (!ecore_file_mkpath(dir)) goto efreet_error;
free(dir);
IF_FREE(dir);
/* create dir for util cache */
dir = ecore_file_dir_get(efreet_desktop_util_cache_file());
if (!ecore_file_mkpath(dir)) goto efreet_error;
free(dir);
IF_FREE(dir);
/* finish efreet init */
if (!efreet_init()) goto efreet_error;
@ -292,10 +279,26 @@ main(int argc, char **argv)
util_ef = eet_open(util_file, EET_FILE_MODE_READ_WRITE);
if (!util_ef) goto error;
/* write cache version */
version.major = EFREET_DESKTOP_UTILS_CACHE_MAJOR;
version.minor = EFREET_DESKTOP_UTILS_CACHE_MINOR;
eet_data_write(util_ef, efreet_version_edd(), EFREET_CACHE_VERSION, &version, 1);
version.major = EFREET_DESKTOP_CACHE_MAJOR;
version.minor = EFREET_DESKTOP_CACHE_MINOR;
eet_data_write(ef, efreet_version_edd(), EFREET_CACHE_VERSION, &version, 1);
desktops = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_desktop_free));
file_ids = eina_hash_string_superfast_new(NULL);
if (!file_ids) goto error;
paths = eina_hash_string_superfast_new(NULL);
if (!paths) goto error;
mime_types = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free));
categories = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free));
startup_wm_class = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free));
name = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free));
generic_name = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free));
comment = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free));
exec = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_array_string_free));
dirs = efreet_default_dirs_get(efreet_data_home_get(), efreet_data_dirs_get(),
"applications");
@ -361,16 +364,52 @@ main(int argc, char **argv)
close(dirsfd);
dirsfd = -1;
}
/* store util */
#define STORE_HASH_ARRAY(_hash) \
if (eina_hash_population((_hash)) > 0) \
{ \
Eina_Iterator *it; \
Efreet_Cache_Array_String array; \
const char *str; \
\
hash.hash = (_hash); \
eet_data_write(util_ef, efreet_hash_array_string_edd(), #_hash "_hash", &hash, 1); \
printf("key: %s = %d\n", #_hash, eina_hash_population(hash.hash)); \
array.array_count = 0; \
array.array = malloc(eina_hash_population(hash.hash) * sizeof(char *)); \
it = eina_hash_iterator_key_new(hash.hash); \
EINA_ITERATOR_FOREACH(it, str) \
array.array[array.array_count++] = str; \
eina_iterator_free(it); \
eet_data_write(util_ef, efreet_array_string_edd(), #_hash "_list", &array, 1); \
}
STORE_HASH_ARRAY(mime_types);
STORE_HASH_ARRAY(categories);
STORE_HASH_ARRAY(startup_wm_class);
STORE_HASH_ARRAY(name);
STORE_HASH_ARRAY(generic_name);
STORE_HASH_ARRAY(comment);
STORE_HASH_ARRAY(exec);
if (eina_hash_population(file_ids) > 0)
{
hash.hash = file_ids;
eet_data_write(util_ef, efreet_hash_string_edd(), "file_id", &hash, 1);
printf("key: file_id = %d\n", eina_hash_population(file_ids));
}
eina_hash_free(mime_types);
eina_hash_free(categories);
eina_hash_free(startup_wm_class);
eina_hash_free(name);
eina_hash_free(generic_name);
eina_hash_free(comment);
eina_hash_free(exec);
eina_hash_free(file_ids);
eina_hash_free(paths);
/* write cache version */
version.major = EFREET_DESKTOP_UTILS_CACHE_MAJOR;
version.minor = EFREET_DESKTOP_UTILS_CACHE_MINOR;
eet_data_write(util_ef, efreet_version_edd(), EFREET_CACHE_VERSION, &version, 1);
version.major = EFREET_DESKTOP_CACHE_MAJOR;
version.minor = EFREET_DESKTOP_CACHE_MINOR;
eet_data_write(ef, efreet_version_edd(), EFREET_CACHE_VERSION, &version, 1);
eina_hash_free(desktops);
/* check if old and new caches contain the same number of entries */
if (!changed)
@ -383,7 +422,6 @@ main(int argc, char **argv)
old = eet_open(efreet_desktop_util_cache_file(), EET_FILE_MODE_READ);
if (!old || eet_num_entries(old) != eet_num_entries(util_ef)) changed = 1;
if (old) eet_close(old);
}
/* cleanup */

View File

@ -56,6 +56,9 @@ static Efreet_Cache_Icons *fallback_cache = NULL;
static Eet_Data_Descriptor *version_edd = NULL;
static Eet_Data_Descriptor *desktop_edd = NULL;
static Eet_Data_Descriptor *hash_array_string_edd = NULL;
static Eet_Data_Descriptor *array_string_edd = NULL;
static Eet_Data_Descriptor *hash_string_edd = NULL;
static Eet_File *desktop_cache = NULL;
static const char *desktop_cache_dirs = NULL;
@ -252,6 +255,67 @@ efreet_version_edd(void)
return version_edd;
}
/*
* Needs EAPI because of helper binaries
*/
EAPI Eet_Data_Descriptor *
efreet_hash_array_string_edd(void)
{
Eet_Data_Descriptor_Class eddc;
if (hash_array_string_edd) return hash_array_string_edd;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Hash);
/* TODO: set own hash func */
hash_array_string_edd = eet_data_descriptor_file_new(&eddc);
if (!hash_array_string_edd) return NULL;
EET_DATA_DESCRIPTOR_ADD_HASH(hash_array_string_edd, Efreet_Cache_Hash,
"hash", hash, efreet_array_string_edd());
return hash_array_string_edd;
}
/*
* Needs EAPI because of helper binaries
*/
EAPI Eet_Data_Descriptor *
efreet_hash_string_edd(void)
{
Eet_Data_Descriptor_Class eddc;
if (hash_string_edd) return hash_string_edd;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Hash);
/* TODO: set own hash func */
hash_string_edd = eet_data_descriptor_file_new(&eddc);
if (!hash_string_edd) return NULL;
EET_DATA_DESCRIPTOR_ADD_HASH_STRING(hash_string_edd, Efreet_Cache_Hash,
"hash", hash);
return hash_string_edd;
}
/*
* Needs EAPI because of helper binaries
*/
EAPI Eet_Data_Descriptor *
efreet_array_string_edd(void)
{
Eet_Data_Descriptor_Class eddc;
if (array_string_edd) return array_string_edd;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Efreet_Cache_Array_String);
array_string_edd = eet_data_descriptor_file_new(&eddc);
if (!array_string_edd) return NULL;
EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY_STRING(array_string_edd, Efreet_Cache_Array_String,
"array", array);
return array_string_edd;
}
/*
* Needs EAPI because of helper binaries
*/
@ -306,6 +370,9 @@ efreet_cache_edd_shutdown(void)
{
EDD_SHUTDOWN(version_edd);
EDD_SHUTDOWN(desktop_edd);
EDD_SHUTDOWN(hash_array_string_edd);
EDD_SHUTDOWN(array_string_edd);
EDD_SHUTDOWN(hash_string_edd);
#ifdef ICON_CACHE
EDD_SHUTDOWN(fallback_edd);
EDD_SHUTDOWN(icon_theme_edd);
@ -675,6 +742,13 @@ efreet_cache_icon_theme_name_list(int *num)
#endif
EAPI void
efreet_cache_array_string_free(Efreet_Cache_Array_String *array)
{
free(array->array);
free(array);
}
Efreet_Desktop *
efreet_cache_desktop_find(const char *file)
{

View File

@ -11,6 +11,9 @@ void *efreet_cache_close(Eet_File *ef);
EAPI Eet_Data_Descriptor *efreet_version_edd(void);
EAPI Eet_Data_Descriptor *efreet_desktop_edd(void);
EAPI Eet_Data_Descriptor *efreet_hash_array_string_edd(void);
EAPI Eet_Data_Descriptor *efreet_hash_string_edd(void);
EAPI Eet_Data_Descriptor *efreet_array_string_edd(void);
#ifdef ICON_CACHE
EAPI Eet_Data_Descriptor *efreet_icon_theme_edd(void);
EAPI Eet_Data_Descriptor *efreet_icons_edd(Eina_Bool include_dirs);

View File

@ -118,10 +118,10 @@ extern Eina_Hash *efreet_desktop_cache;
extern Eina_Hash *efreet_icon_themes;
#endif
#define EFREET_DESKTOP_CACHE_MAJOR 0
#define EFREET_DESKTOP_CACHE_MINOR 1
#define EFREET_DESKTOP_UTILS_CACHE_MAJOR 0
#define EFREET_DESKTOP_UTILS_CACHE_MINOR 1
#define EFREET_DESKTOP_CACHE_MAJOR 1
#define EFREET_DESKTOP_CACHE_MINOR 0
#define EFREET_DESKTOP_UTILS_CACHE_MAJOR 1
#define EFREET_DESKTOP_UTILS_CACHE_MINOR 0
#ifdef ICON_CACHE
#define EFREET_ICON_CACHE_MAJOR 0
@ -186,6 +186,19 @@ struct _Efreet_Cache_Version
unsigned char minor;
};
typedef struct _Efreet_Cache_Hash Efreet_Cache_Hash;
struct _Efreet_Cache_Hash
{
Eina_Hash *hash;
};
typedef struct _Efreet_Cache_Array_String Efreet_Cache_Array_String;
struct _Efreet_Cache_Array_String
{
const char **array;
unsigned int array_count;
};
int efreet_base_init(void);
void efreet_base_shutdown(void);
@ -245,6 +258,7 @@ Efreet_Icon_Theme *efreet_cache_icon_theme_find(const char *theme);
void efreet_cache_icon_theme_free(Efreet_Icon_Theme *theme);
char **efreet_cache_icon_theme_name_list(int *num);
#endif
EAPI void efreet_cache_array_string_free(Efreet_Cache_Array_String *array);
EAPI void efreet_hash_free(Eina_Hash *hash, Eina_Free_Cb free_cb);

View File

@ -4,6 +4,7 @@
/* TODO: move eet file handling to eet_cache.c */
/* TODO: add no_display check, as we might want only displayable items */
/* TODO: Keep data read from eet in mem for a while, to make subsequent searches faster, nice for exebuf */
#undef alloca
#ifdef HAVE_ALLOCA_H
@ -194,7 +195,7 @@ efreet_util_path_to_file_id(const char *path)
EAPI Eina_List *
efreet_util_desktop_mime_list(const char *mime)
{
return efreet_util_cache_list("*::m", mime);
return efreet_util_cache_list("mime_types", mime);
}
/**
@ -209,7 +210,7 @@ efreet_util_desktop_mime_list(const char *mime)
EAPI Efreet_Desktop *
efreet_util_desktop_wm_class_find(const char *wmname, const char *wmclass)
{
return efreet_util_cache_find("*::swc", wmname, wmclass);
return efreet_util_cache_find("startup_wm_class", wmname, wmclass);
}
/**
@ -223,7 +224,21 @@ efreet_util_desktop_wm_class_find(const char *wmname, const char *wmclass)
EAPI Efreet_Desktop *
efreet_util_desktop_file_id_find(const char *file_id)
{
return efreet_util_cache_find("*::fi", file_id, NULL);
Efreet_Cache_Hash *hash;
Efreet_Desktop *ret = NULL;
const char *str;
if (!file_id) return NULL;
if (!efreet_cache_check(&cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL;
hash = eet_data_read(cache, efreet_hash_string_edd(), "file_id");
if (!hash) return NULL;
str = eina_hash_find(hash->hash, file_id);
if (str)
ret = efreet_desktop_get(str);
eina_hash_free(hash->hash);
free(hash);
return ret;
}
/**
@ -237,25 +252,24 @@ efreet_util_desktop_file_id_find(const char *file_id)
EAPI Efreet_Desktop *
efreet_util_desktop_exec_find(const char *exec)
{
char **keys;
int num, i;
Efreet_Cache_Hash *hash;
Efreet_Desktop *ret = NULL;
Efreet_Cache_Array_String *names = NULL;
unsigned int i;
if (!efreet_cache_check(&cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL;
if (!exec) return NULL;
keys = eet_list(cache, "*::e", &num);
if (!keys) return NULL;
for (i = 0; i < num; i++)
names = eet_data_read(cache, efreet_array_string_edd(), "exec_list");
if (!names) goto error;
for (i = 0; i < names->array_count; i++)
{
const char *data, *file;
const char *file;
char *exe;
int size, id;
char key[PATH_MAX];
unsigned int j;
Efreet_Cache_Array_String *array;
data = eet_read_direct(cache, keys[i], &size);
if (!data) continue;
exe = ecore_file_app_exe_get(data);
exe = ecore_file_app_exe_get(names->array[i]);
if (!exe) continue;
file = ecore_file_file_get(exe);
if (!file) continue;
@ -266,14 +280,26 @@ efreet_util_desktop_exec_find(const char *exec)
}
free(exe);
id = atoi(keys[i]);
snprintf(key, sizeof(key), "%d::op", id);
data = eet_read_direct(cache, key, &size);
if (!data) continue;
ret = efreet_desktop_get(data);
if (!hash)
hash = eet_data_read(cache, efreet_hash_array_string_edd(), "exec_hash");
if (!hash) goto error;
array = eina_hash_find(hash->hash, names->array[i]);
if (!array) continue;
for (j = 0; j < array->array_count; j++)
{
ret = efreet_desktop_get(array->array[j]);
if (ret) break;
}
if (ret) break;
}
free(keys);
error:
if (hash)
{
eina_hash_free(hash->hash);
free(hash);
}
if (names)
efreet_cache_array_string_free(names);
return ret;
}
@ -288,7 +314,7 @@ efreet_util_desktop_exec_find(const char *exec)
EAPI Efreet_Desktop *
efreet_util_desktop_name_find(const char *name)
{
return efreet_util_cache_find("*::n", name, NULL);
return efreet_util_cache_find("name", name, NULL);
}
/**
@ -302,7 +328,7 @@ efreet_util_desktop_name_find(const char *name)
EAPI Efreet_Desktop *
efreet_util_desktop_generic_name_find(const char *generic_name)
{
return efreet_util_cache_find("*::gn", generic_name, NULL);
return efreet_util_cache_find("generic_name", generic_name, NULL);
}
/**
@ -316,7 +342,7 @@ efreet_util_desktop_generic_name_find(const char *generic_name)
EAPI Eina_List *
efreet_util_desktop_name_glob_list(const char *glob)
{
return efreet_util_cache_glob_list("*::n", glob);
return efreet_util_cache_glob_list("name", glob);
}
/**
@ -330,26 +356,24 @@ efreet_util_desktop_name_glob_list(const char *glob)
EAPI Eina_List *
efreet_util_desktop_exec_glob_list(const char *glob)
{
char **keys;
int num, i;
Efreet_Cache_Hash *hash = NULL;
Eina_List *ret = NULL;
Efreet_Cache_Array_String *names = NULL;
unsigned int i;
if (!efreet_cache_check(&cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL;
if (!glob) return NULL;
keys = eet_list(cache, "*::e", &num);
if (!keys) return NULL;
for (i = 0; i < num; i++)
names = eet_data_read(cache, efreet_array_string_edd(), "exec_list");
if (!names) goto error;
for (i = 0; i < names->array_count; i++)
{
const char *data;
Efreet_Cache_Array_String *array;
unsigned int j;
char *exe;
int size, id;
char key[PATH_MAX];
Efreet_Desktop *desk;
data = eet_read_direct(cache, keys[i], &size);
if (!data) continue;
exe = ecore_file_app_exe_get(data);
exe = ecore_file_app_exe_get(names->array[i]);
if (!exe) continue;
if (!efreet_util_glob_match(exe, glob))
{
@ -358,15 +382,27 @@ efreet_util_desktop_exec_glob_list(const char *glob)
}
free(exe);
id = atoi(keys[i]);
snprintf(key, sizeof(key), "%d::op", id);
data = eet_read_direct(cache, key, &size);
if (!data) continue;
desk = efreet_desktop_get(data);
if (desk)
ret = eina_list_append(ret, desk);
if (!hash)
hash = eet_data_read(cache, efreet_hash_array_string_edd(), "exec_hash");
if (!hash) goto error;
array = eina_hash_find(hash->hash, names->array[i]);
if (!array) continue;
for (j = 0; j < array->array_count; j++)
{
desk = efreet_desktop_get(array->array[j]);
if (desk)
ret = eina_list_append(ret, desk);
}
}
free(keys);
error:
if (hash)
{
eina_hash_free(hash->hash);
free(hash);
}
if (names)
efreet_cache_array_string_free(names);
return ret;
}
@ -381,7 +417,7 @@ efreet_util_desktop_exec_glob_list(const char *glob)
EAPI Eina_List *
efreet_util_desktop_generic_name_glob_list(const char *glob)
{
return efreet_util_cache_glob_list("*::gn", glob);
return efreet_util_cache_glob_list("generic_name", glob);
}
/**
@ -395,7 +431,7 @@ efreet_util_desktop_generic_name_glob_list(const char *glob)
EAPI Eina_List *
efreet_util_desktop_comment_glob_list(const char *glob)
{
return efreet_util_cache_glob_list("*::co", glob);
return efreet_util_cache_glob_list("comment", glob);
}
/**
@ -407,24 +443,17 @@ efreet_util_desktop_comment_glob_list(const char *glob)
EAPI Eina_List *
efreet_util_desktop_categories_list(void)
{
char **keys;
int num, i;
Efreet_Cache_Array_String *array;
Eina_List *ret = NULL;
unsigned int i;
if (!efreet_cache_check(&cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL;
keys = eet_list(cache, "*::ca", &num);
if (!keys) return NULL;
for (i = 0; i < num; i++)
{
const char *data;
int size;
data = eet_read_direct(cache, keys[i], &size);
if (!data) continue;
if (eina_list_search_unsorted(ret, EINA_COMPARE_CB(strcmp), data)) continue;
ret = eina_list_append(ret, data);
}
free(keys);
array = eet_data_read(cache, efreet_array_string_edd(), "categories_list");
if (!array) return NULL;
for (i = 0; i < array->array_count; i++)
ret = eina_list_append(ret, array->array[i]);
efreet_cache_array_string_free(array);
return ret;
}
@ -439,7 +468,7 @@ efreet_util_desktop_categories_list(void)
EAPI Eina_List *
efreet_util_desktop_category_list(const char *category)
{
return efreet_util_cache_list("*::ca", category);
return efreet_util_cache_list("categories", category);
}
static int
@ -505,104 +534,114 @@ efreet_util_menus_find_helper(Eina_List *menus, const char *config_dir)
static Efreet_Desktop *
efreet_util_cache_find(const char *search, const char *what1, const char *what2)
{
char **keys;
int num, i;
Efreet_Cache_Hash *hash;
Efreet_Desktop *ret = NULL;
Efreet_Cache_Array_String *array = NULL;
char key[256];
if (!efreet_cache_check(&cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL;
if ((!what1) && (!what2)) return NULL;
keys = eet_list(cache, search, &num);
if (!keys) return NULL;
for (i = 0; i < num; i++)
snprintf(key, sizeof(key), "%s_hash", search);
hash = eet_data_read(cache, efreet_hash_array_string_edd(), key);
if (!hash) return NULL;
if (what1)
array = eina_hash_find(hash->hash, what1);
if (!array && what2) array = eina_hash_find(hash->hash, what2);
if (array)
{
const char *data;
int size, id;
char key[PATH_MAX];
unsigned int i;
data = eet_read_direct(cache, keys[i], &size);
if (!data) continue;
if (!((what1 && !strcmp(what1, data)) ||
(what2 && !strcmp(what2, data)))) continue;
id = atoi(keys[i]);
snprintf(key, sizeof(key), "%d::op", id);
data = eet_read_direct(cache, key, &size);
if (!data) continue;
ret = efreet_desktop_get(data);
if (ret) break;
for (i = 0; i < array->array_count; i++)
{
ret = efreet_desktop_get(array->array[i]);
if (ret) break;
}
}
free(keys);
eina_hash_free(hash->hash);
free(hash);
return ret;
}
static Eina_List *
efreet_util_cache_list(const char *search, const char *what)
{
char **keys;
int num, i;
Efreet_Cache_Hash *hash;
Efreet_Cache_Array_String *array;
Eina_List *ret = NULL;
char key[256];
if (!efreet_cache_check(&cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL;
if (!what) return NULL;
keys = eet_list(cache, search, &num);
if (!keys) return NULL;
for (i = 0; i < num; i++)
snprintf(key, sizeof(key), "%s_hash", search);
hash = eet_data_read(cache, efreet_hash_array_string_edd(), key);
if (!hash) return NULL;
array = eina_hash_find(hash->hash, what);
if (array)
{
const char *data;
int size, id;
char key[PATH_MAX];
unsigned int i;
Efreet_Desktop *desk;
data = eet_read_direct(cache, keys[i], &size);
if (!data) continue;
if (strcmp(what, data)) continue;
id = atoi(keys[i]);
snprintf(key, sizeof(key), "%d::op", id);
data = eet_read_direct(cache, key, &size);
if (!data) continue;
desk = efreet_desktop_get(data);
if (desk)
ret = eina_list_append(ret, desk);
for (i = 0; i < array->array_count; i++)
{
desk = efreet_desktop_get(array->array[i]);
if (desk)
ret = eina_list_append(ret, desk);
}
}
free(keys);
eina_hash_free(hash->hash);
free(hash);
return ret;
}
static Eina_List *
efreet_util_cache_glob_list(const char *search, const char *what)
{
char **keys;
int num, i;
Efreet_Cache_Hash *hash = NULL;
Eina_List *ret = NULL;
Efreet_Cache_Array_String *names = NULL;
char key[256];
unsigned int i;
if (!efreet_cache_check(&cache, efreet_desktop_util_cache_file(), EFREET_DESKTOP_UTILS_CACHE_MAJOR)) return NULL;
if (!what) return NULL;
keys = eet_list(cache, search, &num);
if (!keys) return NULL;
for (i = 0; i < num; i++)
snprintf(key, sizeof(key), "%s_list", search);
names = eet_data_read(cache, efreet_array_string_edd(), key);
if (!names) goto error;
for (i = 0; i < names->array_count; i++)
{
const char *data;
int size, id;
char key[PATH_MAX];
Efreet_Cache_Array_String *array;
unsigned int j;
Efreet_Desktop *desk;
data = eet_read_direct(cache, keys[i], &size);
if (!data) continue;
if (!efreet_util_glob_match(data, what)) continue;
if (!efreet_util_glob_match(names->array[i], what)) continue;
id = atoi(keys[i]);
snprintf(key, sizeof(key), "%d::op", id);
data = eet_read_direct(cache, key, &size);
if (!data) continue;
desk = efreet_desktop_get(data);
if (desk)
ret = eina_list_append(ret, desk);
if (!hash)
{
snprintf(key, sizeof(key), "%s_hash", search);
hash = eet_data_read(cache, efreet_hash_array_string_edd(), key);
}
if (!hash) goto error;
array = eina_hash_find(hash->hash, names->array[i]);
if (!array) continue;
for (j = 0; j < array->array_count; j++)
{
desk = efreet_desktop_get(array->array[j]);
if (desk)
ret = eina_list_append(ret, desk);
}
}
free(keys);
error:
if (hash)
{
eina_hash_free(hash->hash);
free(hash);
}
if (names)
efreet_cache_array_string_free(names);
return ret;
}