summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2016-11-17 13:46:28 +0000
committerRichard Hughes <richard@hughsie.com>2016-11-21 15:19:55 +0000
commit1e2dac494cb31234ce19e9eccac11ee920765a82 (patch)
tree4634de27f2e7f209b0f784fe7d17a389ad75bd0b
parentb5be1688c06fbd56d0d1661e5eda2aec09582d68 (diff)
downloadappstream-glib-1e2dac494cb31234ce19e9eccac11ee920765a82.tar.gz
Lazy load structures in AsRelease
This saves another 0.8Mb of RSS.
-rw-r--r--libappstream-glib/as-release.c62
1 files changed, 50 insertions, 12 deletions
diff --git a/libappstream-glib/as-release.c b/libappstream-glib/as-release.c
index 2e4f355..15be5bf 100644
--- a/libappstream-glib/as-release.c
+++ b/libappstream-glib/as-release.c
@@ -53,11 +53,11 @@ typedef struct
AsReleaseState state;
guint64 size[AS_SIZE_KIND_LAST];
AsRefString *version;
- GHashTable *blobs; /* of gchar*:GBytes */
+ GHashTable *blobs; /* of AsRefString:GBytes */
GHashTable *descriptions;
guint64 timestamp;
- GPtrArray *locations; /* of AsRefString */
- GPtrArray *checksums;
+ GPtrArray *locations; /* of AsRefString, lazy */
+ GPtrArray *checksums; /* of AsChecksum, lazy */
} AsReleasePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (AsRelease, as_release, G_TYPE_OBJECT)
@@ -72,9 +72,12 @@ as_release_finalize (GObject *object)
if (priv->version != NULL)
as_ref_string_unref (priv->version);
- g_hash_table_unref (priv->blobs);
- g_ptr_array_unref (priv->checksums);
- g_ptr_array_unref (priv->locations);
+ if (priv->blobs != NULL)
+ g_hash_table_unref (priv->blobs);
+ if (priv->checksums != NULL)
+ g_ptr_array_unref (priv->checksums);
+ if (priv->locations != NULL)
+ g_ptr_array_unref (priv->locations);
if (priv->descriptions != NULL)
g_hash_table_unref (priv->descriptions);
@@ -89,13 +92,37 @@ as_release_init (AsRelease *release)
priv->urgency = AS_URGENCY_KIND_UNKNOWN;
priv->state = AS_RELEASE_STATE_UNKNOWN;
- priv->locations = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref);
+ for (i = 0; i < AS_SIZE_KIND_LAST; i++)
+ priv->size[i] = 0;
+}
+
+static void
+as_release_ensure_checksums (AsRelease *release)
+{
+ AsReleasePrivate *priv = GET_PRIVATE (release);
+ if (priv->checksums != NULL)
+ return;
priv->checksums = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+}
+
+static void
+as_release_ensure_locations (AsRelease *release)
+{
+ AsReleasePrivate *priv = GET_PRIVATE (release);
+ if (priv->locations != NULL)
+ return;
+ priv->locations = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref);
+}
+
+static void
+as_release_ensure_blobs (AsRelease *release)
+{
+ AsReleasePrivate *priv = GET_PRIVATE (release);
+ if (priv->blobs != NULL)
+ return;
priv->blobs = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) as_ref_string_unref,
(GDestroyNotify) g_bytes_unref);
- for (i = 0; i < AS_SIZE_KIND_LAST; i++)
- priv->size[i] = 0;
}
static void
@@ -242,6 +269,8 @@ as_release_get_blob (AsRelease *release, const gchar *filename)
{
AsReleasePrivate *priv = GET_PRIVATE (release);
g_return_val_if_fail (filename != NULL, NULL);
+ if (priv->blobs == NULL)
+ return NULL;
return g_hash_table_lookup (priv->blobs, filename);
}
@@ -259,6 +288,7 @@ GPtrArray *
as_release_get_locations (AsRelease *release)
{
AsReleasePrivate *priv = GET_PRIVATE (release);
+ as_release_ensure_locations (release);
return priv->locations;
}
@@ -295,6 +325,7 @@ GPtrArray *
as_release_get_checksums (AsRelease *release)
{
AsReleasePrivate *priv = GET_PRIVATE (release);
+ as_release_ensure_checksums (release);
return priv->checksums;
}
@@ -342,6 +373,8 @@ as_release_get_checksum_by_target (AsRelease *release, AsChecksumTarget target)
AsReleasePrivate *priv = GET_PRIVATE (release);
guint i;
+ if (priv->checksums == NULL)
+ return NULL;
for (i = 0; i < priv->checksums->len; i++) {
checksum = g_ptr_array_index (priv->checksums, i);
if (as_checksum_get_target (checksum) == target)
@@ -421,6 +454,8 @@ as_release_set_blob (AsRelease *release, const gchar *filename, GBytes *blob)
AsReleasePrivate *priv = GET_PRIVATE (release);
g_return_if_fail (filename != NULL);
g_return_if_fail (blob != NULL);
+
+ as_release_ensure_blobs (release);
g_hash_table_insert (priv->blobs,
as_ref_string_new (filename),
g_bytes_ref (blob));
@@ -492,6 +527,7 @@ void
as_release_add_checksum (AsRelease *release, AsChecksum *checksum)
{
AsReleasePrivate *priv = GET_PRIVATE (release);
+ as_release_ensure_checksums (release);
g_ptr_array_add (priv->checksums, g_object_ref (checksum));
}
@@ -577,12 +613,12 @@ as_release_node_insert (AsRelease *release, GNode *parent, AsNodeContext *ctx)
as_node_add_attribute (n, "version", priv->version);
if (as_node_context_get_version (ctx) >= 0.9) {
const gchar *tmp;
- for (i = 0; i < priv->locations->len; i++) {
+ for (i = 0; priv->locations != NULL && i < priv->locations->len; i++) {
tmp = g_ptr_array_index (priv->locations, i);
as_node_insert (n, "location", tmp,
AS_NODE_INSERT_FLAG_NONE, NULL);
}
- for (i = 0; i < priv->checksums->len; i++) {
+ for (i = 0; priv->checksums != NULL && i < priv->checksums->len; i++) {
checksum = g_ptr_array_index (priv->checksums, i);
as_checksum_node_insert (checksum, n, ctx);
}
@@ -646,13 +682,15 @@ as_release_node_parse (AsRelease *release, GNode *node,
as_release_set_version (release, tmp);
/* get optional locations */
- g_ptr_array_set_size (priv->locations, 0);
+ if (priv->locations != NULL)
+ g_ptr_array_set_size (priv->locations, 0);
for (n = node->children; n != NULL; n = n->next) {
if (as_node_get_tag (n) != AS_TAG_LOCATION)
continue;
tmp = as_node_get_data (n);
if (tmp == NULL)
continue;
+ as_release_ensure_locations (release);
g_ptr_array_add (priv->locations, as_ref_string_ref (tmp));
}