[tracker/miner-fs-refactor] libtracker-miner: Traverse children selectively in TrackerFileSystem



commit 52133d04f01e8141239837e264a14d6f8739db44
Author: Carlos Garnacho <carlos lanedo com>
Date:   Tue Nov 22 15:47:19 2011 +0100

    libtracker-miner: Traverse children selectively in TrackerFileSystem
    
    Now, returning FALSE in the TrackerFileSystemTraverseFunc given to
    tracker_file_system_traverse() means the node will not be recursed,
    but the traversal will still continue.
    
    This deviates a bit from g_node_traverse, but makes more sense given
    the common operations in a filesystem representation.
    
    This is now used in TrackerMinerFS to stop traversal on deleted
    folders.

 src/libtracker-miner/tracker-file-notifier.c |    5 +---
 src/libtracker-miner/tracker-file-system.c   |   34 +++++++++++++++++++++++--
 2 files changed, 32 insertions(+), 7 deletions(-)
---
diff --git a/src/libtracker-miner/tracker-file-notifier.c b/src/libtracker-miner/tracker-file-notifier.c
index d5e7fdd..10f9280 100644
--- a/src/libtracker-miner/tracker-file-notifier.c
+++ b/src/libtracker-miner/tracker-file-notifier.c
@@ -219,10 +219,7 @@ file_notifier_traverse_tree_foreach (GFile    *file,
 		/* In store but not in disk, delete */
 		g_signal_emit (notifier, signals[FILE_DELETED], 0, file);
 
-		/* FIXME: Should avoid recursing through children,
-		 * but we're not allowed to modify the tree during
-		 * traversal, nor have a way to skip recursing within
-		 */
+		return TRUE;
 	} else if (disk_mtime && !store_mtime) {
 		/* In disk but not in store, create */
 		g_signal_emit (notifier, signals[FILE_CREATED], 0, file);
diff --git a/src/libtracker-miner/tracker-file-system.c b/src/libtracker-miner/tracker-file-system.c
index 9aaa4ba..cfcab23 100644
--- a/src/libtracker-miner/tracker-file-system.c
+++ b/src/libtracker-miner/tracker-file-system.c
@@ -514,20 +514,45 @@ tracker_file_system_peek_parent (TrackerFileSystem *file_system,
 typedef struct {
 	TrackerFileSystemTraverseFunc func;
 	gpointer user_data;
+	GSList *ignore_children;
 } TraverseData;
 
+static gint
+node_is_child_of_ignored (gconstpointer a,
+                          gconstpointer b)
+{
+	if (g_node_is_ancestor ((GNode *) a, (GNode *) b))
+		return 0;
+
+	return 1;
+}
+
 static gboolean
 traverse_filesystem_func (GNode    *node,
                           gpointer  user_data)
 {
 	TraverseData *data = user_data;
 	FileNodeData *node_data;
-	gboolean retval;
+	gboolean retval = FALSE;
 
 	node_data = node->data;
-	retval = data->func (node_data->file, data->user_data);
 
-	return retval;
+	if (!data->ignore_children ||
+	    !g_slist_find_custom (data->ignore_children,
+	                          node, node_is_child_of_ignored)) {
+		/* This node isn't a child of an
+		 * ignored one, execute callback
+		 */
+		retval = data->func (node_data->file, data->user_data);
+	}
+
+	/* Avoid recursing within the children of this node */
+	if (retval) {
+		data->ignore_children = g_slist_prepend (data->ignore_children,
+		                                         node);
+	}
+
+	return FALSE;
 }
 
 void
@@ -554,6 +579,7 @@ tracker_file_system_traverse (TrackerFileSystem             *file_system,
 
 	data.func = func;
 	data.user_data = user_data;
+	data.ignore_children = NULL;
 
 	g_node_traverse (node,
 	                 order,
@@ -561,6 +587,8 @@ tracker_file_system_traverse (TrackerFileSystem             *file_system,
 	                 -1,
 	                 traverse_filesystem_func,
 	                 &data);
+
+	g_slist_free (data.ignore_children);
 }
 
 void



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