summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2016-08-04 12:57:31 +0100
committerRichard Hughes <richard@hughsie.com>2016-08-04 12:57:31 +0100
commit2c53426cc148725d72ace38a0eaeb78e28b6ba1d (patch)
treeed237919999499912ff9ca23f76e0e466a17ab4b
parent8b58bc974bca72fc323074f3df1089f2461e00a0 (diff)
downloadappstream-glib-2c53426cc148725d72ace38a0eaeb78e28b6ba1d.tar.gz
Add a fast as_utils_unique_id_equal() to compare IDs for equality
-rw-r--r--libappstream-glib/as-self-test.c23
-rw-r--r--libappstream-glib/as-utils.c64
-rw-r--r--libappstream-glib/as-utils.h2
3 files changed, 89 insertions, 0 deletions
diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c
index 708123a..9d928e3 100644
--- a/libappstream-glib/as-self-test.c
+++ b/libappstream-glib/as-self-test.c
@@ -5017,6 +5017,28 @@ as_test_markup_import_html (void)
g_assert_cmpstr (out_list, ==, "<ul><li>First line of the list</li><li>Second line of the list</li></ul>");
}
+static void
+as_test_utils_unique_id_func (void)
+{
+ const guint loops = 100000;
+ guint i;
+ gdouble duration_ns;
+ g_autoptr(GTimer) timer = g_timer_new ();
+
+ for (i = 0; i < loops; i++) {
+ g_assert (as_utils_unique_id_equal ("aa/bb/cc/dd/ee/ff/gg/hh",
+ "aa/bb/cc/dd/ee/ff/gg/hh"));
+ g_assert (as_utils_unique_id_equal ("aa/bb/cc/dd/ee/ff/gg/hh",
+ "aa/*/cc/dd/ee/ff/gg/hh"));
+ g_assert (as_utils_unique_id_equal ("user/flatpak/utopia/desktop/gimp.desktop/i386/master/1.2.3",
+ "*/*/*/*/*/*/*/*"));
+ g_assert (!as_utils_unique_id_equal ("zz/zz/zz/zz/zz/zz/zz/zz",
+ "aa/bb/cc/dd/ee/ff/gg/hh"));
+ }
+ duration_ns = g_timer_elapsed (timer, NULL) * 1000000000.f;
+ g_print ("%.0f ns: ", duration_ns / (loops * 4));
+}
+
int
main (int argc, char **argv)
{
@@ -5026,6 +5048,7 @@ main (int argc, char **argv)
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
/* tests go here */
+ g_test_add_func ("/AppStream/utils{unique_id}", as_test_utils_unique_id_func);
g_test_add_func ("/AppStream/utils{locale-compat}", as_test_utils_locale_compat_func);
g_test_add_func ("/AppStream/utils{string-replace}", as_test_utils_string_replace_func);
g_test_add_func ("/AppStream/tag", as_test_tag_func);
diff --git a/libappstream-glib/as-utils.c b/libappstream-glib/as-utils.c
index dfeec4c..c1472e3 100644
--- a/libappstream-glib/as-utils.c
+++ b/libappstream-glib/as-utils.c
@@ -1763,3 +1763,67 @@ as_utils_unique_id_build (AsAppScope scope,
_as_utils_fix_unique_id_part (branch),
_as_utils_fix_unique_id_part (version));
}
+
+static inline guint
+as_utils_unique_id_find_part (const gchar *str)
+{
+ guint i;
+ for (i = 0; str[i] != '/' && str[i] != '\0'; i++);
+ return i;
+}
+
+/**
+ * as_utils_unique_id_equal:
+ * @unique_id1: a unique ID
+ * @unique_id2: another unique ID
+ *
+ * Checks two unique IDs for equality allowing globs to match.
+ *
+ * Returns: %TRUE if the ID's should be considered equal.
+ *
+ * Since: 0.6.1
+ */
+gboolean
+as_utils_unique_id_equal (const gchar *unique_id1, const gchar *unique_id2)
+{
+ guint i;
+ guint last1 = 0;
+ guint last2 = 0;
+ guint len1;
+ guint len2;
+
+ /* trivial */
+ if (unique_id1 == unique_id2)
+ return TRUE;
+
+ /* invalid */
+ if (unique_id1 == NULL || unique_id2 == NULL)
+ return FALSE;
+
+ /* look at each part */
+ for (i = 0; i < 8; i++) {
+ const gchar *tmp1 = unique_id1 + last1;
+ const gchar *tmp2 = unique_id2 + last2;
+
+ /* find the slash or the end of the string */
+ len1 = as_utils_unique_id_find_part (tmp1);
+ len2 = as_utils_unique_id_find_part (tmp2);
+
+ /* either string was a wildcard */
+ if (len1 == 1 && tmp1[0] == '*')
+ continue;
+ if (len2 == 1 && tmp2[0] == '*')
+ continue;
+
+ /* are substrings the same */
+ if (len1 != len2)
+ return FALSE;
+ if (memcmp (tmp1, tmp2, len1) != 0)
+ return FALSE;
+
+ /* advance to next section */
+ last1 += len1 + 1;
+ last2 += len2 + 1;
+ }
+ return TRUE;
+}
diff --git a/libappstream-glib/as-utils.h b/libappstream-glib/as-utils.h
index 267e172..c41b7e7 100644
--- a/libappstream-glib/as-utils.h
+++ b/libappstream-glib/as-utils.h
@@ -140,6 +140,8 @@ gchar *as_utils_unique_id_build (AsAppScope scope,
const gchar *arch,
const gchar *branch,
const gchar *version);
+gboolean as_utils_unique_id_equal (const gchar *unique_id1,
+ const gchar *unique_id2);
G_END_DECLS