From 0e31062f43c22a119966aecac047cb90cb3bfcd9 Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Mon, 24 Mar 2014 12:15:49 +0000 Subject: Add as_node_take_attribute() to reduce allocations during parse This speeds up parsing by a couple of ms, but reduces the memory footprint by a few kb. --- libappstream-glib/as-app.c | 21 ++++++++------- libappstream-glib/as-node-private.h | 2 ++ libappstream-glib/as-node.c | 53 ++++++++++++++++++++++++++++++++++--- libappstream-glib/as-release.c | 12 ++++++--- 4 files changed, 70 insertions(+), 18 deletions(-) diff --git a/libappstream-glib/as-app.c b/libappstream-glib/as-app.c index 081b746..7425772 100644 --- a/libappstream-glib/as-app.c +++ b/libappstream-glib/as-app.c @@ -1377,21 +1377,21 @@ as_app_node_parse_child (AsApp *app, GNode *n, GError **error) /* */ case AS_TAG_NAME: - tmp = as_node_get_attribute (n, "xml:lang"); - if (tmp == NULL) - tmp = "C"; + taken = as_node_take_attribute (n, "xml:lang"); + if (taken == NULL) + taken = g_strdup ("C"); g_hash_table_insert (priv->names, - g_strdup (tmp), + taken, as_node_take_data (n)); break; /* */ case AS_TAG_SUMMARY: - tmp = as_node_get_attribute (n, "xml:lang"); - if (tmp == NULL) - tmp = "C"; + taken = as_node_take_attribute (n, "xml:lang"); + if (taken == NULL) + taken = g_strdup ("C"); g_hash_table_insert (priv->comments, - g_strdup (tmp), + taken, as_node_take_data (n)); break; @@ -1539,14 +1539,15 @@ as_app_node_parse_child (AsApp *app, GNode *n, GError **error) case AS_TAG_METADATA: g_hash_table_remove_all (priv->metadata); for (c = n->children; c != NULL; c = c->next) { + gchar *key; if (g_strcmp0 (as_node_get_name (c), "value") != 0) continue; - tmp = as_node_get_attribute (c, "key"); + key = as_node_take_attribute (c, "key"); taken = as_node_take_data (c); if (taken == NULL) taken = g_strdup (""); g_hash_table_insert (priv->metadata, - g_strdup (tmp), + key, taken); } break; diff --git a/libappstream-glib/as-node-private.h b/libappstream-glib/as-node-private.h index 3947a26..71a01a1 100644 --- a/libappstream-glib/as-node-private.h +++ b/libappstream-glib/as-node-private.h @@ -31,6 +31,8 @@ G_BEGIN_DECLS gchar *as_node_take_data (const GNode *node); +gchar *as_node_take_attribute (const GNode *node, + const gchar *key); void as_node_set_data (GNode *node, const gchar *cdata, gssize cdata_len, diff --git a/libappstream-glib/as-node.c b/libappstream-glib/as-node.c index 1256687..a4eee71 100644 --- a/libappstream-glib/as-node.c +++ b/libappstream-glib/as-node.c @@ -94,10 +94,10 @@ as_node_attr_insert (AsNodeData *data, const gchar *key, const gchar *value) } /** - * as_node_attr_lookup: + * as_node_attr_find: **/ -static const gchar * -as_node_attr_lookup (AsNodeData *data, const gchar *key) +static AsNodeAttr * +as_node_attr_find (AsNodeData *data, const gchar *key) { AsNodeAttr *attr; GList *l; @@ -105,11 +105,24 @@ as_node_attr_lookup (AsNodeData *data, const gchar *key) for (l = data->attrs; l != NULL; l = l->next) { attr = l->data; if (g_strcmp0 (attr->key, key) == 0) - return attr->value; + return attr; } return NULL; } +/** + * as_node_attr_lookup: + **/ +static const gchar * +as_node_attr_lookup (AsNodeData *data, const gchar *key) +{ + AsNodeAttr *attr; + attr = as_node_attr_find (data, key); + if (attr != NULL) + return attr->value; + return NULL; +} + /** * as_node_destroy_node_cb: **/ @@ -825,6 +838,38 @@ as_node_get_attribute (const GNode *node, const gchar *key) return as_node_attr_lookup (data, key); } +/** + * as_node_take_attribute: (skip) + * @node: a #GNode + * @key: the attribute key + * + * Gets a node attribute, e.g. "false" + * + * Return value: string value + * + * Since: 0.1.2 + **/ +gchar * +as_node_take_attribute (const GNode *node, const gchar *key) +{ + AsNodeAttr *attr; + AsNodeData *data; + gchar *tmp; + + g_return_val_if_fail (node != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (node->data == NULL) + return NULL; + data = (AsNodeData *) node->data; + attr = as_node_attr_find (data, key); + if (attr == NULL) + return NULL; + tmp = attr->value; + attr->value = NULL; + return tmp; +} + /** * as_node_add_attribute: (skip) * @node: a #GNode diff --git a/libappstream-glib/as-release.c b/libappstream-glib/as-release.c index 635b192..af28d1f 100644 --- a/libappstream-glib/as-release.c +++ b/libappstream-glib/as-release.c @@ -259,16 +259,20 @@ as_release_node_insert (AsRelease *release, GNode *parent, gdouble api_version) gboolean as_release_node_parse (AsRelease *release, GNode *node, GError **error) { - const gchar *tmp; + AsReleasePrivate *priv = GET_PRIVATE (release); GNode *n; GString *xml; + const gchar *tmp; + gchar *taken; tmp = as_node_get_attribute (node, "timestamp"); if (tmp != NULL) as_release_set_timestamp (release, atol (tmp)); - tmp = as_node_get_attribute (node, "version"); - if (tmp != NULL) - as_release_set_version (release, tmp, -1); + taken = as_node_take_attribute (node, "version"); + if (taken != NULL) { + g_free (priv->version); + priv->version = taken; + } /* descriptions are translated and optional */ for (n = node->children; n != NULL; n = n->next) { -- cgit v1.2.1