summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2015-03-17 18:58:14 +0100
committerCarlos Garnacho <carlosg@gnome.org>2015-03-17 21:48:40 +0100
commitc390dbaa2bbb0138589d7dd2d0217b905bc3082e (patch)
treea15ba92617852b3315a9c8396813d1d7d2ae75a4
parentc5425cd5afb583fafe86ca61a2f4fb6047873891 (diff)
downloadtracker-c390dbaa2bbb0138589d7dd2d0217b905bc3082e.tar.gz
libtracker-miner: Invalidate the IRI of just inserted elements
This allows us to be smarter about when to look up the IRI on the database. If a file is created and being slowly written to (eg. downloads), ::file-created will be emitted for the file eventually, but the updates will keep the file instance alive on the TrackerFileSystem. In this case we attempted to be smart and avoid querying needlessly the database for the IRI, which resulted on a mistakenly NULL IRI, and on an attempt to "create" the item again, even though it existed. This resulted in "UNIQUE constraint" errors. One thing we can do is "invalidating" the IRI, so the next time we call tracker_file_notifier_get_file_iri() on it, a query is forced only in these situations, this will make later updates happy with the right IRI. If the updates are too slow, and the file happens to be flushed out of the TrackerFileSystem (all non-directory files do), the next update would trigger again its insertion, and the IRI would be queried again, so we're safe in that regard. https://bugzilla.redhat.com/show_bug.cgi?id=1192224
-rw-r--r--src/libtracker-miner/tracker-file-notifier.c45
-rw-r--r--src/libtracker-miner/tracker-file-notifier.h3
-rw-r--r--src/libtracker-miner/tracker-file-system.c30
-rw-r--r--src/libtracker-miner/tracker-file-system.h5
-rw-r--r--src/libtracker-miner/tracker-miner-fs.c2
5 files changed, 77 insertions, 8 deletions
diff --git a/src/libtracker-miner/tracker-file-notifier.c b/src/libtracker-miner/tracker-file-notifier.c
index 6f094bacb..b5054ead7 100644
--- a/src/libtracker-miner/tracker-file-notifier.c
+++ b/src/libtracker-miner/tracker-file-notifier.c
@@ -1672,6 +1672,7 @@ tracker_file_notifier_get_file_iri (TrackerFileNotifier *notifier,
TrackerFileNotifierPrivate *priv;
GFile *canonical;
gchar *iri = NULL;
+ gboolean found;
g_return_val_if_fail (TRACKER_IS_FILE_NOTIFIER (notifier), NULL);
g_return_val_if_fail (G_IS_FILE (file), NULL);
@@ -1685,9 +1686,21 @@ tracker_file_notifier_get_file_iri (TrackerFileNotifier *notifier,
return NULL;
}
- iri = tracker_file_system_get_property (priv->file_system,
- canonical,
- quark_property_iri);
+ found = tracker_file_system_get_property_full (priv->file_system,
+ canonical,
+ quark_property_iri,
+ (gpointer *) &iri);
+
+ if (found && !iri) {
+ /* NULL here mean the file iri was "invalidated", the file
+ * was inserted by a previous event, so it has an unknown iri,
+ * and further updates are keeping the file object alive.
+ *
+ * When these updates are processed, they'll need fetching the
+ * file IRI again, so we force here extraction for these cases.
+ */
+ force = TRUE;
+ }
if (!iri && force) {
TrackerSparqlCursor *cursor;
@@ -1711,3 +1724,29 @@ tracker_file_notifier_get_file_iri (TrackerFileNotifier *notifier,
return iri;
}
+
+void
+tracker_file_notifier_invalidate_file_iri (TrackerFileNotifier *notifier,
+ GFile *file)
+{
+ TrackerFileNotifierPrivate *priv;
+ GFile *canonical;
+
+ g_return_val_if_fail (TRACKER_IS_FILE_NOTIFIER (notifier), NULL);
+ g_return_val_if_fail (G_IS_FILE (file), NULL);
+
+ priv = notifier->priv;
+ canonical = tracker_file_system_get_file (priv->file_system,
+ file,
+ G_FILE_TYPE_REGULAR,
+ NULL);
+ if (!canonical) {
+ return;
+ }
+
+ /* Set a NULL iri, so we make sure to look it up afterwards */
+ tracker_file_system_set_property (priv->file_system,
+ canonical,
+ quark_property_iri,
+ NULL);
+}
diff --git a/src/libtracker-miner/tracker-file-notifier.h b/src/libtracker-miner/tracker-file-notifier.h
index f1c86a551..51e70a2ba 100644
--- a/src/libtracker-miner/tracker-file-notifier.h
+++ b/src/libtracker-miner/tracker-file-notifier.h
@@ -90,6 +90,9 @@ const gchar * tracker_file_notifier_get_file_iri (TrackerFileNotifier *notif
GFile *file,
gboolean force);
+void tracker_file_notifier_invalidate_file_iri (TrackerFileNotifier *notifier,
+ GFile *file);
+
G_END_DECLS
#endif /* __TRACKER_FILE_SYSTEM_H__ */
diff --git a/src/libtracker-miner/tracker-file-system.c b/src/libtracker-miner/tracker-file-system.c
index 696f48275..834ed8c04 100644
--- a/src/libtracker-miner/tracker-file-system.c
+++ b/src/libtracker-miner/tracker-file-system.c
@@ -839,10 +839,11 @@ tracker_file_system_set_property (TrackerFileSystem *file_system,
}
}
-gpointer
-tracker_file_system_get_property (TrackerFileSystem *file_system,
- GFile *file,
- GQuark prop)
+gboolean
+tracker_file_system_get_property_full (TrackerFileSystem *file_system,
+ GFile *file,
+ GQuark prop,
+ gpointer *prop_data)
{
FileNodeData *data;
FileNodeProperty property, *match;
@@ -862,7 +863,26 @@ tracker_file_system_get_property (TrackerFileSystem *file_system,
data->properties->len, sizeof (FileNodeProperty),
search_property_node);
- return (match) ? match->value : NULL;
+ if (prop_data)
+ *prop_data = (match) ? match->value : NULL;
+
+ return match != NULL;
+}
+
+gpointer
+tracker_file_system_get_property (TrackerFileSystem *file_system,
+ GFile *file,
+ GQuark prop)
+{
+ gpointer data;
+
+ g_return_val_if_fail (TRACKER_IS_FILE_SYSTEM (file_system), NULL);
+ g_return_val_if_fail (file != NULL, NULL);
+ g_return_val_if_fail (prop > 0, NULL);
+
+ tracker_file_system_get_property_full (file_system, file, prop, &data);
+
+ return data;
}
void
diff --git a/src/libtracker-miner/tracker-file-system.h b/src/libtracker-miner/tracker-file-system.h
index fe83c5f26..c80b1e587 100644
--- a/src/libtracker-miner/tracker-file-system.h
+++ b/src/libtracker-miner/tracker-file-system.h
@@ -94,6 +94,11 @@ void tracker_file_system_unset_property (TrackerFileSystem *file_system,
GFile *file,
GQuark prop);
+gboolean tracker_file_system_get_property_full (TrackerFileSystem *file_system,
+ GFile *file,
+ GQuark prop,
+ gpointer *data);
+
G_END_DECLS
#endif /* __TRACKER_FILE_SYSTEM_H__ */
diff --git a/src/libtracker-miner/tracker-miner-fs.c b/src/libtracker-miner/tracker-miner-fs.c
index 069f86918..435c0b607 100644
--- a/src/libtracker-miner/tracker-miner-fs.c
+++ b/src/libtracker-miner/tracker-miner-fs.c
@@ -1282,6 +1282,8 @@ sparql_buffer_task_finished_cb (GObject *object,
task = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
task_file = tracker_task_get_file (task);
+ tracker_file_notifier_invalidate_file_iri (priv->file_notifier, task_file);
+
if (item_queue_is_blocked_by_file (fs, task_file)) {
g_object_unref (priv->item_queue_blocker);
priv->item_queue_blocker = NULL;