a start on the eap cache - it can load and save right now but not update once

saved. its disabled atm.

BUT i have reduced the data needing to be loaded at startup from opening 200
eap files totalling something like 6.5Mb of disk space used (though actual
loads will be less - likely), down to loading 1 file of about 7kb and doing a
stat or 2 on each file (my next phase is to remove the stat on startup here
and cache that info too, and then add in the code to have e slowly run over
the cache data and match it up against real life data and see if its still
valid or not etc. and write it out as well as make sure new caches are
written out whenever eapp dirs change, and then finally make a cmd-line tool
to do it per dir)


SVN revision: 16922
This commit is contained in:
Carsten Haitzler 2005-09-24 17:25:48 +00:00
parent f4498d11a3
commit 7dbb6fbe66
4 changed files with 446 additions and 47 deletions

View File

@ -32,8 +32,6 @@ struct _E_App_Callback
static void _e_app_free (E_App *a);
static void _e_app_fields_fill (E_App *a, const char *path);
static void _e_app_fields_empty (E_App *a);
static Ecore_List *_e_app_dir_file_list_get (E_App *a);
static E_App *_e_app_subapp_file_find (E_App *a, const char *file);
static void _e_app_change (E_App *a, E_App_Change ch);
static int _e_apps_cb_exit (void *data, int type, void *event);
@ -66,6 +64,7 @@ e_app_init(void)
char *home;
char buf[PATH_MAX];
e_app_cache_init();
home = e_user_homedir_get();
snprintf(buf, sizeof(buf), "%s/.e/e/applications/trash", home);
_e_apps_path_trash = strdup(buf);
@ -114,15 +113,124 @@ e_app_shutdown(void)
printf("BUG: References %d %s\n", E_OBJECT(a)->references, a->path);
}
}
e_app_cache_shutdown();
return 1;
}
E_App *
e_app_raw_new(void)
{
E_App *a;
a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
return a;
}
static void
_e_app_cache_copy(E_App_Cache *ac, E_App *a)
{
#define IF_DUP(x) if (ac->x) a->x = strdup(ac->x)
IF_DUP(name);
IF_DUP(generic);
IF_DUP(comment);
IF_DUP(exe);
IF_DUP(win_name);
IF_DUP(win_class);
IF_DUP(win_title);
IF_DUP(win_role);
IF_DUP(icon_class);
a->startup_notify = ac->startup_notify;
a->wait_exit = ac->wait_exit;
}
static E_App *
_e_app_cache_new(E_App_Cache *ac, char *path, int scan_subdirs)
{
Evas_List *l;
E_App *a;
char buf[PATH_MAX];
a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
_e_app_cache_copy(ac, a);
a->path = strdup(path);
a->scanned = 1;
for (l = ac->subapps; l; l = l->next)
{
E_App_Cache *ac2;
E_App *a2;
int is_dir;
ac2 = l->data;
snprintf(buf, sizeof(buf), "%s/%s", path, ac2->file);
is_dir = ecore_file_is_dir(buf);
if ((is_dir) && (scan_subdirs))
{
a2 = e_app_new(buf, scan_subdirs);
a2->parent = a;
a->subapps = evas_list_append(a->subapps, a2);
}
else
{
if (ecore_file_exists(buf))
{
a2 = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
_e_app_cache_copy(ac2, a2);
if (is_dir)
{
E_FREE(a2->exe);
}
a2->parent = a;
a2->path = strdup(buf);
a->subapps = evas_list_append(a->subapps, a2);
_e_apps = evas_hash_add(_e_apps, a2->path, a2);
_e_apps_list = evas_list_prepend(_e_apps_list, a2);
}
else
{
E_App *a3;
Evas_List *pl;
pl = _e_apps_repositories;
a2 = NULL;
while ((!a2) && (pl))
{
snprintf(buf, sizeof(buf), "%s/%s", (char *)pl->data, ac2->file);
a2 = e_app_new(buf, scan_subdirs);
pl = pl->next;
}
if (a2)
{
a3 = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
if (a3)
{
if (_e_app_copy(a3, a2))
{
a3->parent = a;
a->subapps = evas_list_append(a->subapps, a3);
a2->references = evas_list_append(a2->references, a3);
}
else
e_object_del(E_OBJECT(a3));
}
}
}
}
}
/* FIXME: create timer object to scan this slowly and fixup */
// and at the end of the slow scan add this:
// a->monitor = ecore_file_monitor_add(a->path, _e_app_cb_monitor, a);
return a;
}
E_App *
e_app_new(const char *path, int scan_subdirs)
{
E_App *a;
char buf[PATH_MAX];
E_App_Cache *ac;
a = evas_hash_find(_e_apps, path);
if (a)
{
@ -131,46 +239,64 @@ e_app_new(const char *path, int scan_subdirs)
e_object_ref(E_OBJECT(a));
return a;
}
if (ecore_file_exists(path))
/*
ac = e_app_cache_load((char *)path);
if (ac)
{
a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
/* record the path */
a->path = strdup(path);
if (ecore_file_is_dir(a->path))
a = _e_app_cache_new(ac, path, scan_subdirs);
if (a)
{
snprintf(buf, sizeof(buf), "%s/.directory.eap", path);
if (ecore_file_exists(buf))
_e_app_fields_fill(a, buf);
else
a->name = strdup(ecore_file_get_file(a->path));
if (scan_subdirs) e_app_subdir_scan(a, scan_subdirs);
a->monitor = ecore_file_monitor_add(a->path, _e_app_cb_monitor, a);
_e_apps = evas_hash_add(_e_apps, a->path, a);
_e_apps_list = evas_list_prepend(_e_apps_list, a);
}
else if (_e_app_is_eapp(path))
e_app_cache_free(ac);
}
else
*/
{
if (ecore_file_exists(path))
{
_e_app_fields_fill(a, path);
/* no exe field.. not valid. drop it */
if (!a->exe)
a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
/* record the path */
a->path = strdup(path);
if (ecore_file_is_dir(a->path))
{
snprintf(buf, sizeof(buf), "%s/.directory.eap", path);
if (ecore_file_exists(buf))
e_app_fields_fill(a, buf);
else
a->name = strdup(ecore_file_get_file(a->path));
if (scan_subdirs) e_app_subdir_scan(a, scan_subdirs);
a->monitor = ecore_file_monitor_add(a->path, _e_app_cb_monitor, a);
}
else if (_e_app_is_eapp(path))
{
e_app_fields_fill(a, path);
/* no exe field.. not valid. drop it */
if (!a->exe)
goto error;
}
else
goto error;
}
else
goto error;
return NULL;
_e_apps = evas_hash_add(_e_apps, a->path, a);
_e_apps_list = evas_list_prepend(_e_apps_list, a);
ac = e_app_cache_generate(a);
e_app_cache_save(ac, a->path);
e_app_cache_free(ac);
}
else
return NULL;
_e_apps = evas_hash_add(_e_apps, a->path, a);
_e_apps_list = evas_list_prepend(_e_apps_list, a);
return a;
error:
if (a->monitor) ecore_file_monitor_del(a->monitor);
if (a->path) free(a->path);
_e_app_fields_empty(a);
e_app_fields_empty(a);
free(a);
return NULL;
}
@ -198,7 +324,8 @@ e_app_subdir_scan(E_App *a, int scan_subdirs)
Ecore_List *files;
char *s;
char buf[PATH_MAX];
E_App_Cache *ac;
E_OBJECT_CHECK(a);
E_OBJECT_TYPE_CHECK(a, E_APP_TYPE);
if (a->exe) return;
@ -212,7 +339,7 @@ e_app_subdir_scan(E_App *a, int scan_subdirs)
return;
}
a->scanned = 1;
files = _e_app_dir_file_list_get(a);
files = e_app_dir_file_list_get(a);
if (files)
{
while ((s = ecore_list_next(files)))
@ -263,6 +390,10 @@ e_app_subdir_scan(E_App *a, int scan_subdirs)
}
ecore_list_destroy(files);
}
ac = e_app_cache_generate(a);
e_app_cache_save(ac, a->path);
e_app_cache_free(ac);
}
int
@ -766,14 +897,14 @@ _e_app_free(E_App *a)
ecore_file_monitor_del(a->monitor);
_e_apps = evas_hash_del(_e_apps, a->path, a);
_e_apps_list = evas_list_remove(_e_apps_list, a);
_e_app_fields_empty(a);
e_app_fields_empty(a);
E_FREE(a->path);
free(a);
}
}
static void
_e_app_fields_fill(E_App *a, const char *path)
void
e_app_fields_fill(E_App *a, const char *path)
{
Eet_File *ef;
char buf[PATH_MAX];
@ -912,8 +1043,8 @@ _e_app_fields_fill(E_App *a, const char *path)
eet_close(ef);
}
static void
_e_app_fields_empty(E_App *a)
void
e_app_fields_empty(E_App *a)
{
E_FREE(a->name);
E_FREE(a->generic);
@ -926,8 +1057,8 @@ _e_app_fields_empty(E_App *a)
E_FREE(a->win_role);
}
static Ecore_List *
_e_app_dir_file_list_get(E_App *a)
Ecore_List *
e_app_dir_file_list_get(E_App *a)
{
Ecore_List *files, *files2;
char *file;
@ -1137,13 +1268,13 @@ _e_app_cb_monitor(void *data, Ecore_File_Monitor *em,
if ((event == ECORE_FILE_EVENT_CREATED_FILE)
|| (event == ECORE_FILE_EVENT_MODIFIED))
{
_e_app_fields_empty(app);
_e_app_fields_fill(app, path);
e_app_fields_empty(app);
e_app_fields_fill(app, path);
_e_app_change(app, E_APP_CHANGE);
}
else if (event == ECORE_FILE_EVENT_DELETED_FILE)
{
_e_app_fields_empty(app);
e_app_fields_empty(app);
app->name = strdup(ecore_file_get_file(app->path));
}
else
@ -1162,8 +1293,8 @@ _e_app_cb_monitor(void *data, Ecore_File_Monitor *em,
{
Evas_List *l;
_e_app_fields_empty(a2);
_e_app_fields_fill(a2, path);
e_app_fields_empty(a2);
e_app_fields_fill(a2, path);
_e_app_change(a2, E_APP_CHANGE);
for (l = a2->references; l; l = l->next)
@ -1240,7 +1371,7 @@ _e_app_subdir_rescan(E_App *app)
char buf[PATH_MAX];
char *s;
files = _e_app_dir_file_list_get(app);
files = e_app_dir_file_list_get(app);
if (files)
{
while ((s = ecore_list_next(files)))

View File

@ -96,6 +96,11 @@ EAPI E_App *e_app_file_find(char *file);
EAPI E_App *e_app_name_find(char *name);
EAPI E_App *e_app_generic_find(char *generic);
EAPI E_App *e_app_exe_find(char *exe);
EAPI void e_app_fields_fill(E_App *a, const char *path);
EAPI E_App *e_app_raw_new(void);
EAPI Ecore_List *e_app_dir_file_list_get(E_App *a);
EAPI void e_app_fields_empty(E_App *a);
#endif
#endif

View File

@ -2,3 +2,229 @@
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "e.h"
#define NEWD(str, typ) \
eet_data_descriptor_new(str, sizeof(typ), \
(void *(*) (void *))evas_list_next, \
(void *(*) (void *, void *))evas_list_append, \
(void *(*) (void *))evas_list_data, \
(void *(*) (void *))evas_list_free, \
(void (*) (void *, int (*) (void *, const char *, void *, void *), void *))evas_hash_foreach, \
(void *(*) (void *, const char *, void *))evas_hash_add, \
(void (*) (void *))evas_hash_free)
#define FREED(eed) \
if (eed) \
{ \
eet_data_descriptor_free((eed)); \
(eed) = NULL; \
}
#define NEWI(str, it, type) \
EET_DATA_DESCRIPTOR_ADD_BASIC(_e_app_cache_edd, E_App_Cache, str, it, type)
#define NEWL(str, it, type) \
EET_DATA_DESCRIPTOR_ADD_LIST(_e_app_cache_edd, E_App_Cache, str, it, type)
static void _e_eapp_cache_fill(E_App_Cache *ac, E_App *a);
static Eet_Data_Descriptor *_e_app_cache_edd = NULL;
int
e_app_cache_init(void)
{
_e_app_cache_edd = NEWD("E_App_Cache", E_App_Cache);
NEWI("nm", name, EET_T_STRING);
NEWI("gn", generic, EET_T_STRING);
NEWI("cm", comment, EET_T_STRING);
NEWI("ex", exe, EET_T_STRING);
NEWI("fl", file, EET_T_STRING);
NEWI("fm", file_mod_time, EET_T_ULONG_LONG);
NEWI("wn", win_name, EET_T_STRING);
NEWI("wc", win_class, EET_T_STRING);
NEWI("wt", win_title, EET_T_STRING);
NEWI("wr", win_role, EET_T_STRING);
NEWI("ic", icon_class, EET_T_STRING);
NEWL("ap", subapps, _e_app_cache_edd);
NEWI("sn", startup_notify, EET_T_UCHAR);
NEWI("wx", wait_exit, EET_T_UCHAR);
return 1;
}
int
e_app_cache_shutdown(void)
{
FREED(_e_app_cache_edd);
return 1;
}
E_App_Cache *
e_app_cache_load(char *path)
{
Eet_File *ef;
char buf[PATH_MAX];
E_App_Cache *ac;
if (!path) return NULL;
snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", path);
ef = eet_open(buf, EET_FILE_MODE_READ);
if (!ef) return NULL;
ac = eet_data_read(ef, _e_app_cache_edd, "cache");
eet_close(ef);
return ac;
}
E_App_Cache *
e_app_cache_generate(E_App *a)
{
E_App_Cache *ac;
Evas_List *l;
if (!a) return NULL;
ac = calloc(1, sizeof(E_App_Cache));
if (!ac) return NULL;
_e_eapp_cache_fill(ac, a);
for (l = a->subapps; l; l = l->next)
{
E_App *a2;
E_App_Cache *ac2;
a2 = l->data;
ac2 = calloc(1, sizeof(E_App_Cache));
if (ac2)
{
_e_eapp_cache_fill(ac2, a2);
ac->subapps = evas_list_append(ac->subapps, ac2);
ac->subapps_hash = evas_hash_add(ac->subapps_hash, ac2->file, ac2);
}
}
return ac;
}
E_App_Cache *
e_app_cache_path_generate(char *path)
{
E_App_Cache *ac;
E_App *a;
char buf[PATH_MAX];
Ecore_List *files;
if (!path) return NULL;
ac = calloc(1, sizeof(E_App_Cache));
if (!ac) return NULL;
a = e_app_raw_new();
a->path = strdup(path);
_e_eapp_cache_fill(ac, a);
if (ecore_file_is_dir(a->path))
{
snprintf(buf, sizeof(buf), "%s/.directory.eap", path);
if (ecore_file_exists(buf))
e_app_fields_fill(a, buf);
else
a->name = strdup(ecore_file_get_file(a->path));
files = e_app_dir_file_list_get(a);
if (files)
{
char *s = NULL;
while ((s = ecore_list_next(files)))
{
E_App *a2;
E_App_Cache *ac2;
ac2 = calloc(1, sizeof(E_App_Cache));
if (ac2)
{
a2 = e_app_raw_new();
if (a2)
{
snprintf(buf, sizeof(buf), "%s/%s", a->path, s);
a2->path = strdup(buf);
if (ecore_file_is_dir(a2->path))
{
snprintf(buf, sizeof(buf), "%s/.directory.eap", a2->path);
e_app_fields_fill(a2, buf);
}
else
e_app_fields_fill(a2, a2->path);
_e_eapp_cache_fill(ac2, a2);
e_app_fields_empty(a2);
free(a2);
}
ac->subapps = evas_list_append(ac->subapps, ac2);
ac->subapps_hash = evas_hash_add(ac->subapps_hash, ac2->file, ac2);
}
}
ecore_list_destroy(files);
}
}
e_app_fields_empty(a);
free(a);
return ac;
}
void
e_app_cache_free(E_App_Cache *ac)
{
if (!ac) return;
E_FREE(ac->name);
E_FREE(ac->generic);
E_FREE(ac->comment);
E_FREE(ac->exe);
E_FREE(ac->file);
E_FREE(ac->win_name);
E_FREE(ac->win_class);
E_FREE(ac->win_title);
E_FREE(ac->win_role);
E_FREE(ac->icon_class);
while (ac->subapps)
{
E_App_Cache *ac2;
ac2 = ac->subapps->data;
ac->subapps = evas_list_remove_list(ac->subapps, ac->subapps);
e_app_cache_free(ac2);
}
evas_hash_free(ac->subapps_hash);
free(ac);
}
int
e_app_cache_save(E_App_Cache *ac, char *path)
{
Eet_File *ef;
char buf[4096];
int ret;
if ((!ac) || (!path)) return 0;
snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", path);
ef = eet_open(buf, EET_FILE_MODE_WRITE);
if (!ef) return 0;
ret = eet_data_write(ef, _e_app_cache_edd, "cache", ac, 1);
eet_close(ef);
return ret;
}
static void
_e_eapp_cache_fill(E_App_Cache *ac, E_App *a)
{
#define IF_DUP(x) if (a->x) ac->x = strdup(a->x)
IF_DUP(name);
IF_DUP(generic);
IF_DUP(comment);
IF_DUP(exe);
ac->file = strdup(ecore_file_get_file(a->path));
ac->file_mod_time = ecore_file_mod_time(a->path);
IF_DUP(win_name);
IF_DUP(win_class);
IF_DUP(win_title);
IF_DUP(win_role);
IF_DUP(icon_class);
ac->startup_notify = a->startup_notify;
ac->wait_exit = a->wait_exit;
}

View File

@ -3,9 +3,46 @@
*/
#ifdef E_TYPEDEFS
typedef struct _E_App_Cache E_App_Cache;
#else
#ifndef E_APPS_CACHE_H
#define E_APPS_CAHCE_H
#define E_APPS_CACHE_H
struct _E_App_Cache
{
char *name; /* app name */
char *generic; /* generic app name */
char *comment; /* a longer description */
char *exe; /* command to execute, NULL if directory */
char *file; /* the .eap filename */
unsigned long long file_mod_time; /* the last modified time of the file */
char *win_name; /* window name */
char *win_class; /* window class */
char *win_title; /* window title */
char *win_role; /* window role */
char *icon_class; /* icon_class */
Evas_List *subapps; /* if this a directory, a list of more E_App's */
unsigned char startup_notify; /* disable while starting etc. */
unsigned char wait_exit; /* wait for app to exit before execing next */
/* these are generated post-load */
Evas_Hash *subapps_hash; /* a quick lookup hash */
};
EAPI int e_app_cache_init(void);
EAPI int e_app_cache_shutdown(void);
EAPI E_App_Cache *e_app_cache_load(char *path);
EAPI E_App_Cache *e_app_cache_generate(E_App *a);
EAPI E_App_Cache *e_app_cache_path_generate(char *path);
EAPI void e_app_cache_free(E_App_Cache *ac);
EAPI int e_app_cache_save(E_App_Cache *ac, char *path);
#endif
#endif