[gom] gom: Don't do get/set properties in != main thread when reading
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gom] gom: Don't do get/set properties in != main thread when reading
- Date: Wed, 5 Nov 2014 17:36:17 +0000 (UTC)
commit b43eb35b1d715dd29c50d792e2f210a481654a9b
Author: Bastien Nocera <hadess hadess net>
Date: Wed Nov 5 18:21:14 2014 +0100
gom: Don't do get/set properties in != main thread when reading
This is the 2nd part of b14e7044bf5cbfe4b6baac4b3ce66dba7dc8f458.
We now try to avoid creating, and setting GomResource items when reading
from the database. Instead, the items are created from cached results as
needed when gom_resource_group_get_index() is called.
https://bugzilla.gnome.org/show_bug.cgi?id=728301
gom/gom-resource-group.c | 110 ++++++++++++++++++++++++++++++++++++----------
1 files changed, 87 insertions(+), 23 deletions(-)
---
diff --git a/gom/gom-resource-group.c b/gom/gom-resource-group.c
index eef37c5..5aa6f31 100644
--- a/gom/gom-resource-group.c
+++ b/gom/gom-resource-group.c
@@ -60,6 +60,11 @@ enum
LAST_PROP
};
+typedef struct {
+ GomResource *resource;
+ GHashTable *ht;
+} ItemData;
+
static GParamSpec *gParamSpecs[LAST_PROP];
GomResourceGroup *
@@ -363,21 +368,68 @@ gom_resource_group_set_resource_type (GomResourceGroup *group,
}
static void
-set_props (GomResource *resource,
- GomCursor *cursor)
+value_free (gpointer data)
+{
+ GValue *value = data;
+
+ if (value == NULL)
+ return;
+ g_value_unset(value);
+ g_free(value);
+}
+
+static void
+item_data_free (gpointer data)
+{
+ ItemData *itemdata = data;
+ if (itemdata == NULL)
+ return;
+ g_clear_object(&itemdata->resource);
+ g_clear_pointer(&itemdata->ht, g_hash_table_destroy);
+}
+
+static void
+foreach_prop (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ g_object_set_property(user_data, key, value);
+}
+
+static void
+item_data_ensure_resource (ItemData *itemdata,
+ GType resource_type,
+ GomRepository *repository)
+{
+ if (itemdata->resource)
+ return;
+
+ itemdata->resource = g_object_new(resource_type,
+ "repository", repository,
+ NULL);
+ g_hash_table_foreach(itemdata->ht, foreach_prop, itemdata->resource);
+ gom_resource_set_is_from_table(itemdata->resource, TRUE);
+ g_clear_pointer(&itemdata->ht, g_hash_table_destroy);
+}
+
+static ItemData *
+set_props (GType resource_type,
+ GomCursor *cursor)
{
GObjectClass *klass;
const gchar *name;
GParamSpec *pspec;
- GValue value = { 0 };
guint n_cols;
guint i;
+ GHashTable *ht;
+ ItemData *itemdata;
- g_assert(GOM_IS_RESOURCE(resource));
g_assert(GOM_IS_CURSOR(cursor));
- klass = G_OBJECT_GET_CLASS(resource);
+ klass = g_type_class_ref(resource_type);
n_cols = gom_cursor_get_n_columns(cursor);
+ ht = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, value_free);
for (i = 0; i < n_cols; i++) {
name = gom_cursor_get_column_name(cursor, i);
@@ -386,22 +438,32 @@ set_props (GomResource *resource,
from_bytes = g_param_spec_get_qdata(pspec, GOM_RESOURCE_FROM_BYTES_FUNC);
if (from_bytes) {
- GValue converted = { 0, };
+ GValue *converted;
+ GValue value = { 0, };
+ converted = g_new0 (GValue, 1);
g_value_init(&value, G_TYPE_BYTES);
gom_cursor_get_column(cursor, i, &value);
- (*from_bytes) (g_value_get_boxed(&value), &converted);
+ (*from_bytes) (g_value_get_boxed(&value), converted);
g_value_unset(&value);
- g_object_set_property(G_OBJECT(resource), name, &converted);
- g_value_unset(&converted);
+ g_hash_table_insert(ht, g_strdup(name), converted);
} else {
- g_value_init(&value, pspec->value_type);
- gom_cursor_get_column(cursor, i, &value);
- g_object_set_property(G_OBJECT(resource), name, &value);
- g_value_unset(&value);
+ GValue *value;
+
+ value = g_new0 (GValue, 1);
+ g_value_init(value, pspec->value_type);
+ gom_cursor_get_column(cursor, i, value);
+ g_hash_table_insert(ht, g_strdup(name), value);
}
}
}
+
+ g_type_class_unref (klass);
+
+ itemdata = g_new0(ItemData, 1);
+ itemdata->ht = ht;
+
+ return itemdata;
}
static void
@@ -412,7 +474,6 @@ gom_resource_group_fetch_cb (GomAdapter *adapter,
GomCommandBuilder *builder = NULL;
GomResourceGroup *group;
GomRepository *repository = NULL;
- GomResource *resource;
GomCommand *command = NULL;
GomCursor *cursor = NULL;
GomFilter *filter = NULL;
@@ -470,20 +531,19 @@ gom_resource_group_fetch_cb (GomAdapter *adapter,
if (!group->priv->items) {
group->priv->items = g_hash_table_new_full(g_int_hash, g_int_equal,
- g_free, g_object_unref);
+ g_free, item_data_free);
}
idx = offset;
while (gom_cursor_next(cursor)) {
- guint *key = g_new0(guint, 1);
+ ItemData *itemdata;
+ guint *key;
+
+ key = g_new0(guint, 1);
*key = idx++;
- resource = g_object_new(resource_type,
- "repository", repository,
- NULL);
- set_props(resource, cursor);
- gom_resource_set_is_from_table(resource, TRUE);
- g_hash_table_insert(group->priv->items, key, resource);
+ itemdata = set_props(resource_type, cursor);
+ g_hash_table_insert(group->priv->items, key, itemdata);
}
g_simple_async_result_set_op_res_gboolean(simple, TRUE);
@@ -618,7 +678,11 @@ gom_resource_group_get_index (GomResourceGroup *group,
priv = group->priv;
if (priv->items) {
- return g_hash_table_lookup(priv->items, &index_);
+ ItemData *itemdata;
+
+ itemdata = g_hash_table_lookup(priv->items, &index_);
+ item_data_ensure_resource(itemdata, priv->resource_type, priv->repository);
+ return itemdata->resource;
}
return NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]