[gnome-builder] egg-task-cache: add support for arbitrary boxed value types
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] egg-task-cache: add support for arbitrary boxed value types
- Date: Wed, 13 May 2015 20:43:43 +0000 (UTC)
commit c4aab8ae2789d97347bd60e83feca069bb51a82f
Author: Christian Hergert <christian hergert me>
Date: Wed May 13 13:40:51 2015 -0700
egg-task-cache: add support for arbitrary boxed value types
This allows us to support more than GObject now. We still do require that
the return type is a pointer though.
contrib/egg/egg-task-cache.c | 85 +++++++++++++++++++++++++++-----------
contrib/egg/egg-task-cache.h | 2 +
libide/clang/ide-clang-service.c | 2 +
tests/test-egg-cache.c | 2 +
4 files changed, 67 insertions(+), 24 deletions(-)
---
diff --git a/contrib/egg/egg-task-cache.c b/contrib/egg/egg-task-cache.c
index 9270683..cb2854b 100644
--- a/contrib/egg/egg-task-cache.c
+++ b/contrib/egg/egg-task-cache.c
@@ -32,6 +32,8 @@ struct _EggTaskCache
GEqualFunc key_equal_func;
GBoxedCopyFunc key_copy_func;
GBoxedFreeFunc key_destroy_func;
+ GBoxedCopyFunc value_copy_func;
+ GBoxedFreeFunc value_destroy_func;
EggTaskCacheCallback populate_callback;
gpointer populate_callback_data;
@@ -49,9 +51,10 @@ struct _EggTaskCache
typedef struct
{
- GObject *item;
- gpointer key;
- gint64 evict_at;
+ EggTaskCache *self;
+ gpointer key;
+ gpointer value;
+ gint64 evict_at;
} CacheItem;
typedef struct
@@ -79,6 +82,8 @@ enum {
PROP_POPULATE_CALLBACK_DATA,
PROP_POPULATE_CALLBACK_DATA_DESTROY,
PROP_TIME_TO_LIVE,
+ PROP_VALUE_COPY_FUNC,
+ PROP_VALUE_DESTROY_FUNC,
LAST_PROP
};
@@ -168,8 +173,11 @@ cache_item_free (gpointer data)
{
CacheItem *item = data;
- /* key is freed by g_hash_table to avoid needing self pointer. */
- g_object_unref (item->item);
+ item->self->key_destroy_func (item->key);
+ item->self->value_destroy_func (item->value);
+ item->self = NULL;
+ item->evict_at = 0;
+
g_slice_free (CacheItem, item);
}
@@ -184,17 +192,20 @@ cache_item_compare_evict_at (gconstpointer a,
}
static CacheItem *
-cache_item_new (gpointer key,
- GObject *item,
- gint64 time_to_live_usec)
+cache_item_new (EggTaskCache *self,
+ gconstpointer key,
+ gconstpointer value)
{
CacheItem *ret;
+ g_assert (EGG_IS_TASK_CACHE (self));
+
ret = g_slice_new0 (CacheItem);
- ret->key = key;
- ret->item = item;
- if (time_to_live_usec > 0)
- ret->evict_at = g_get_monotonic_time () + time_to_live_usec;
+ ret->self = self;
+ ret->key = self->key_copy_func ((gpointer)key);
+ ret->value = self->value_copy_func ((gpointer)value);
+ if (self->time_to_live_usec > 0)
+ ret->evict_at = g_get_monotonic_time () + self->time_to_live_usec;
return ret;
}
@@ -267,7 +278,7 @@ egg_task_cache_peek (EggTaskCache *self,
if ((item = g_hash_table_lookup (self->cache, key)))
{
EGG_COUNTER_INC (hits);
- return item->item;
+ return item->value;
}
return NULL;
@@ -316,12 +327,10 @@ egg_task_cache_populate (EggTaskCache *self,
g_assert (EGG_IS_TASK_CACHE (self));
g_assert (G_IS_OBJECT (value));
+ item = cache_item_new (self, key, value);
+
if (g_hash_table_contains (self->cache, key))
egg_task_cache_evict (self, key);
-
- item = cache_item_new (self->key_copy_func ((gpointer)key),
- g_object_ref (value),
- self->time_to_live_usec);
g_hash_table_insert (self->cache, item->key, item);
egg_heap_insert_val (self->evict_heap, item);
@@ -351,7 +360,9 @@ egg_task_cache_propagate_pointer (EggTaskCache *self,
GTask *task;
task = g_ptr_array_index (queued, i);
- g_task_return_pointer (task, g_object_ref (value), g_object_unref);
+ g_task_return_pointer (task,
+ self->value_copy_func (value),
+ self->value_destroy_func);
}
g_ptr_array_unref (queued);
@@ -391,11 +402,9 @@ egg_task_cache_fetch_cb (GObject *object,
g_hash_table_remove (self->in_flight, key);
EGG_COUNTER_DEC (in_flight);
- g_assert (!ret || G_IS_OBJECT (ret));
- g_clear_object (&ret);
-
self->key_destroy_func (key);
- g_object_unref (task);
+ if (ret != NULL)
+ self->value_destroy_func (ret);
}
void
@@ -420,7 +429,9 @@ egg_task_cache_get_async (EggTaskCache *self,
*/
if (!force_update && (ret = egg_task_cache_peek (self, key)))
{
- g_task_return_pointer (task, g_object_ref (ret), g_object_unref);
+ g_task_return_pointer (task,
+ self->value_copy_func (ret),
+ self->value_destroy_func);
return;
}
@@ -515,6 +526,8 @@ egg_task_cache_constructed (GObject *object)
(self->key_destroy_func == NULL) ||
(self->key_equal_func == NULL) ||
(self->key_hash_func == NULL) ||
+ (self->value_copy_func == NULL) ||
+ (self->value_destroy_func == NULL) ||
(self->populate_callback == NULL))
{
g_error ("EggTaskCache was configured improperly.");
@@ -526,7 +539,7 @@ egg_task_cache_constructed (GObject *object)
*/
self->cache = g_hash_table_new_full (self->key_hash_func,
self->key_equal_func,
- self->key_destroy_func,
+ NULL,
cache_item_free);
/*
@@ -676,6 +689,14 @@ egg_task_cache_set_property (GObject *object,
self->time_to_live_usec = (g_value_get_int64 (value) * 1000L);
break;
+ case PROP_VALUE_COPY_FUNC:
+ self->value_copy_func = g_value_get_pointer (value);
+ break;
+
+ case PROP_VALUE_DESTROY_FUNC:
+ self->value_destroy_func = g_value_get_pointer (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
@@ -750,6 +771,18 @@ egg_task_cache_class_init (EggTaskCacheClass *klass)
30 * 1000,
(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ gParamSpecs [PROP_VALUE_COPY_FUNC] =
+ g_param_spec_pointer ("value-copy-func",
+ _("Value Copy Func"),
+ _("Value Copy Func"),
+ (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ gParamSpecs [PROP_VALUE_DESTROY_FUNC] =
+ g_param_spec_pointer ("value-destroy-func",
+ _("Value Destroy Func"),
+ _("Value Destroy Func"),
+ (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
}
@@ -767,6 +800,8 @@ egg_task_cache_new (GHashFunc key_hash_func,
GEqualFunc key_equal_func,
GBoxedCopyFunc key_copy_func,
GBoxedFreeFunc key_destroy_func,
+ GBoxedCopyFunc value_copy_func,
+ GBoxedFreeFunc value_destroy_func,
gint64 time_to_live,
EggTaskCacheCallback populate_callback,
gpointer populate_callback_data,
@@ -787,5 +822,7 @@ egg_task_cache_new (GHashFunc key_hash_func,
"populate-callback-data", populate_callback_data,
"populate-callback-data-destroy", populate_callback_data_destroy,
"time-to-live", time_to_live,
+ "value-copy-func", value_copy_func,
+ "value-destroy-func", value_destroy_func,
NULL);
}
diff --git a/contrib/egg/egg-task-cache.h b/contrib/egg/egg-task-cache.h
index 10824e9..ef885c9 100644
--- a/contrib/egg/egg-task-cache.h
+++ b/contrib/egg/egg-task-cache.h
@@ -53,6 +53,8 @@ EggTaskCache *egg_task_cache_new (GHashFunc key_hash_func,
GEqualFunc key_equal_func,
GBoxedCopyFunc key_copy_func,
GBoxedFreeFunc key_destroy_func,
+ GBoxedCopyFunc value_copy_func,
+ GBoxedFreeFunc value_free_func,
gint64 time_to_live_msec,
EggTaskCacheCallback populate_callback,
gpointer populate_callback_data,
diff --git a/libide/clang/ide-clang-service.c b/libide/clang/ide-clang-service.c
index 4d2c3e5..c53a251 100644
--- a/libide/clang/ide-clang-service.c
+++ b/libide/clang/ide-clang-service.c
@@ -542,6 +542,8 @@ ide_clang_service_start (IdeService *service)
(GEqualFunc)ide_file_equal,
g_object_ref,
g_object_unref,
+ g_object_ref,
+ g_object_unref,
DEFAULT_EVICTION_MSEC,
ide_clang_service_get_translaction_unit_worker,
g_object_ref (self),
diff --git a/tests/test-egg-cache.c b/tests/test-egg-cache.c
index 4c72e8d..2ef24aa 100644
--- a/tests/test-egg-cache.c
+++ b/tests/test-egg-cache.c
@@ -42,6 +42,8 @@ test_task_cache (void)
g_str_equal,
(GBoxedCopyFunc)g_strdup,
(GBoxedFreeFunc)g_free,
+ g_object_ref,
+ g_object_unref,
100 /* msec */,
populate_callback, NULL, NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]