summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2020-11-28 19:48:02 +0100
committerCarlos Garnacho <carlosg@gnome.org>2020-12-01 13:09:45 +0100
commit9e9a34fe232d222dd67aa6d3abdf23ee3310bf95 (patch)
treed3bb05ccbccd71254c4caf8706e7de0f74ce428b
parent8ed66aee64c65c8c0fc6775ac00657e6ca10b024 (diff)
downloadtracker-9e9a34fe232d222dd67aa6d3abdf23ee3310bf95.tar.gz
libtracker-data: Add fast path to insert new bnode UUIDs
The way to insert bnodes used to consist of 1) SELECT SparqlBNode() (which may query multiple times for an unused one). 2) SELECT ID FROM Resource WHERE Uri=bnode 3) INSERT INTO Resource(..., bnode) Step 2 no longer applies since earlier commits, but this can be streamlined so we try to insert bnodes until one comes up successful, and it'll usually be on the first try. Make this apply to direct updates from TrackerResource, as that's where it's easiest to pull off.
-rw-r--r--src/libtracker-data/tracker-data-update.c61
-rw-r--r--src/libtracker-data/tracker-data-update.h3
2 files changed, 60 insertions, 4 deletions
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index 0f865f0a2..fcce6d105 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -37,6 +37,7 @@
#include "tracker-property.h"
#include "tracker-sparql.h"
#include "tracker-turtle-reader.h"
+#include "tracker-uuid.h"
typedef struct _TrackerDataUpdateBuffer TrackerDataUpdateBuffer;
typedef struct _TrackerDataUpdateBufferGraph TrackerDataUpdateBufferGraph;
@@ -1578,8 +1579,7 @@ get_bnode_for_resource (GHashTable *bnodes,
return bnode;
iface = tracker_data_manager_get_writable_db_interface (data->manager);
- bnode = tracker_data_query_unused_uuid (data->manager,
- iface);
+ bnode = tracker_data_update_ensure_new_bnode (data, iface, NULL);
identifier = tracker_resource_get_identifier (resource);
g_hash_table_insert (bnodes, g_strdup (identifier), bnode);
@@ -1627,8 +1627,7 @@ bytes_from_gvalue (GValue *gvalue,
TrackerDBInterface *iface;
iface = tracker_data_manager_get_writable_db_interface (data->manager);
- bnode = tracker_data_query_unused_uuid (data->manager,
- iface);
+ bnode = tracker_data_update_ensure_new_bnode (data, iface, NULL);
g_hash_table_insert (bnodes, g_strdup (uri), bnode);
}
@@ -3063,3 +3062,57 @@ tracker_data_update_resource (TrackerData *data,
return retval;
}
+
+gchar *
+tracker_data_update_ensure_new_bnode (TrackerData *data,
+ TrackerDBInterface *iface,
+ GError **error)
+{
+ TrackerDBStatement *stmt = NULL;
+ GError *inner_error = NULL;
+ gchar *uuid, *key;
+ gint id;
+
+ iface = tracker_data_manager_get_writable_db_interface (data->manager);
+
+ stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE,
+ &inner_error,
+ "INSERT INTO Resource (Uri, BlankNode) VALUES (?, ?)");
+ if (!stmt) {
+ g_propagate_error (error, inner_error);
+ return NULL;
+ }
+
+ while (TRUE) {
+ uuid = tracker_generate_uuid ("urn:bnode:");
+
+ tracker_db_statement_bind_text (stmt, 0, uuid);
+ tracker_db_statement_bind_int (stmt, 1, 1);
+ tracker_db_statement_execute (stmt, &inner_error);
+
+ if (!inner_error ||
+ !g_error_matches (inner_error,
+ TRACKER_DB_INTERFACE_ERROR,
+ TRACKER_DB_CONSTRAINT)) {
+ break;
+ }
+
+ /* Constraint error, retry */
+ g_clear_error (&inner_error);
+ g_free (uuid);
+ }
+
+ g_object_unref (stmt);
+
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ return NULL;
+ }
+
+ id = tracker_db_interface_sqlite_get_last_insert_id (iface);
+ key = g_strdup (uuid);
+ g_hash_table_insert (data->update_buffer.resource_cache, key, GINT_TO_POINTER (id));
+ g_hash_table_add (data->update_buffer.new_resources, key);
+
+ return uuid;
+}
diff --git a/src/libtracker-data/tracker-data-update.h b/src/libtracker-data/tracker-data-update.h
index 21d6d89e9..8df34e213 100644
--- a/src/libtracker-data/tracker-data-update.h
+++ b/src/libtracker-data/tracker-data-update.h
@@ -146,6 +146,9 @@ gboolean tracker_data_update_resource (TrackerData *data,
gint tracker_data_update_ensure_resource (TrackerData *data,
const gchar *uri,
gboolean *create);
+gchar * tracker_data_update_ensure_new_bnode (TrackerData *data,
+ TrackerDBInterface *iface,
+ GError **error);
GType tracker_data_get_type (void) G_GNUC_CONST;
TrackerData * tracker_data_new (TrackerDataManager *manager);