Commit c390dbaa authored by Carlos Garnacho's avatar Carlos Garnacho

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
parent c5425cd5
......@@ -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);
}
......@@ -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__ */
......@@ -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
......
......@@ -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__ */
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment