summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2014-03-24 12:15:49 +0000
committerRichard Hughes <richard@hughsie.com>2014-03-24 12:18:06 +0000
commit0e31062f43c22a119966aecac047cb90cb3bfcd9 (patch)
tree9ab1f1b813cea424088c7378834e597a61459e88
parent9399965ae26c0314071d34dc823c511503bd2b7c (diff)
downloadappstream-glib-0e31062f43c22a119966aecac047cb90cb3bfcd9.tar.gz
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.
-rw-r--r--libappstream-glib/as-app.c21
-rw-r--r--libappstream-glib/as-node-private.h2
-rw-r--r--libappstream-glib/as-node.c53
-rw-r--r--libappstream-glib/as-release.c12
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)
/* <name> */
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;
/* <summary> */
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,12 +105,25 @@ 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:
**/
static gboolean
@@ -826,6 +839,38 @@ as_node_get_attribute (const GNode *node, const gchar *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
* @key: the attribute key
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) {