ethumb: cache exists result.

SVN revision: 59017
This commit is contained in:
Cedric BAIL 2011-04-28 17:00:13 +00:00
parent fc27a465a3
commit 88745904b4
3 changed files with 163 additions and 24 deletions

View File

@ -1563,7 +1563,7 @@ ethumb_exists(Ethumb *e)
return r;
}
Evas *
EAPI Evas *
ethumb_evas_get(const Ethumb *e)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(e, NULL);
@ -1571,7 +1571,7 @@ ethumb_evas_get(const Ethumb *e)
return e->sub_e;
}
Ecore_Evas *
EAPI Ecore_Evas *
ethumb_ecore_evas_get(const Ethumb *e)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(e, NULL);
@ -1579,7 +1579,7 @@ ethumb_ecore_evas_get(const Ethumb *e)
return e->sub_ee;
}
Ethumb *
EAPI Ethumb *
ethumb_dup(const Ethumb *e)
{
Ecore_Evas *ee;
@ -1659,7 +1659,7 @@ ethumb_dup(const Ethumb *e)
if (e1->Param != e2->Param) \
return EINA_TRUE;
Eina_Bool
EAPI Eina_Bool
ethumb_cmp(const Ethumb *e1, const Ethumb *e2)
{
CHECK_DELTA(thumb_dir);
@ -1684,3 +1684,89 @@ ethumb_cmp(const Ethumb *e1, const Ethumb *e2)
return EINA_FALSE;
}
EAPI unsigned int
ethumb_length(__UNUSED__ const void *key)
{
return sizeof (Ethumb);
}
#define CMP_PARAM(Param) \
if (e1->Param != e2->Param) \
return e1->Param - e2->Param;
EAPI int
ethumb_key_cmp(const void *key1, __UNUSED__ int key1_length,
const void *key2, __UNUSED__ int key2_length)
{
const Ethumb *e1 = key1;
const Ethumb *e2 = key2;
CMP_PARAM(thumb_dir);
CMP_PARAM(category);
CMP_PARAM(thumb_dir);
CMP_PARAM(category);
CMP_PARAM(tw);
CMP_PARAM(th);
CMP_PARAM(format);
CMP_PARAM(aspect);
CMP_PARAM(orientation);
CMP_PARAM(crop_x);
CMP_PARAM(crop_y);
CMP_PARAM(quality);
CMP_PARAM(compress);
CMP_PARAM(rw);
CMP_PARAM(rh);
CMP_PARAM(video.start);
CMP_PARAM(video.time);
CMP_PARAM(video.interval);
CMP_PARAM(video.ntimes);
CMP_PARAM(video.fps);
CMP_PARAM(document.page);
CMP_PARAM(src_path);
CMP_PARAM(src_key);
return 0;
}
#undef CMP_PARAM
#define HASH_PARAM_I(Param) r ^= eina_hash_int32((unsigned int*) &e->Param, 0);
#ifdef __LP64__
# define HASH_PARAM_P(Param) r ^= eina_hash_int64((unsigned long int*) &e->Param, 0);
#else
# define HASH_PARAM_P(Param) r ^= eina_hash_int32((unsigned int*) &e->Param, 0);
#endif
#define HASH_PARAM_D(Param) r ^= eina_hash_int64((unsigned long int*)&e->Param, 0);
#define HASH_PARAM_F(Param) r ^= eina_hash_int32((unsigned int*) &e->Param, 0);
EAPI int
ethumb_hash(const void *key, int key_length)
{
const Ethumb *e = key;
int r = 0;
HASH_PARAM_P(thumb_dir);
HASH_PARAM_P(category);
HASH_PARAM_I(tw);
HASH_PARAM_I(th);
HASH_PARAM_I(format);
HASH_PARAM_I(aspect);
HASH_PARAM_I(orientation);
HASH_PARAM_F(crop_x);
HASH_PARAM_F(crop_y);
HASH_PARAM_I(quality);
HASH_PARAM_I(compress);
HASH_PARAM_P(src_path);
HASH_PARAM_P(src_key);
HASH_PARAM_I(rw);
HASH_PARAM_I(rh);
HASH_PARAM_D(video.start);
HASH_PARAM_D(video.time);
HASH_PARAM_D(video.interval);
HASH_PARAM_I(video.ntimes);
HASH_PARAM_I(video.fps);
HASH_PARAM_I(document.page);
return r;
}

View File

@ -186,6 +186,10 @@ EAPI Eina_Bool ethumb_exists(Ethumb *e) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL
EAPI Ethumb *ethumb_dup(const Ethumb *e) EINA_ARG_NONNULL(1);
EAPI Eina_Bool ethumb_cmp(const Ethumb *e1, const Ethumb *e2) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT EINA_PURE;
EAPI int ethumb_hash(const void *key, int key_length) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT EINA_PURE;
EAPI int ethumb_key_cmp(const void *key1, int key1_length,
const void *key2, int key2_length) EINA_ARG_NONNULL(1, 3) EINA_WARN_UNUSED_RESULT EINA_PURE;
EAPI unsigned int ethumb_length(const void *key) EINA_PURE EINA_WARN_UNUSED_RESULT;
/**
* @}

View File

@ -169,14 +169,14 @@ struct _ethumb_pending_gen
};
typedef struct _Ethumb_Async_Exists Ethumb_Async_Exists;
typedef struct _Ethumb_Async_Exists_Cb Ethumb_Async_Exists_Cb;
struct _Ethumb_Async_Exists
{
Ethumb *dup;
Ethumb_Client *source;
Ethumb_Client_Thumb_Exists_Cb exists_cb;
const void *data;
Eina_List *callbacks;
Ecore_Thread *thread;
int refcount;
@ -184,6 +184,12 @@ struct _Ethumb_Async_Exists
Eina_Bool exists : 1;
};
struct _Ethumb_Async_Exists_Cb
{
Ethumb_Client_Thumb_Exists_Cb exists_cb;
const void *data;
};
static const char _ethumb_dbus_bus_name[] = "org.enlightenment.Ethumb";
static const char _ethumb_dbus_interface[] = "org.enlightenment.Ethumb";
static const char _ethumb_dbus_objects_interface[] = "org.enlightenment.Ethumb.objects";
@ -193,6 +199,7 @@ static const char fdo_bus_name[] = "org.freedesktop.DBus";
static const char fdo_path[] = "/org/freedesktop/DBus";
static int _initcount = 0;
static Eina_Hash *_exists_request = NULL;
static void _ethumb_client_generated_cb(void *data, DBusMessage *msg);
static void _ethumb_client_get_name_owner(void *data, DBusMessage *msg, DBusError *err);
@ -251,6 +258,20 @@ __dbus_iter_type_check(int type, int expected, const char *expected_name)
} \
while (0)
static void
_ethumb_async_delete(void *data)
{
Ethumb_Async_Exists *async = data;
ethumb_free(async->dup);
async->source->refcount--;
if (async->source->delete_me == EINA_TRUE)
ethumb_client_disconnect(async->source);
free(async);
}
static void
_ethumb_client_name_owner_changed(void *data, DBusMessage *msg)
{
@ -495,40 +516,38 @@ static void
_ethumb_client_exists_end(void *data, Ecore_Thread *thread)
{
Ethumb_Async_Exists *async = data;
Ethumb_Async_Exists_Cb *cb;
Ethumb *tmp = async->source->ethumb;
async->source->ethumb = async->dup;
async->source->ethumb_dirty = ethumb_cmp(tmp, async->dup);
async->exists_cb(async->source, (Ethumb_Exists*) async, async->exists, (void*) async->data);
EINA_LIST_FREE(async->callbacks, cb)
cb->exists_cb(async->source, (Ethumb_Exists*) async, async->exists, (void*) cb->data);
async->source->ethumb = tmp;
async->thread = NULL;
ethumb_free(async->dup);
async->source->refcount--;
if (async->source->delete_me == EINA_TRUE)
ethumb_client_disconnect(async->source);
free(async);
eina_hash_del(_exists_request, async->dup, async);
}
static void
_ethumb_client_exists_cancel(void *data, Ecore_Thread *thread)
{
Ethumb_Async_Exists_Cb *cb;
Ethumb_Async_Exists *async = data;
Ethumb *tmp = async->source->ethumb;
async->source->ethumb = async->dup;
async->source->ethumb_dirty = ethumb_cmp(tmp, async->dup);
async->exists_cb(async->source, (Ethumb_Exists*) async, EINA_FALSE, (void*) async->data);
EINA_LIST_FREE(async->callbacks, cb)
cb->exists_cb(async->source, (Ethumb_Exists*) async, EINA_FALSE, (void*) cb->data);
async->source->ethumb = tmp;
async->thread = NULL;
ethumb_free(async->dup);
async->source->refcount--;
if (async->source->delete_me == EINA_TRUE)
ethumb_client_disconnect(async->source);
free(async);
eina_hash_del(_exists_request, async->dup, async);
}
/**
@ -574,6 +593,12 @@ ethumb_client_init(void)
ethumb_init();
e_dbus_init();
_exists_request = eina_hash_new(ethumb_length,
ethumb_key_cmp,
ethumb_hash,
_ethumb_async_delete,
3);
return ++_initcount;
}
@ -600,6 +625,8 @@ ethumb_client_shutdown(void)
if (_initcount > 0)
return _initcount;
/* should find a non racy solution to closing all pending exists request */
e_dbus_shutdown();
ethumb_shutdown();
eina_log_domain_unregister(_log_dom);
@ -2122,13 +2149,33 @@ ethumb_client_thumb_path_get(Ethumb_Client *client, const char **path, const cha
EAPI Ethumb_Exists *
ethumb_client_thumb_exists(Ethumb_Client *client, Ethumb_Client_Thumb_Exists_Cb exists_cb, const void *data)
{
Ethumb_Async_Exists_Cb *cb;
Ethumb_Async_Exists *async;
EINA_SAFETY_ON_NULL_RETURN_VAL(client, NULL);
cb = malloc(sizeof (Ethumb_Async_Exists_Cb));
if (!cb)
{
exists_cb(client, NULL, EINA_FALSE, (void*) data);
return NULL;
}
cb->exists_cb = exists_cb;
cb->data = data;
async = eina_hash_find(_exists_request, client->ethumb);
if (async)
{
async->refcount++;
async->callbacks = eina_list_append(async->callbacks, cb);
return (Ethumb_Exists*) async;
}
async = malloc(sizeof (Ethumb_Async_Exists));
if (!async)
{
free(cb);
exists_cb(client, NULL, EINA_FALSE, (void*) data);
return NULL;
}
@ -2136,16 +2183,18 @@ ethumb_client_thumb_exists(Ethumb_Client *client, Ethumb_Client_Thumb_Exists_Cb
async->dup = ethumb_dup(client->ethumb);
async->source = client;
async->source->refcount++;
async->exists_cb = exists_cb;
async->data = data;
async->exists = EINA_FALSE;
async->callbacks = eina_list_append(NULL, cb);
async->refcount = 1;
async->thread = ecore_thread_run(_ethumb_client_exists_heavy,
_ethumb_client_exists_end,
_ethumb_client_exists_cancel,
async);
eina_hash_direct_add(_exists_request, async->dup, async);
return (Ethumb_Exists*) async;
}