[tracker-miners/wip/carlosg/batches-and-resources: 21/31] libtracker-miner: Use TrackerBatch to push SPARQL changes




commit 7336faa675e739d0f8069f978573349e4543155e
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Dec 2 18:57:46 2020 +0100

    libtracker-miner: Use TrackerBatch to push SPARQL changes
    
    Use TrackerBatch beneath TrackerSparqlBuffer, which allows the
    direct mapping of TrackerResources onto the DB, without translations
    from/to SPARQL.

 src/libtracker-miner/tracker-miner-fs.c        | 192 +++++------------------
 src/libtracker-miner/tracker-miner-fs.h        |  28 ++--
 src/libtracker-miner/tracker-sparql-buffer.c   | 203 ++++++++++++++++---------
 src/libtracker-miner/tracker-sparql-buffer.h   |  15 +-
 src/miners/fs/tracker-miner-files.c            | 139 ++++++++---------
 tests/libtracker-miner/tracker-miner-fs-test.c |  56 ++++---
 6 files changed, 284 insertions(+), 349 deletions(-)
---
diff --git a/src/libtracker-miner/tracker-miner-fs.c b/src/libtracker-miner/tracker-miner-fs.c
index ce33b4ede..a1ae80a34 100644
--- a/src/libtracker-miner/tracker-miner-fs.c
+++ b/src/libtracker-miner/tracker-miner-fs.c
@@ -400,8 +400,8 @@ tracker_miner_fs_class_init (TrackerMinerFSClass *klass)
                              G_STRUCT_OFFSET (TrackerMinerFSClass, process_file),
                              NULL, NULL,
                              NULL,
-                             G_TYPE_STRING,
-                             2, G_TYPE_FILE, G_TYPE_FILE_INFO);
+                             G_TYPE_NONE,
+                             3, G_TYPE_FILE, G_TYPE_FILE_INFO, TRACKER_TYPE_SPARQL_BUFFER);
 
        /**
         * TrackerMinerFS::process-file-attributes:
@@ -436,8 +436,8 @@ tracker_miner_fs_class_init (TrackerMinerFSClass *klass)
                              G_STRUCT_OFFSET (TrackerMinerFSClass, process_file_attributes),
                              NULL, NULL,
                              NULL,
-                             G_TYPE_STRING,
-                             2, G_TYPE_FILE, G_TYPE_FILE_INFO);
+                             G_TYPE_NONE,
+                             3, G_TYPE_FILE, G_TYPE_FILE_INFO, TRACKER_TYPE_SPARQL_BUFFER);
 
        /**
         * TrackerMinerFS::finished:
@@ -531,8 +531,8 @@ tracker_miner_fs_class_init (TrackerMinerFSClass *klass)
                              G_SIGNAL_RUN_LAST,
                              G_STRUCT_OFFSET (TrackerMinerFSClass, remove_file),
                              NULL, NULL, NULL,
-                             G_TYPE_STRING,
-                             1, G_TYPE_FILE);
+                             G_TYPE_NONE,
+                             2, G_TYPE_FILE, TRACKER_TYPE_SPARQL_BUFFER);
 
        signals[REMOVE_CHILDREN] =
                g_signal_new ("remove-children",
@@ -540,8 +540,8 @@ tracker_miner_fs_class_init (TrackerMinerFSClass *klass)
                              G_SIGNAL_RUN_LAST,
                              G_STRUCT_OFFSET (TrackerMinerFSClass, remove_children),
                              NULL, NULL, NULL,
-                             G_TYPE_STRING,
-                             1, G_TYPE_FILE);
+                             G_TYPE_NONE,
+                             2, G_TYPE_FILE, TRACKER_TYPE_SPARQL_BUFFER);
 
        signals[MOVE_FILE] =
                g_signal_new ("move-file",
@@ -549,8 +549,8 @@ tracker_miner_fs_class_init (TrackerMinerFSClass *klass)
                              G_SIGNAL_RUN_LAST,
                              G_STRUCT_OFFSET (TrackerMinerFSClass, move_file),
                              NULL, NULL, NULL,
-                             G_TYPE_STRING,
-                             3, G_TYPE_FILE, G_TYPE_FILE, G_TYPE_BOOLEAN);
+                             G_TYPE_NONE,
+                             4, G_TYPE_FILE, G_TYPE_FILE, TRACKER_TYPE_SPARQL_BUFFER, G_TYPE_BOOLEAN);
 
        quark_last_queue_event = g_quark_from_static_string ("tracker-last-queue-event");
 }
@@ -1252,15 +1252,20 @@ sparql_buffer_flush_cb (GObject      *object,
                task_file = tracker_task_get_file (task);
 
                if (error) {
-                       tracker_error_report (task_file, error->message,
-                                             tracker_sparql_task_get_sparql (task));
+                       gchar *sparql;
+
+                       sparql = tracker_sparql_task_get_sparql (task);
+                       tracker_error_report (task_file, error->message, sparql);
                        fs->priv->total_files_notified_error++;
+                       g_free (sparql);
                } else {
                        tracker_error_report_delete (task_file);
                }
 
                if (item_queue_is_blocked_by_file (fs, task_file))
                        g_clear_object (&fs->priv->item_queue_blocker);
+
+               tracker_lru_remove (fs->priv->urn_lru, task_file);
        }
 
        if (priv->item_queue_blocker != NULL) {
@@ -1288,77 +1293,13 @@ sparql_buffer_flush_cb (GObject      *object,
        g_clear_error (&error);
 }
 
-static void
-push_sparql_task (TrackerMinerFS *fs,
-                  GFile          *file,
-                  gchar          *sparql)
-{
-       TrackerTask *sparql_task = NULL;
-       gchar *uri;
-
-       uri = g_file_get_uri (file);
-
-       fs->priv->total_files_notified++;
-
-       TRACKER_NOTE (MINER_FS_EVENTS, g_message ("Creating/updating item '%s'", uri));
-
-       sparql_task = tracker_sparql_task_new_take_sparql_str (file, sparql);
-
-       if (sparql_task) {
-               tracker_sparql_buffer_push (fs->priv->sparql_buffer,
-                                           sparql_task);
-
-               if (item_queue_is_blocked_by_file (fs, file)) {
-                       tracker_sparql_buffer_flush (fs->priv->sparql_buffer,
-                                                    "Current file is blocking item queue",
-                                                    sparql_buffer_flush_cb,
-                                                    fs);
-
-                       /* Check if we've finished inserting for given prefixes ... */
-                       notify_roots_finished (fs, TRUE);
-               } else if (tracker_task_pool_limit_reached (TRACKER_TASK_POOL (fs->priv->sparql_buffer))) {
-                       tracker_sparql_buffer_flush (fs->priv->sparql_buffer,
-                                                    "SPARQL buffer limit reached",
-                                                    sparql_buffer_flush_cb,
-                                                    fs);
-
-                       /* Check if we've finished inserting for given prefixes ... */
-                       notify_roots_finished (fs, TRUE);
-               }
-
-               /* We can let go of our reference here because the
-                * sparql buffer takes its own reference when adding
-                * it to the task pool.
-                */
-               tracker_task_unref (sparql_task);
-       } else {
-               if (item_queue_is_blocked_by_file (fs, file)) {
-                       /* Make sure that we don't stall the item queue, although we could
-                        * expect the file to be reenqueued until the loop detector makes
-                        * us drop it since we were specifically waiting for it to complete.
-                        */
-                       g_object_unref (fs->priv->item_queue_blocker);
-                       fs->priv->item_queue_blocker = NULL;
-                       item_queue_handlers_set_up (fs);
-               }
-       }
-
-       if (tracker_miner_fs_has_items_to_process (fs) == FALSE &&
-           tracker_task_pool_get_size (TRACKER_TASK_POOL (fs->priv->task_pool)) == 0) {
-               /* We need to run this one more time to trigger process_stop() */
-               item_queue_handlers_set_up (fs);
-       }
-
-       g_free (uri);
-}
-
 static gboolean
 item_add_or_update (TrackerMinerFS *fs,
                     GFile          *file,
                     GFileInfo      *info,
                     gboolean        attributes_update)
 {
-       gchar *uri, *sparql;
+       gchar *uri;
 
        g_object_ref (file);
 
@@ -1377,17 +1318,14 @@ item_add_or_update (TrackerMinerFS *fs,
        if (!attributes_update) {
                TRACKER_NOTE (MINER_FS_EVENTS, g_message ("Processing file '%s'...", uri));
                g_signal_emit (fs, signals[PROCESS_FILE], 0,
-                              file, info,
-                              &sparql);
+                              file, info, fs->priv->sparql_buffer);
        } else {
                TRACKER_NOTE (MINER_FS_EVENTS, g_message ("Processing attributes in file '%s'...", uri));
                g_signal_emit (fs, signals[PROCESS_FILE_ATTRIBUTES], 0,
-                              file, info,
-                              &sparql);
+                              file, info, fs->priv->sparql_buffer);
        }
 
        fs->priv->total_files_processed++;
-       push_sparql_task (fs, file, sparql);
 
        g_free (uri);
        g_object_unref (file);
@@ -1398,10 +1336,9 @@ item_add_or_update (TrackerMinerFS *fs,
 static gboolean
 item_remove (TrackerMinerFS *fs,
              GFile          *file,
-             gboolean        only_children,
-             GString        *task_sparql)
+             gboolean        only_children)
 {
-       gchar *uri, *sparql;
+       gchar *uri;
        guint signal_num;
 
        uri = g_file_get_uri (file);
@@ -1416,14 +1353,7 @@ item_remove (TrackerMinerFS *fs,
 
        /* Call the implementation to generate a SPARQL update for the removal. */
        signal_num = only_children ? REMOVE_CHILDREN : REMOVE_FILE;
-       g_signal_emit (fs, signals[signal_num], 0, file, &sparql);
-
-       if (sparql && sparql[0] != '\0') {
-               g_string_append (task_sparql, sparql);
-               g_string_append (task_sparql, ";\n");
-       }
-
-       g_free (sparql);
+       g_signal_emit (fs, signals[signal_num], 0, file, fs->priv->sparql_buffer);
        g_free (uri);
 
        return TRUE;
@@ -1433,11 +1363,9 @@ static gboolean
 item_move (TrackerMinerFS *fs,
            GFile          *dest_file,
            GFile          *source_file,
-           GString        *dest_task_sparql,
-           GString        *source_task_sparql,
            gboolean        is_dir)
 {
-       gchar     *uri, *source_uri, *sparql;
+       gchar *uri, *source_uri;
        TrackerDirectoryFlags source_flags, flags;
        gboolean recursive;
 
@@ -1455,24 +1383,17 @@ item_move (TrackerMinerFS *fs,
                     is_dir);
 
        /* Delete destination item from store if any */
-       item_remove (fs, dest_file, FALSE, dest_task_sparql);
+       item_remove (fs, dest_file, FALSE);
 
        /* If the original location is recursive, but the destination location
         * is not, remove all children.
         */
        if (!recursive &&
            (source_flags & TRACKER_DIRECTORY_FLAG_RECURSE) != 0)
-               item_remove (fs, source_file, TRUE, source_task_sparql);
+               item_remove (fs, source_file, TRUE);
 
-       g_signal_emit (fs, signals[MOVE_FILE], 0, dest_file, source_file, recursive, &sparql);
+       g_signal_emit (fs, signals[MOVE_FILE], 0, dest_file, source_file, fs->priv->sparql_buffer, recursive);
 
-       if (sparql && sparql[0] != '\0') {
-               /* This is treated as a task on dest_file */
-               g_string_append (dest_task_sparql, sparql);
-               g_string_append (dest_task_sparql, ";\n");
-       }
-
-       g_free (sparql);
        g_free (uri);
        g_free (source_uri);
 
@@ -1594,37 +1515,17 @@ item_queue_get_progress (TrackerMinerFS *fs,
        return (gdouble) (items_total - items_to_process) / items_total;
 }
 
-/* Add a task to the processing pool to update stored information on 'file'.
- *
- * This function takes ownership of the 'sparql' string.
- */
-static void
-push_task (TrackerMinerFS *fs,
-           GFile          *file,
-           gchar          *sparql)
-{
-       TrackerTask *task;
-
-       task = tracker_sparql_task_new_take_sparql_str (file, sparql);
-       tracker_sparql_buffer_push (fs->priv->sparql_buffer,
-                                   task);
-       tracker_task_unref (task);
-}
-
 static gboolean
 miner_handle_next_item (TrackerMinerFS *fs)
 {
        GFile *file = NULL;
        GFile *source_file = NULL;
-       GFile *parent;
        gint64 time_now;
        static gint64 time_last = 0;
        gboolean keep_processing = TRUE;
        gboolean attributes_update = FALSE;
        gboolean is_dir = FALSE;
        TrackerMinerFSEventType type;
-       GString *task_sparql = NULL;
-       GString *source_task_sparql = NULL;
        GFileInfo *info = NULL;
 
        if (tracker_task_pool_limit_reached (TRACKER_TASK_POOL (fs->priv->sparql_buffer))) {
@@ -1761,46 +1662,28 @@ miner_handle_next_item (TrackerMinerFS *fs)
        /* Handle queues */
        switch (type) {
        case TRACKER_MINER_FS_EVENT_MOVED:
-               task_sparql = g_string_new ("");
-               source_task_sparql = g_string_new ("");
-               keep_processing = item_move (fs, file, source_file, task_sparql, source_task_sparql, is_dir);
+               keep_processing = item_move (fs, file, source_file, is_dir);
                break;
        case TRACKER_MINER_FS_EVENT_DELETED:
-               task_sparql = g_string_new ("");
-               keep_processing = item_remove (fs, file, FALSE, task_sparql);
+               keep_processing = item_remove (fs, file, FALSE);
                break;
        case TRACKER_MINER_FS_EVENT_CREATED:
        case TRACKER_MINER_FS_EVENT_UPDATED:
-               parent = g_file_get_parent (file);
-
                keep_processing = item_add_or_update (fs, file, info, attributes_update);
-
-               if (parent) {
-                       g_object_unref (parent);
-               }
-
                break;
        default:
                g_assert_not_reached ();
        }
 
-       if (source_task_sparql) {
-               if (source_task_sparql->len == 0) {
-                       g_string_free (source_task_sparql, TRUE);
-               } else {
-                       push_task (fs, source_file, g_string_free (source_task_sparql, FALSE));
-               }
-       }
-
-       if (task_sparql) {
-               if (task_sparql->len == 0) {
-                       g_string_free (task_sparql, TRUE);
-               } else {
-                       push_task (fs, file, g_string_free (task_sparql, FALSE));
-               }
-       }
+       if (item_queue_is_blocked_by_file (fs, file)) {
+               tracker_sparql_buffer_flush (fs->priv->sparql_buffer,
+                                            "Current file is blocking item queue",
+                                            sparql_buffer_flush_cb,
+                                            fs);
 
-       if (tracker_task_pool_limit_reached (TRACKER_TASK_POOL (fs->priv->sparql_buffer))) {
+               /* Check if we've finished inserting for given prefixes ... */
+               notify_roots_finished (fs, TRUE);
+       } else if (tracker_task_pool_limit_reached (TRACKER_TASK_POOL (fs->priv->sparql_buffer))) {
                tracker_sparql_buffer_flush (fs->priv->sparql_buffer,
                                             "SPARQL buffer limit reached",
                                             sparql_buffer_flush_cb,
@@ -2409,6 +2292,7 @@ tracker_miner_fs_get_folder_urn (TrackerMinerFS *fs,
                return NULL;
 
        if (!tracker_sparql_cursor_next (cursor, NULL, NULL)) {
+               tracker_lru_add (fs->priv->urn_lru, g_object_ref (file), NULL);
                g_object_unref (cursor);
                return NULL;
        }
diff --git a/src/libtracker-miner/tracker-miner-fs.h b/src/libtracker-miner/tracker-miner-fs.h
index 9d26a3ae9..5625b20d4 100644
--- a/src/libtracker-miner/tracker-miner-fs.h
+++ b/src/libtracker-miner/tracker-miner-fs.h
@@ -32,6 +32,7 @@
 #include "tracker-miner-object.h"
 #include "tracker-data-provider.h"
 #include "tracker-indexing-tree.h"
+#include "tracker-sparql-buffer.h"
 
 G_BEGIN_DECLS
 
@@ -91,34 +92,37 @@ struct _TrackerMinerFS {
 typedef struct {
        TrackerMinerClass parent;
 
-       gchar *  (* process_file)             (TrackerMinerFS       *fs,
+       void     (* process_file)             (TrackerMinerFS       *fs,
                                               GFile                *file,
-                                              GFileInfo            *info);
+                                              GFileInfo            *info,
+                                              TrackerSparqlBuffer  *buffer);
        void     (* finished)                 (TrackerMinerFS       *fs,
                                               gdouble               elapsed,
                                               gint                  directories_found,
                                               gint                  directories_ignored,
                                               gint                  files_found,
                                               gint                  files_ignored);
-       gchar *  (* process_file_attributes)  (TrackerMinerFS       *fs,
+       void     (* process_file_attributes)  (TrackerMinerFS       *fs,
                                               GFile                *file,
-                                              GFileInfo            *info);
+                                              GFileInfo            *info,
+                                              TrackerSparqlBuffer  *buffer);
        void     (* finished_root)            (TrackerMinerFS       *fs,
                                               GFile                *root,
                                               gint                  directories_found,
                                               gint                  directories_ignored,
                                               gint                  files_found,
                                               gint                  files_ignored);
-       gchar *  (* remove_file)              (TrackerMinerFS       *fs,
-                                              GFile                *file);
-       gchar *  (* remove_children)          (TrackerMinerFS       *fs,
-                                              GFile                *file);
-       gchar *  (* move_file)                (TrackerMinerFS       *fs,
-                                              GFile                *dest,
+       void     (* remove_file)              (TrackerMinerFS       *fs,
+                                              GFile                *file,
+                                              TrackerSparqlBuffer  *buffer);
+       void     (* remove_children)          (TrackerMinerFS       *fs,
+                                              GFile                *file,
+                                              TrackerSparqlBuffer  *buffer);
+       void     (* move_file)                (TrackerMinerFS       *fs,
+                                              GFile                *dest,
                                               GFile                *source,
+                                              TrackerSparqlBuffer  *buffer,
                                               gboolean              recursive);
-       /* <Private> */
-       gpointer padding[20];
 } TrackerMinerFSClass;
 
 /**
diff --git a/src/libtracker-miner/tracker-sparql-buffer.c b/src/libtracker-miner/tracker-sparql-buffer.c
index eaea5ec84..94a7d9414 100644
--- a/src/libtracker-miner/tracker-sparql-buffer.c
+++ b/src/libtracker-miner/tracker-sparql-buffer.c
@@ -28,7 +28,7 @@
 
 typedef struct _TrackerSparqlBufferPrivate TrackerSparqlBufferPrivate;
 typedef struct _SparqlTaskData SparqlTaskData;
-typedef struct _UpdateArrayData UpdateArrayData;
+typedef struct _UpdateBatchData UpdateBatchData;
 
 enum {
        PROP_0,
@@ -40,17 +40,34 @@ struct _TrackerSparqlBufferPrivate
        TrackerSparqlConnection *connection;
        GPtrArray *tasks;
        gint n_updates;
+       TrackerBatch *batch;
+};
+
+enum {
+       TASK_TYPE_RESOURCE,
+       TASK_TYPE_SPARQL
 };
 
 struct _SparqlTaskData
 {
-       gchar *str;
+       guint type;
+
+       union {
+               struct {
+                       gchar *graph;
+                       TrackerResource *resource;
+               } resource;
+
+               struct {
+                       gchar *sparql;
+               } sparql;
+       } d;
 };
 
-struct _UpdateArrayData {
+struct _UpdateBatchData {
        TrackerSparqlBuffer *buffer;
        GPtrArray *tasks;
-       GArray *sparql_array;
+       TrackerBatch *batch;
        GTask *async_task;
 };
 
@@ -152,34 +169,27 @@ remove_task_foreach (TrackerTask     *task,
 }
 
 static void
-update_array_data_free (UpdateArrayData *update_data)
+update_batch_data_free (UpdateBatchData *batch_data)
 {
-       if (!update_data)
-               return;
-
-       if (update_data->sparql_array) {
-               /* The array contains pointers to strings in the tasks, so no need to
-                * deallocate its pointed contents, just the array itself. */
-               g_array_free (update_data->sparql_array, TRUE);
-       }
+       g_object_unref (batch_data->batch);
 
-       g_ptr_array_foreach (update_data->tasks,
+       g_ptr_array_foreach (batch_data->tasks,
                             (GFunc) remove_task_foreach,
-                            update_data->buffer);
-       g_ptr_array_unref (update_data->tasks);
+                            batch_data->buffer);
+       g_ptr_array_unref (batch_data->tasks);
 
-       g_slice_free (UpdateArrayData, update_data);
+       g_slice_free (UpdateBatchData, batch_data);
 }
 
 static void
-tracker_sparql_buffer_update_array_cb (GObject      *object,
-                                       GAsyncResult *result,
-                                       gpointer      user_data)
+batch_execute_cb (GObject      *object,
+                  GAsyncResult *result,
+                  gpointer      user_data)
 {
        TrackerSparqlBufferPrivate *priv;
        TrackerSparqlBuffer *buffer;
        GError *error = NULL;
-       UpdateArrayData *update_data;
+       UpdateBatchData *update_data;
 
        update_data = user_data;
        buffer = TRACKER_SPARQL_BUFFER (update_data->buffer);
@@ -190,11 +200,12 @@ tracker_sparql_buffer_update_array_cb (GObject      *object,
                      g_message ("(Sparql buffer) Finished array-update with %u tasks",
                                 update_data->tasks->len));
 
-       if (!tracker_sparql_connection_update_array_finish (priv->connection,
-                                                           result,
-                                                           &error)) {
-               g_critical ("  (Sparql buffer) Error in array-update: %s",
-                           error->message);
+       if (!tracker_batch_execute_finish (TRACKER_BATCH (object),
+                                          result,
+                                          &error)) {
+               g_critical ("Error executing batch: %s\n", error->message);
+               g_error_free (error);
+               return;
        }
 
        if (error) {
@@ -205,8 +216,8 @@ tracker_sparql_buffer_update_array_cb (GObject      *object,
                                       (GDestroyNotify) g_ptr_array_unref);
        }
 
-       /* Note that tasks are actually deallocated here */
-       update_array_data_free (update_data);
+       g_clear_error (&error);
+       update_batch_data_free (update_data);
 }
 
 gboolean
@@ -216,9 +227,7 @@ tracker_sparql_buffer_flush (TrackerSparqlBuffer *buffer,
                              gpointer             user_data)
 {
        TrackerSparqlBufferPrivate *priv;
-       GArray *sparql_array;
-       UpdateArrayData *update_data;
-       gint i;
+       UpdateBatchData *update_data;
 
        priv = tracker_sparql_buffer_get_instance_private (buffer);
 
@@ -233,22 +242,10 @@ tracker_sparql_buffer_flush (TrackerSparqlBuffer *buffer,
 
        TRACKER_NOTE (MINER_FS_EVENTS, g_message ("Flushing SPARQL buffer, reason: %s", reason));
 
-       /* Loop buffer and construct array of strings */
-       sparql_array = g_array_new (FALSE, TRUE, sizeof (gchar *));
-
-       for (i = 0; i < priv->tasks->len; i++) {
-               SparqlTaskData *task_data;
-               TrackerTask *task;
-
-               task = g_ptr_array_index (priv->tasks, i);
-               task_data = tracker_task_get_data (task);
-               g_array_append_val (sparql_array, task_data->str);
-       }
-
-       update_data = g_slice_new0 (UpdateArrayData);
+       update_data = g_slice_new0 (UpdateBatchData);
        update_data->buffer = buffer;
        update_data->tasks = g_ptr_array_ref (priv->tasks);
-       update_data->sparql_array = sparql_array;
+       update_data->batch = g_object_ref (priv->batch);
        update_data->async_task = g_task_new (buffer, NULL, cb, user_data);
 
        /* Empty pool, update_data will keep
@@ -258,14 +255,12 @@ tracker_sparql_buffer_flush (TrackerSparqlBuffer *buffer,
        g_ptr_array_unref (priv->tasks);
        priv->tasks = NULL;
        priv->n_updates++;
+       g_clear_object (&priv->batch);
 
-       /* Start the update */
-       tracker_sparql_connection_update_array_async (priv->connection,
-                                                     (gchar **) update_data->sparql_array->data,
-                                                     update_data->sparql_array->len,
-                                                     NULL,
-                                                     tracker_sparql_buffer_update_array_cb,
-                                                     update_data);
+       tracker_batch_execute_async (update_data->batch,
+                                    NULL,
+                                    batch_execute_cb,
+                                    update_data);
        return TRUE;
 }
 
@@ -289,24 +284,43 @@ sparql_buffer_push_to_pool (TrackerSparqlBuffer *buffer,
        g_ptr_array_add (priv->tasks, tracker_task_ref (task));
 }
 
-void
-tracker_sparql_buffer_push (TrackerSparqlBuffer *buffer,
-                            TrackerTask         *task)
+static TrackerBatch *
+tracker_sparql_buffer_get_current_batch (TrackerSparqlBuffer *buffer)
 {
-       g_return_if_fail (TRACKER_IS_SPARQL_BUFFER (buffer));
-       g_return_if_fail (task != NULL);
+       TrackerSparqlBufferPrivate *priv;
 
-       sparql_buffer_push_to_pool (buffer, task);
+       g_return_val_if_fail (TRACKER_IS_SPARQL_BUFFER (buffer), NULL);
+
+       priv = tracker_sparql_buffer_get_instance_private (TRACKER_SPARQL_BUFFER (buffer));
+
+       if (!priv->batch)
+               priv->batch = tracker_sparql_connection_create_batch (priv->connection);
+
+       return priv->batch;
+}
+
+static SparqlTaskData *
+sparql_task_data_new_resource (const gchar     *graph,
+                               TrackerResource *resource)
+{
+       SparqlTaskData *task_data;
+
+       task_data = g_slice_new0 (SparqlTaskData);
+       task_data->type = TASK_TYPE_RESOURCE;
+       task_data->d.resource.resource = g_object_ref (resource);
+       task_data->d.resource.graph = g_strdup (graph);
+
+       return task_data;
 }
 
 static SparqlTaskData *
-sparql_task_data_new (gchar *data,
-                      guint  flags)
+sparql_task_data_new_sparql (const gchar *sparql)
 {
        SparqlTaskData *task_data;
 
        task_data = g_slice_new0 (SparqlTaskData);
-       task_data->str = data;
+       task_data->type = TASK_TYPE_SPARQL;
+       task_data->d.sparql.sparql = g_strdup (sparql);
 
        return task_data;
 }
@@ -314,40 +328,81 @@ sparql_task_data_new (gchar *data,
 static void
 sparql_task_data_free (SparqlTaskData *data)
 {
-       g_free (data->str);
+       if (data->type == TASK_TYPE_RESOURCE) {
+               g_clear_object (&data->d.resource.resource);
+               g_free (data->d.resource.graph);
+       } else if (data->type == TASK_TYPE_SPARQL) {
+               g_free (data->d.sparql.sparql);
+       }
+
        g_slice_free (SparqlTaskData, data);
 }
 
-TrackerTask *
-tracker_sparql_task_new_take_sparql_str (GFile *file,
-                                         gchar *sparql_str)
+void
+tracker_sparql_buffer_push (TrackerSparqlBuffer *buffer,
+                            GFile               *file,
+                            const gchar         *graph,
+                            TrackerResource     *resource)
 {
+       TrackerBatch *batch;
+       TrackerTask *task;
        SparqlTaskData *data;
 
-       data = sparql_task_data_new (sparql_str, 0);
-       return tracker_task_new (file, data,
+       g_return_if_fail (TRACKER_IS_SPARQL_BUFFER (buffer));
+       g_return_if_fail (G_IS_FILE (file));
+       g_return_if_fail (TRACKER_IS_RESOURCE (resource));
+
+       batch = tracker_sparql_buffer_get_current_batch (buffer);
+       tracker_batch_add_resource (batch, graph, resource);
+
+       data = sparql_task_data_new_resource (graph, resource);
+
+       task = tracker_task_new (file, data,
                                 (GDestroyNotify) sparql_task_data_free);
+       sparql_buffer_push_to_pool (buffer, task);
+       tracker_task_unref (task);
 }
 
-TrackerTask *
-tracker_sparql_task_new_with_sparql_str (GFile       *file,
-                                         const gchar *sparql_str)
+void
+tracker_sparql_buffer_push_sparql (TrackerSparqlBuffer *buffer,
+                                   GFile               *file,
+                                   const gchar         *sparql)
 {
+       TrackerBatch *batch;
+       TrackerTask *task;
        SparqlTaskData *data;
 
-       data = sparql_task_data_new (g_strdup (sparql_str), 0);
-       return tracker_task_new (file, data,
+       g_return_if_fail (TRACKER_IS_SPARQL_BUFFER (buffer));
+       g_return_if_fail (G_IS_FILE (file));
+       g_return_if_fail (sparql != NULL);
+
+       batch = tracker_sparql_buffer_get_current_batch (buffer);
+       tracker_batch_add_sparql (batch, sparql);
+
+       data = sparql_task_data_new_sparql (sparql);
+
+       task = tracker_task_new (file, data,
                                 (GDestroyNotify) sparql_task_data_free);
+       sparql_buffer_push_to_pool (buffer, task);
+       tracker_task_unref (task);
 }
 
-const gchar *
+gchar *
 tracker_sparql_task_get_sparql (TrackerTask *task)
 {
        SparqlTaskData *task_data;
 
        task_data = tracker_task_get_data (task);
 
-       return task_data->str;
+       if (task_data->type == TASK_TYPE_RESOURCE) {
+               return tracker_resource_print_sparql_update (task_data->d.resource.resource,
+                                                            NULL,
+                                                            task_data->d.resource.graph);
+       } else if (task_data->type == TASK_TYPE_SPARQL) {
+               return g_strdup (task_data->d.sparql.sparql);
+       }
+
+       return NULL;
 }
 
 GPtrArray *
diff --git a/src/libtracker-miner/tracker-sparql-buffer.h b/src/libtracker-miner/tracker-sparql-buffer.h
index 0d9c5fce2..af2dc3af6 100644
--- a/src/libtracker-miner/tracker-sparql-buffer.h
+++ b/src/libtracker-miner/tracker-sparql-buffer.h
@@ -73,17 +73,18 @@ GPtrArray *          tracker_sparql_buffer_flush_finish (TrackerSparqlBuffer  *b
                                                          GAsyncResult         *res,
                                                          GError              **error);
 
-void                 tracker_sparql_buffer_push  (TrackerSparqlBuffer *buffer,
-                                                  TrackerTask         *task);
+void                 tracker_sparql_buffer_push (TrackerSparqlBuffer *buffer,
+                                                 GFile               *file,
+                                                 const gchar         *graph,
+                                                 TrackerResource     *resource);
+void                 tracker_sparql_buffer_push_sparql (TrackerSparqlBuffer *buffer,
+                                                        GFile               *file,
+                                                        const gchar         *sparql);
 
 TrackerSparqlBufferState tracker_sparql_buffer_get_state (TrackerSparqlBuffer *buffer,
                                                           GFile               *file);
 
-TrackerTask *        tracker_sparql_task_new_take_sparql_str (GFile                *file,
-                                                              gchar                *sparql_str);
-TrackerTask *        tracker_sparql_task_new_with_sparql_str (GFile                *file,
-                                                              const gchar          *sparql_str);
-const gchar *        tracker_sparql_task_get_sparql          (TrackerTask *task);
+gchar *              tracker_sparql_task_get_sparql          (TrackerTask *task);
 
 G_END_DECLS
 
diff --git a/src/miners/fs/tracker-miner-files.c b/src/miners/fs/tracker-miner-files.c
index f1604274c..bff67fad8 100644
--- a/src/miners/fs/tracker-miner-files.c
+++ b/src/miners/fs/tracker-miner-files.c
@@ -183,19 +183,24 @@ static void        set_up_application_indexing          (TrackerMinerFiles    *m
 static void        index_applications_changed_cb        (GObject              *gobject,
                                                          GParamSpec           *arg1,
                                                          gpointer              user_data);
-static gchar *     miner_files_process_file             (TrackerMinerFS       *fs,
+static void        miner_files_process_file             (TrackerMinerFS       *fs,
                                                          GFile                *file,
-                                                         GFileInfo            *info);
-static gchar *     miner_files_process_file_attributes  (TrackerMinerFS       *fs,
+                                                         GFileInfo            *info,
+                                                         TrackerSparqlBuffer  *buffer);
+static void        miner_files_process_file_attributes  (TrackerMinerFS       *fs,
                                                          GFile                *file,
-                                                         GFileInfo            *info);
-static gchar *     miner_files_remove_children          (TrackerMinerFS       *fs,
-                                                         GFile                *file);
-static gchar *     miner_files_remove_file              (TrackerMinerFS       *fs,
-                                                         GFile                *file);
-static gchar *     miner_files_move_file                (TrackerMinerFS       *fs,
+                                                         GFileInfo            *info,
+                                                         TrackerSparqlBuffer  *buffer);
+static void        miner_files_remove_children          (TrackerMinerFS       *fs,
+                                                         GFile                *file,
+                                                         TrackerSparqlBuffer  *buffer);
+static void        miner_files_remove_file              (TrackerMinerFS       *fs,
+                                                         GFile                *file,
+                                                         TrackerSparqlBuffer  *buffer);
+static void        miner_files_move_file                (TrackerMinerFS       *fs,
                                                          GFile                *file,
                                                          GFile                *source_file,
+                                                         TrackerSparqlBuffer  *buffer,
                                                          gboolean              recursive);
 static void        miner_files_finished                 (TrackerMinerFS       *fs,
                                                          gdouble               elapsed,
@@ -2068,19 +2073,20 @@ miner_files_create_folder_information_element (TrackerMinerFiles *miner,
        return resource;
 }
 
-static gchar *
-miner_files_process_file (TrackerMinerFS *fs,
-                          GFile          *file,
-                          GFileInfo      *file_info)
+static void
+miner_files_process_file (TrackerMinerFS      *fs,
+                          GFile               *file,
+                          GFileInfo           *file_info,
+                          TrackerSparqlBuffer *buffer)
 {
        TrackerMinerFilesPrivate *priv;
-       TrackerResource *resource, *folder_resource = NULL;
+       TrackerResource *resource = NULL, *folder_resource = NULL, *graph_file = NULL;
        const gchar *mime_type, *graph;
        gchar *parent_urn;
        gchar *delete_properties_sparql = NULL;
        guint64 time_;
        GFile *parent;
-       gchar *uri, *sparql_str, *sparql_update_str, *time_str, *ie_update_str = NULL, *graph_file_str = NULL;
+       gchar *uri, *time_str;
        gboolean is_directory;
 
        priv = TRACKER_MINER_FILES (fs)->private;
@@ -2156,20 +2162,9 @@ miner_files_process_file (TrackerMinerFS *fs,
 
        miner_files_add_to_datasource (TRACKER_MINER_FILES (fs), file, resource, folder_resource);
 
-       sparql_update_str = tracker_resource_print_sparql_update (resource, NULL, DEFAULT_GRAPH);
-
-       if (folder_resource) {
-               ie_update_str = tracker_resource_print_sparql_update (folder_resource,
-                                                                     NULL,
-                                                                     DEFAULT_GRAPH);
-               g_object_unref (folder_resource);
-       }
-
        graph = tracker_extract_module_manager_get_graph (mime_type);
 
        if (graph) {
-               TrackerResource *graph_file;
-
                /* This mimetype will be extracted by some module, pre-fill the
                 * nfo:FileDataObject in that graph.
                 */
@@ -2180,38 +2175,33 @@ miner_files_process_file (TrackerMinerFS *fs,
                time_str = tracker_date_to_string (time_);
                tracker_resource_set_string (graph_file, "nfo:fileLastModified", time_str);
                g_free (time_str);
-
-               graph_file_str = tracker_resource_print_sparql_update (graph_file,
-                                                                      NULL, graph);
-               g_object_unref (graph_file);
        }
 
-       sparql_str = g_strdup_printf ("%s %s %s %s",
-                                     delete_properties_sparql ? delete_properties_sparql : "",
-                                     sparql_update_str,
-                                     ie_update_str ? ie_update_str : "",
-                                     graph_file_str ? graph_file_str : "");
-       g_free (ie_update_str);
-       g_free (delete_properties_sparql);
-       g_free (graph_file_str);
+       if (delete_properties_sparql)
+               tracker_sparql_buffer_push_sparql (buffer, file, delete_properties_sparql);
 
-       g_object_run_dispose (G_OBJECT (resource));
-       g_object_unref (resource);
-       g_free (uri);
-       g_free (sparql_update_str);
+       tracker_sparql_buffer_push (buffer, file, DEFAULT_GRAPH, resource);
 
-       return sparql_str;
+       if (graph_file)
+               tracker_sparql_buffer_push (buffer, file, graph, graph_file);
+       if (folder_resource)
+               tracker_sparql_buffer_push (buffer, file, DEFAULT_GRAPH, folder_resource);
 
+       g_object_unref (resource);
+       g_clear_object (&folder_resource);
+       g_clear_object (&graph_file);
+       g_free (uri);
 }
 
-static gchar *
-miner_files_process_file_attributes (TrackerMinerFS *fs,
-                                     GFile          *file,
-                                     GFileInfo      *info)
+static void
+miner_files_process_file_attributes (TrackerMinerFS      *fs,
+                                     GFile               *file,
+                                     GFileInfo           *info,
+                                     TrackerSparqlBuffer *buffer)
 {
        TrackerResource *resource;
        guint64 time_;
-       gchar *uri, *time_str, *sparql_str;
+       gchar *uri, *time_str;
 
        uri = g_file_get_uri (file);
        resource = tracker_resource_new (uri);
@@ -2238,11 +2228,8 @@ miner_files_process_file_attributes (TrackerMinerFS *fs,
 
        g_free (uri);
 
-       sparql_str = tracker_resource_print_sparql_update (resource, NULL, DEFAULT_GRAPH);
-
+       tracker_sparql_buffer_push (buffer, file, DEFAULT_GRAPH, resource);
        g_object_unref (resource);
-
-       return sparql_str;
 }
 
 static void
@@ -2258,15 +2245,16 @@ miner_files_finished (TrackerMinerFS *fs,
        tracker_miner_files_check_unextracted (TRACKER_MINER_FILES (fs));
 }
 
-static gchar *
-create_delete_sparql (GFile    *file,
-                     gboolean  delete_self,
-                     gboolean  delete_children)
+static void
+add_delete_sparql (GFile               *file,
+                   TrackerSparqlBuffer *buffer,
+                   gboolean             delete_self,
+                   gboolean             delete_children)
 {
        GString *sparql;
        gchar *uri;
 
-       g_return_val_if_fail (delete_self || delete_children, NULL);
+       g_return_if_fail (delete_self || delete_children);
 
        uri = g_file_get_uri (file);
        sparql = g_string_new ("DELETE { "
@@ -2301,28 +2289,32 @@ create_delete_sparql (GFile    *file,
        g_string_append (sparql, ")}");
        g_free (uri);
 
-       return g_string_free (sparql, FALSE);
+       tracker_sparql_buffer_push_sparql (buffer, file, sparql->str);
+       g_string_free (sparql, TRUE);
 }
 
-static gchar *
-miner_files_remove_children (TrackerMinerFS *fs,
-                             GFile          *file)
+static void
+miner_files_remove_children (TrackerMinerFS      *fs,
+                             GFile               *file,
+                             TrackerSparqlBuffer *buffer)
 {
-       return create_delete_sparql (file, FALSE, TRUE);
+       add_delete_sparql (file, buffer, FALSE, TRUE);
 }
 
-static gchar *
-miner_files_remove_file (TrackerMinerFS *fs,
-                         GFile          *file)
+static void
+miner_files_remove_file (TrackerMinerFS      *fs,
+                         GFile               *file,
+                         TrackerSparqlBuffer *buffer)
 {
-       return create_delete_sparql (file, TRUE, TRUE);
+       add_delete_sparql (file, buffer, TRUE, TRUE);
 }
 
-static gchar *
-miner_files_move_file (TrackerMinerFS *fs,
-                       GFile          *file,
-                       GFile          *source_file,
-                       gboolean        recursive)
+static void
+miner_files_move_file (TrackerMinerFS      *fs,
+                       GFile               *file,
+                       GFile               *source_file,
+                       TrackerSparqlBuffer *buffer,
+                       gboolean             recursive)
 {
        GString *sparql = g_string_new (NULL);
        gchar *uri, *source_uri, *display_name, *container_clause = NULL;
@@ -2470,12 +2462,13 @@ miner_files_move_file (TrackerMinerFS *fs,
                                        uri, source_uri, source_uri);
        }
 
+       tracker_sparql_buffer_push_sparql (buffer, file, sparql->str);
+
        g_free (uri);
        g_free (source_uri);
        g_free (display_name);
        g_clear_object (&new_parent);
-
-       return g_string_free (sparql, FALSE);
+       g_string_free (sparql, TRUE);
 }
 
 TrackerMiner *
diff --git a/tests/libtracker-miner/tracker-miner-fs-test.c b/tests/libtracker-miner/tracker-miner-fs-test.c
index 889a81b3b..ec8b39ffe 100644
--- a/tests/libtracker-miner/tracker-miner-fs-test.c
+++ b/tests/libtracker-miner/tracker-miner-fs-test.c
@@ -27,15 +27,16 @@ G_DEFINE_TYPE (TestMiner, test_miner, TRACKER_TYPE_MINER_FS)
                    TrackerMinerFSTestFixture, NULL, \
                    fixture_setup, func, fixture_teardown)
 
-static gchar *
-test_miner_process_file (TrackerMinerFS *miner,
-                         GFile          *file,
-                         GFileInfo      *info)
+static void
+test_miner_process_file (TrackerMinerFS      *miner,
+                         GFile               *file,
+                         GFileInfo           *info,
+                         TrackerSparqlBuffer *buffer)
 {
        TrackerResource *resource;
        GDateTime *modification_time;
        TrackerIndexingTree *tree;
-       gchar *sparql, *uri, *parent_uri, *str;
+       gchar *uri, *parent_uri, *str;
        GFile *parent;
 
        ((TestMiner *) miner)->n_process_file++;
@@ -87,16 +88,15 @@ test_miner_process_file (TrackerMinerFS *miner,
                g_object_unref (parent);
        }
 
-       sparql = tracker_resource_print_sparql_update (resource, NULL, "tracker:FileSystem");
+       tracker_sparql_buffer_push (buffer, file, "tracker:FileSystem", resource);
        g_object_unref (resource);
        g_free (uri);
-
-       return sparql;
 }
 
-static gchar *
-test_miner_remove_file (TrackerMinerFS *miner,
-                        GFile          *file)
+static void
+test_miner_remove_file (TrackerMinerFS      *miner,
+                        GFile               *file,
+                        TrackerSparqlBuffer *buffer)
 {
        gchar *sparql, *uri;
 
@@ -110,12 +110,14 @@ test_miner_remove_file (TrackerMinerFS *miner,
                                  "}", uri, uri);
        g_free (uri);
 
-       return sparql;
+       tracker_sparql_buffer_push_sparql (buffer, file, sparql);
+       g_free (sparql);
 }
 
-static gchar *
-test_miner_remove_children (TrackerMinerFS *miner,
-                            GFile          *file)
+static void
+test_miner_remove_children (TrackerMinerFS      *miner,
+                            GFile               *file,
+                            TrackerSparqlBuffer *buffer)
 {
        gchar *sparql, *uri;
 
@@ -129,24 +131,20 @@ test_miner_remove_children (TrackerMinerFS *miner,
                                  "}", uri);
        g_free (uri);
 
-       return sparql;
+       tracker_sparql_buffer_push_sparql (buffer, file, sparql);
+       g_free (sparql);
 }
 
-static gchar *
-test_miner_move_file (TrackerMinerFS *miner,
-                      GFile          *dest,
-                      GFile          *source,
-                      gboolean        recursive)
+static void
+test_miner_move_file (TrackerMinerFS      *miner,
+                      GFile               *dest,
+                      GFile               *source,
+                      TrackerSparqlBuffer *buffer,
+                      gboolean             recursive)
 {
-       gchar *sparql, *delete, *insert;
-
        /* Caution: This does not deal with recursive moves */
-       delete = test_miner_remove_file (miner, source);
-       insert = test_miner_process_file (miner, dest, NULL);
-       sparql = g_strdup_printf ("%s\n%s", delete, insert);
-       sparql[strlen(sparql) - 2] = '\0';
-
-       return sparql;
+       test_miner_remove_file (miner, source, buffer);
+       test_miner_process_file (miner, dest, NULL, buffer);
 }
 
 static void



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