diff options
author | Richard Hughes <richard@hughsie.com> | 2016-08-04 12:57:31 +0100 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2016-08-04 12:57:31 +0100 |
commit | 2c53426cc148725d72ace38a0eaeb78e28b6ba1d (patch) | |
tree | ed237919999499912ff9ca23f76e0e466a17ab4b | |
parent | 8b58bc974bca72fc323074f3df1089f2461e00a0 (diff) | |
download | appstream-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.c | 23 | ||||
-rw-r--r-- | libappstream-glib/as-utils.c | 64 | ||||
-rw-r--r-- | libappstream-glib/as-utils.h | 2 |
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 |