diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2020-11-28 19:48:02 +0100 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2020-12-01 13:09:45 +0100 |
commit | 9e9a34fe232d222dd67aa6d3abdf23ee3310bf95 (patch) | |
tree | d3bb05ccbccd71254c4caf8706e7de0f74ce428b | |
parent | 8ed66aee64c65c8c0fc6775ac00657e6ca10b024 (diff) | |
download | tracker-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.c | 61 | ||||
-rw-r--r-- | src/libtracker-data/tracker-data-update.h | 3 |
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); |