[tracker] libtracker-miner: Invalidate the IRI of just inserted elements



commit c390dbaa2bbb0138589d7dd2d0217b905bc3082e
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Mar 17 18:58:14 2015 +0100

    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

 src/libtracker-miner/tracker-file-notifier.c |   45 ++++++++++++++++++++++++--
 src/libtracker-miner/tracker-file-notifier.h |    3 ++
 src/libtracker-miner/tracker-file-system.c   |   30 ++++++++++++++---
 src/libtracker-miner/tracker-file-system.h   |    5 +++
 src/libtracker-miner/tracker-miner-fs.c      |    2 +
 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 6f094ba..b5054ea 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 f1c86a5..51e70a2 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 696f482..834ed8c 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 fe83c5f..c80b1e5 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 069f869..435c0b6 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;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]