[gnome-software/wip/hughsie/libxml-XbQuery: 2/2] Use the new libxmlb prepared queries feature to make search faster
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/hughsie/libxml-XbQuery: 2/2] Use the new libxmlb prepared queries feature to make search faster
- Date: Tue, 23 Oct 2018 16:41:39 +0000 (UTC)
commit 577145f740386e7398ca58f65cb3340ca7c1cfab
Author: Richard Hughes <richard hughsie com>
Date: Tue Oct 23 13:27:27 2018 +0100
Use the new libxmlb prepared queries feature to make search faster
On ARM hardware this makes searches 76% faster.
meson.build | 2 +-
plugins/core/gs-appstream.c | 91 +++++++++++++++++++--------------------------
2 files changed, 39 insertions(+), 54 deletions(-)
---
diff --git a/meson.build b/meson.build
index bea407de..f435ad79 100644
--- a/meson.build
+++ b/meson.build
@@ -98,7 +98,7 @@ conf.set('HAVE_LINUX_UNISTD_H', cc.has_header('linux/unistd.h'))
appstream_glib = dependency('appstream-glib', version : '>= 0.7.14')
gdk_pixbuf = dependency('gdk-pixbuf-2.0', version : '>= 2.32.0')
-libxmlb = dependency('xmlb', version : '>= 0.1.3', fallback : ['libxmlb', 'libxmlb_dep'])
+libxmlb = dependency('xmlb', version : '>= 0.1.4', fallback : ['libxmlb', 'libxmlb_dep'])
gio_unix = dependency('gio-unix-2.0', version : '>= 2.56.0')
gmodule = dependency('gmodule-2.0')
gtk = dependency('gtk+-3.0', version : '>= 3.22.4')
diff --git a/plugins/core/gs-appstream.c b/plugins/core/gs-appstream.c
index 091aeb5b..2649ee06 100644
--- a/plugins/core/gs-appstream.c
+++ b/plugins/core/gs-appstream.c
@@ -948,70 +948,27 @@ gs_appstream_refine_app (GsPlugin *plugin,
typedef struct {
AsAppSearchMatch match_value;
- gchar *xpath;
+ XbQuery *query;
} GsAppstreamSearchHelper;
static void
gs_appstream_search_helper_free (GsAppstreamSearchHelper *helper)
{
- g_free (helper->xpath);
+ g_object_unref (helper->query);
g_free (helper);
}
static guint16
-gs_appstream_silo_search_component2 (XbNode *component, const gchar *search)
+gs_appstream_silo_search_component2 (GPtrArray *array, XbNode *component, const gchar *search)
{
- GsAppstreamSearchHelper *helper;
guint16 match_value = 0;
- g_autoptr(GPtrArray) array = g_ptr_array_new_with_free_func ((GDestroyNotify)
gs_appstream_search_helper_free);
-
- /* mimetype */
- helper = g_new0 (GsAppstreamSearchHelper, 1);
- helper->match_value = AS_APP_SEARCH_MATCH_MIMETYPE;
- helper->xpath = g_strdup_printf ("mimetypes/mimetype[type()~='%s']", search);
- g_ptr_array_add (array, helper);
-
- /* package name */
- helper = g_new0 (GsAppstreamSearchHelper, 1);
- helper->match_value = AS_APP_SEARCH_MATCH_PKGNAME;
- helper->xpath = g_strdup_printf ("pkgname[text()~='%s']", search);
- g_ptr_array_add (array, helper);
-
- /* summary */
- helper = g_new0 (GsAppstreamSearchHelper, 1);
- helper->match_value = AS_APP_SEARCH_MATCH_COMMENT;
- helper->xpath = g_strdup_printf ("summary[text()~='%s']", search);
- g_ptr_array_add (array, helper);
-
- /* name */
- helper = g_new0 (GsAppstreamSearchHelper, 1);
- helper->match_value = AS_APP_SEARCH_MATCH_NAME;
- helper->xpath = g_strdup_printf ("name[text()~='%s']", search);
- g_ptr_array_add (array, helper);
-
- /* keywords */
- helper = g_new0 (GsAppstreamSearchHelper, 1);
- helper->match_value = AS_APP_SEARCH_MATCH_KEYWORD;
- helper->xpath = g_strdup_printf ("keywords/keyword[text()~='%s']", search);
- g_ptr_array_add (array, helper);
-
- /* AppStream ID */
- helper = g_new0 (GsAppstreamSearchHelper, 1);
- helper->match_value = AS_APP_SEARCH_MATCH_ID;
- helper->xpath = g_strdup_printf ("id[text()~='%s']", search);
- g_ptr_array_add (array, helper);
-
- /* origin */
- helper = g_new0 (GsAppstreamSearchHelper, 1);
- helper->match_value = AS_APP_SEARCH_MATCH_ORIGIN;
- helper->xpath = g_strdup_printf ("../components[@origin~='%s']", search);
- g_ptr_array_add (array, helper);
/* do searches */
for (guint i = 0; i < array->len; i++) {
- g_autoptr(XbNode) n = NULL;
- helper = g_ptr_array_index (array, i);
- n = xb_node_query_first (component, helper->xpath, NULL);
+ g_autoptr(GPtrArray) n = NULL;
+ GsAppstreamSearchHelper *helper = g_ptr_array_index (array, i);
+ xb_query_bind_str (helper->query, 0, search, NULL);
+ n = xb_node_query_full (component, helper->query, NULL);
if (n != NULL)
match_value |= helper->match_value;
}
@@ -1019,13 +976,13 @@ gs_appstream_silo_search_component2 (XbNode *component, const gchar *search)
}
static guint16
-gs_appstream_silo_search_component (XbNode *component, gchar **search)
+gs_appstream_silo_search_component (GPtrArray *array, XbNode *component, gchar **search)
{
guint16 matches_sum = 0;
/* do *all* search keywords match */
for (guint i = 0; search[i] != NULL; i++) {
- guint tmp = gs_appstream_silo_search_component2 (component, search[i]);
+ guint tmp = gs_appstream_silo_search_component2 (array, component, search[i]);
if (tmp == 0)
return 0;
matches_sum |= tmp;
@@ -1042,8 +999,36 @@ gs_appstream_search (GsPlugin *plugin,
GError **error)
{
g_autoptr(GError) error_local = NULL;
+ g_autoptr(GPtrArray) array = g_ptr_array_new_with_free_func ((GDestroyNotify)
gs_appstream_search_helper_free);
g_autoptr(GPtrArray) components = NULL;
g_autoptr(GTimer) timer = g_timer_new ();
+ struct {
+ AsAppSearchMatch match_value;
+ const gchar *xpath;
+ } queries[] = {
+ { AS_APP_SEARCH_MATCH_MIMETYPE, "mimetypes/mimetype[text()~=?]" },
+ { AS_APP_SEARCH_MATCH_PKGNAME, "pkgname[text()~=?]" },
+ { AS_APP_SEARCH_MATCH_COMMENT, "summary[text()~=?]" },
+ { AS_APP_SEARCH_MATCH_NAME, "name[text()~=?]" },
+ { AS_APP_SEARCH_MATCH_KEYWORD, "keywords/keyword[text()~=?]" },
+ { AS_APP_SEARCH_MATCH_ID, "id[text()~=?]" },
+ { AS_APP_SEARCH_MATCH_ORIGIN, "../components[@origin~=?]" },
+ { AS_APP_SEARCH_MATCH_NONE, NULL }
+ };
+
+ /* add some weighted queries */
+ for (guint i = 0; queries[i].xpath != NULL; i++) {
+ g_autoptr(GError) error_query = NULL;
+ g_autoptr(XbQuery) query = xb_query_new (silo, queries[i].xpath, &error_query);
+ if (query != NULL) {
+ GsAppstreamSearchHelper *helper = g_new0 (GsAppstreamSearchHelper, 1);
+ helper->match_value = queries[i].match_value;
+ helper->query = g_steal_pointer (&query);
+ g_ptr_array_add (array, helper);
+ } else {
+ g_debug ("ignoring: %s", error_query->message);
+ }
+ }
/* get all components */
components = xb_silo_query (silo, "components/component", 0, &error_local);
@@ -1057,7 +1042,7 @@ gs_appstream_search (GsPlugin *plugin,
}
for (guint i = 0; i < components->len; i++) {
XbNode *component = g_ptr_array_index (components, i);
- guint16 match_value = gs_appstream_silo_search_component (component, values);
+ guint16 match_value = gs_appstream_silo_search_component (array, component, values);
if (match_value != 0) {
g_autoptr(GsApp) app = gs_appstream_create_app (plugin, silo, component, error);
if (app == NULL)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]