diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2022-12-31 14:24:35 +0100 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2023-01-10 15:51:21 +0100 |
commit | ff9c769f3e15170ab8f3fd790d5b7b89e66bf430 (patch) | |
tree | 57f1542d92dcd343165e27d48dd215db141f8642 /src/libtracker-sparql | |
parent | 92696167b908b54aaf4b10da61df701018acea9a (diff) | |
download | tracker-ff9c769f3e15170ab8f3fd790d5b7b89e66bf430.tar.gz |
libtracker-sparql: Optimize tracker_namespace_manager_compress_uri()
Keep an array of expanded IRIs with their length, so that we can minimize
string comparisons (by checking the first/last chars match) and avoid
GHashTableIter.
Diffstat (limited to 'src/libtracker-sparql')
-rw-r--r-- | src/libtracker-sparql/tracker-namespace-manager.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/src/libtracker-sparql/tracker-namespace-manager.c b/src/libtracker-sparql/tracker-namespace-manager.c index 377feab81..f2eabdf00 100644 --- a/src/libtracker-sparql/tracker-namespace-manager.c +++ b/src/libtracker-sparql/tracker-namespace-manager.c @@ -31,8 +31,15 @@ #define MAX_PREFIX_LENGTH 100 typedef struct { + const gchar *prefix; + const gchar *uri; + int uri_len; +} PrefixMap; + +typedef struct { GHashTable *prefix_to_namespace; GHashTable *namespace_to_prefix; + GArray *prefix_map; gboolean sealed; } TrackerNamespaceManagerPrivate; @@ -74,6 +81,7 @@ tracker_namespace_manager_init (TrackerNamespaceManager *self) priv->prefix_to_namespace = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); priv->namespace_to_prefix = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + priv->prefix_map = g_array_new (FALSE, FALSE, sizeof (PrefixMap)); } static void @@ -85,6 +93,7 @@ finalize (GObject *object) g_hash_table_unref (priv->prefix_to_namespace); g_hash_table_unref (priv->namespace_to_prefix); + g_array_unref (priv->prefix_map); (G_OBJECT_CLASS (tracker_namespace_manager_parent_class)->finalize)(object); } @@ -220,6 +229,8 @@ tracker_namespace_manager_add_prefix (TrackerNamespaceManager *self, { TrackerNamespaceManagerPrivate *priv; const char *str; + gchar *prefix_copy, *ns_copy; + PrefixMap map; g_return_if_fail (TRACKER_IS_NAMESPACE_MANAGER (self)); g_return_if_fail (prefix != NULL); @@ -245,8 +256,16 @@ tracker_namespace_manager_add_prefix (TrackerNamespaceManager *self, return; } - g_hash_table_insert (priv->prefix_to_namespace, g_strdup (prefix), g_strdup (ns)); + prefix_copy = g_strdup (prefix); + ns_copy = g_strdup (ns); + + g_hash_table_insert (priv->prefix_to_namespace, prefix_copy, ns_copy); g_hash_table_insert (priv->namespace_to_prefix, g_strdup (ns), g_strdup (prefix)); + + map.prefix = prefix_copy; + map.uri = ns_copy; + map.uri_len = strlen (map.uri); + g_array_append_val (priv->prefix_map, map); } /** @@ -311,20 +330,28 @@ tracker_namespace_manager_compress_uri (TrackerNamespaceManager *self, const char *uri) { TrackerNamespaceManagerPrivate *priv; - GHashTableIter iter; - const char *prefix, *namespace, *suffix; + guint i; + int len; g_return_val_if_fail (TRACKER_IS_NAMESPACE_MANAGER (self), NULL); g_return_val_if_fail (uri != NULL, NULL); priv = GET_PRIVATE (self); - g_hash_table_iter_init (&iter, priv->prefix_to_namespace); + len = strlen (uri); + + for (i = 0; i < priv->prefix_map->len; i++) { + PrefixMap *map; + const char *suffix; + + map = &g_array_index (priv->prefix_map, PrefixMap, i); - while (g_hash_table_iter_next (&iter, (gpointer *) &prefix, (gpointer *) &namespace)) { - if (g_str_has_prefix (uri, namespace)) { - suffix = &uri[strlen(namespace)]; - return g_strdup_printf ("%s:%s", prefix, suffix); + if (map->uri_len <= len && + map->uri[0] == uri[0] && + map->uri[map->uri_len - 1] == uri[map->uri_len - 1] && + strncmp (uri, map->uri, map->uri_len) == 0) { + suffix = &uri[map->uri_len]; + return g_strconcat (map->prefix, ":", suffix, NULL); } } |