[tracker/wip/miner-fs-refactor: 30/51] libtracker-miner: Add TrackerFileNotifier
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/miner-fs-refactor: 30/51] libtracker-miner: Add TrackerFileNotifier
- Date: Fri, 30 Sep 2011 10:35:18 +0000 (UTC)
commit 6ef37cc40aa5d4f37e9f73145863ddcfe2be9a8b
Author: Carlos Garnacho <carlos lanedo com>
Date: Tue Sep 27 15:26:17 2011 +0200
libtracker-miner: Add TrackerFileNotifier
TrackerFileNotifier is meant to be a high-level object that notifies
about any update/addition/removal affecting the indexed content of
a miner. At the moment only basic infrastructure has been added, so
it only crawls the contents.
src/libtracker-miner/Makefile.am | 5 +-
src/libtracker-miner/tracker-file-notifier.c | 444 ++++++++++++++++++++++++++
src/libtracker-miner/tracker-file-notifier.h | 72 +++++
src/libtracker-miner/tracker-miner.h | 1 +
4 files changed, 521 insertions(+), 1 deletions(-)
---
diff --git a/src/libtracker-miner/Makefile.am b/src/libtracker-miner/Makefile.am
index 6b6c140..1c2fd7f 100644
--- a/src/libtracker-miner/Makefile.am
+++ b/src/libtracker-miner/Makefile.am
@@ -68,6 +68,8 @@ libtracker_miner_ TRACKER_API_VERSION@_la_SOURCES = \
$(password_provider_sources) \
$(crawler_sources) \
$(miner_sources) \
+ tracker-file-notifier.h \
+ tracker-file-notifier.c \
tracker-file-system.h \
tracker-file-system.c \
tracker-indexing-tree.c \
@@ -82,6 +84,7 @@ libtracker_miner_ TRACKER_API_VERSION@_la_SOURCES = \
libtracker_minerinclude_HEADERS = \
tracker-albumart.h \
tracker-crawler.h \
+ tracker-file-notifier.h \
tracker-file-system.h \
tracker-indexing-tree.h \
tracker-miner.h \
@@ -101,7 +104,7 @@ if !ENABLE_GCOV
# Using enable_gcov instead of have_unit_test because when doing a release
# we disable gcov but NOT the unit tests
libtracker_miner_ TRACKER_API_VERSION@_la_LDFLAGS += \
- -export-symbols-regex '^tracker_(miner|thumbnailer|crawler|storage|password_provider|network_provider|indexing_tree|file_system)_.*'
+ -export-symbols-regex '^tracker_(miner|thumbnailer|crawler|storage|password_provider|network_provider|indexing_tree|file_system|file_notifier)_.*'
endif
libtracker_miner_ TRACKER_API_VERSION@_la_LIBADD = \
diff --git a/src/libtracker-miner/tracker-file-notifier.c b/src/libtracker-miner/tracker-file-notifier.c
new file mode 100644
index 0000000..cf9ba82
--- /dev/null
+++ b/src/libtracker-miner/tracker-file-notifier.c
@@ -0,0 +1,444 @@
+/*
+ * Copyright (C) 2011, Nokia <ivan frade nokia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Carlos Garnacho <carlos lanedo com>
+ */
+
+#include <libtracker-common/tracker-log.h>
+
+#include "tracker-file-notifier.h"
+#include "tracker-file-system.h"
+#include "tracker-crawler.h"
+#include "tracker-monitor.h"
+
+enum {
+ PROP_0,
+ PROP_INDEXING_TREE
+};
+
+typedef struct {
+ TrackerIndexingTree *indexing_tree;
+ TrackerFileSystem *file_system;
+
+ TrackerCrawler *crawler;
+ TrackerMonitor *monitor;
+
+ GTimer *crawling_timer;
+
+ /* List of pending directory
+ * trees to get data from
+ */
+ GList *pending_index_roots;
+
+ guint stopped : 1;
+} TrackerFileNotifierPrivate;
+
+G_DEFINE_TYPE (TrackerFileNotifier, tracker_file_notifier, G_TYPE_OBJECT)
+
+static void
+tracker_file_notifier_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TrackerFileNotifierPrivate *priv;
+
+ priv = TRACKER_FILE_NOTIFIER (object)->priv;
+
+ switch (prop_id) {
+ case PROP_INDEXING_TREE:
+ priv->indexing_tree = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+tracker_file_notifier_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TrackerFileNotifierPrivate *priv;
+
+ priv = TRACKER_FILE_NOTIFIER (object)->priv;
+
+ switch (prop_id) {
+ case PROP_INDEXING_TREE:
+ g_value_set_object (value, priv->indexing_tree);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/* Crawler signal handlers */
+static gboolean
+crawler_check_file_cb (TrackerCrawler *crawler,
+ GFile *file,
+ gpointer user_data)
+{
+ TrackerFileNotifierPrivate *priv;
+
+ priv = TRACKER_FILE_NOTIFIER (user_data)->priv;
+
+ return tracker_indexing_tree_file_is_indexable (priv->indexing_tree,
+ file,
+ G_FILE_TYPE_REGULAR);
+}
+
+static gboolean
+crawler_check_directory_cb (TrackerCrawler *crawler,
+ GFile *directory,
+ gpointer user_data)
+{
+ TrackerFileNotifierPrivate *priv;
+
+ priv = TRACKER_FILE_NOTIFIER (user_data)->priv;
+
+ return tracker_indexing_tree_file_is_indexable (priv->indexing_tree,
+ directory,
+ G_FILE_TYPE_DIRECTORY);
+}
+
+static gboolean
+crawler_check_directory_contents_cb (TrackerCrawler *crawler,
+ GFile *parent,
+ GList *children,
+ gpointer user_data)
+{
+ TrackerFileNotifierPrivate *priv;
+ gboolean process;
+
+ priv = TRACKER_FILE_NOTIFIER (user_data)->priv;
+ process = tracker_indexing_tree_parent_is_indexable (priv->indexing_tree,
+ parent, children);
+#if 0
+ if (process) {
+ TrackerDirectoryFlags parent_flags;
+ gboolean add_monitor;
+
+ tracker_indexing_tree_get_root (priv->indexing_tree,
+ parent, &parent_flags);
+
+ add_monitor = (parent_flags & TRACKER_DIRECTORY_FLAG_MONITOR) != 0;
+
+ /* FIXME: add monitor */
+ }
+#endif
+
+ return process;
+}
+
+typedef struct {
+ TrackerFileNotifier *notifier;
+ GNode *cur_parent_node;
+ TrackerFile *cur_parent;
+} DirectoryCrawledData;
+
+static gboolean
+file_notifier_add_node_foreach (GNode *node,
+ gpointer user_data)
+{
+ DirectoryCrawledData *data = user_data;
+ TrackerFileNotifierPrivate *priv;
+ GFile *file;
+
+ priv = data->notifier->priv;
+ file = node->data;
+
+ if (node->parent &&
+ node->parent != data->cur_parent_node) {
+ data->cur_parent_node = node->parent;
+ data->cur_parent = tracker_file_system_peek_file (priv->file_system,
+ node->parent->data);
+ } else {
+ data->cur_parent_node = NULL;
+ data->cur_parent = NULL;
+ }
+
+ tracker_file_system_get_file (priv->file_system,
+ file,
+ G_FILE_TYPE_UNKNOWN,
+ data->cur_parent);
+ return FALSE;
+}
+
+static void
+crawler_directory_crawled_cb (TrackerCrawler *crawler,
+ GFile *directory,
+ GNode *tree,
+ guint directories_found,
+ guint directories_ignored,
+ guint files_found,
+ guint files_ignored,
+ gpointer user_data)
+{
+ DirectoryCrawledData data = { 0 };
+
+ data.notifier = user_data;
+ g_node_traverse (tree,
+ G_PRE_ORDER,
+ G_TRAVERSE_ALL,
+ -1,
+ file_notifier_add_node_foreach,
+ &data);
+
+ g_message (" Found %d directories, ignored %d directories",
+ directories_found,
+ directories_ignored);
+ g_message (" Found %d files, ignored %d files",
+ files_found,
+ files_ignored);
+}
+
+static gboolean
+crawl_directories_start (TrackerFileNotifier *notifier)
+{
+ TrackerFileNotifierPrivate *priv = notifier->priv;
+ TrackerDirectoryFlags flags;
+ GFile *directory;
+
+ if (!priv->pending_index_roots) {
+ return FALSE;
+ }
+
+ if (priv->stopped) {
+ return FALSE;
+ }
+
+ while (priv->pending_index_roots) {
+ directory = tracker_file_system_resolve_file (priv->file_system,
+ priv->pending_index_roots->data);
+
+ tracker_indexing_tree_get_root (priv->indexing_tree,
+ directory,
+ &flags);
+
+ if (tracker_crawler_start (priv->crawler,
+ directory,
+ (flags & TRACKER_DIRECTORY_FLAG_RECURSE) != 0)) {
+ g_timer_reset (priv->crawling_timer);
+ return TRUE;
+ }
+
+ /* Remove index root and try the next one */
+ priv->pending_index_roots = g_list_remove_link (priv->pending_index_roots,
+ priv->pending_index_roots);
+ }
+
+ return FALSE;
+}
+
+static void
+crawler_finished_cb (TrackerCrawler *crawler,
+ gboolean was_interrupted,
+ gpointer user_data)
+{
+ TrackerFileNotifier *notifier = user_data;
+ TrackerFileNotifierPrivate *priv = notifier->priv;
+
+ tracker_info ("%s crawling files after %2.2f seconds",
+ was_interrupted ? "Stopped" : "Finished",
+ g_timer_elapsed (priv->crawling_timer, NULL));
+
+ if (!was_interrupted) {
+ /* FIXME: signal delete signals for files found
+ * during crawling but not during querying */
+
+ /* We've finished indexing on the first element
+ * of the pending list, continue onto the next */
+ priv->pending_index_roots = g_list_remove_link (priv->pending_index_roots,
+ priv->pending_index_roots);
+
+ crawl_directories_start (notifier);
+ }
+}
+
+/* Indexing tree signal handlers */
+static void
+indexing_tree_directory_added (TrackerIndexingTree *indexing_tree,
+ GFile *directory,
+ gpointer user_data)
+{
+ TrackerFileNotifier *notifier = user_data;
+ TrackerFileNotifierPrivate *priv = notifier->priv;
+ gboolean start_crawler = FALSE;
+ TrackerDirectoryFlags flags;
+ TrackerFile *file;
+
+ tracker_indexing_tree_get_root (indexing_tree, directory, &flags);
+
+ file = tracker_file_system_get_file (priv->file_system, directory,
+ G_FILE_TYPE_DIRECTORY, NULL);
+
+ if (!priv->stopped &&
+ !priv->pending_index_roots) {
+ start_crawler = TRUE;
+ }
+
+ priv->pending_index_roots = g_list_append (priv->pending_index_roots,
+ file);
+ if (start_crawler) {
+ crawl_directories_start (notifier);
+ }
+}
+
+static void
+indexing_tree_directory_removed (TrackerIndexingTree *indexing_tree,
+ GFile *directory,
+ gpointer user_data)
+{
+ /* Signal as removed? depends on delete vs unmount */
+}
+
+static void
+tracker_file_notifier_finalize (GObject *object)
+{
+ TrackerFileNotifierPrivate *priv;
+
+ priv = TRACKER_FILE_NOTIFIER (object)->priv;
+
+ if (priv->indexing_tree) {
+ g_object_unref (priv->indexing_tree);
+ }
+
+ g_object_unref (priv->file_system);
+ g_object_unref (priv->crawler);
+
+ g_list_free (priv->pending_index_roots);
+
+ G_OBJECT_CLASS (tracker_file_notifier_parent_class)->finalize (object);
+}
+
+static void
+tracker_file_notifier_constructed (GObject *object)
+{
+ TrackerFileNotifierPrivate *priv;
+
+ priv = TRACKER_FILE_NOTIFIER (object)->priv;
+ g_assert (priv->indexing_tree);
+
+ g_signal_connect (priv->indexing_tree, "directory-added",
+ G_CALLBACK (indexing_tree_directory_added), object);
+ g_signal_connect (priv->indexing_tree, "directory-removed",
+ G_CALLBACK (indexing_tree_directory_removed), object);
+}
+
+static void
+tracker_file_notifier_class_init (TrackerFileNotifierClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = tracker_file_notifier_finalize;
+ object_class->set_property = tracker_file_notifier_set_property;
+ object_class->get_property = tracker_file_notifier_get_property;
+ object_class->constructed = tracker_file_notifier_constructed;
+
+ g_object_class_install_property (object_class,
+ PROP_INDEXING_TREE,
+ g_param_spec_object ("indexing-tree",
+ "Indexing tree",
+ "Indexing tree",
+ TRACKER_TYPE_INDEXING_TREE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_type_class_add_private (object_class,
+ sizeof (TrackerFileNotifierClass));
+}
+
+static void
+tracker_file_notifier_init (TrackerFileNotifier *notifier)
+{
+ TrackerFileNotifierPrivate *priv;
+
+ priv = notifier->priv =
+ G_TYPE_INSTANCE_GET_PRIVATE (notifier,
+ TRACKER_TYPE_FILE_NOTIFIER,
+ TrackerFileNotifierPrivate);
+
+ priv->file_system = tracker_file_system_new ();
+ priv->crawling_timer = g_timer_new ();
+ priv->stopped = TRUE;
+
+ /* Set up crawler */
+ priv->crawler = tracker_crawler_new ();
+ g_signal_connect (priv->crawler, "check-file",
+ G_CALLBACK (crawler_check_file_cb),
+ notifier);
+ g_signal_connect (priv->crawler, "check-directory",
+ G_CALLBACK (crawler_check_directory_cb),
+ notifier);
+ g_signal_connect (priv->crawler, "check-directory-contents",
+ G_CALLBACK (crawler_check_directory_contents_cb),
+ notifier);
+ g_signal_connect (priv->crawler, "directory-crawled",
+ G_CALLBACK (crawler_directory_crawled_cb),
+ notifier);
+ g_signal_connect (priv->crawler, "finished",
+ G_CALLBACK (crawler_finished_cb),
+ notifier);
+}
+
+TrackerFileNotifier *
+tracker_file_notifier_new (TrackerIndexingTree *indexing_tree)
+{
+ g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (indexing_tree), NULL);
+
+ return g_object_new (TRACKER_TYPE_FILE_NOTIFIER,
+ "indexing-tree", indexing_tree,
+ NULL);
+}
+
+gboolean
+tracker_file_notifier_start (TrackerFileNotifier *notifier)
+{
+ TrackerFileNotifierPrivate *priv;
+
+ g_return_val_if_fail (TRACKER_IS_FILE_NOTIFIER (notifier), FALSE);
+
+ priv = notifier->priv;
+
+ if (priv->stopped) {
+ priv->stopped = FALSE;
+
+ if (priv->pending_index_roots) {
+ crawl_directories_start (notifier);
+ }
+ }
+
+ return TRUE;
+}
+
+void
+tracker_file_notifier_stop (TrackerFileNotifier *notifier)
+{
+ TrackerFileNotifierPrivate *priv;
+
+ g_return_if_fail (TRACKER_IS_FILE_NOTIFIER (notifier));
+
+ priv = notifier->priv;
+
+ if (!priv->stopped) {
+ tracker_crawler_stop (priv->crawler);
+ priv->stopped = TRUE;
+ }
+}
diff --git a/src/libtracker-miner/tracker-file-notifier.h b/src/libtracker-miner/tracker-file-notifier.h
new file mode 100644
index 0000000..304171d
--- /dev/null
+++ b/src/libtracker-miner/tracker-file-notifier.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011, Nokia <ivan frade nokia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Carlos Garnacho <carlos lanedo com>
+ */
+
+#ifndef __TRACKER_FILE_NOTIFIER_H__
+#define __TRACKER_FILE_NOTIFIER_H__
+
+#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION)
+#error "Only <libtracker-miner/tracker-miner.h> can be included directly."
+#endif
+
+#include <gio/gio.h>
+#include "tracker-indexing-tree.h"
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_FILE_NOTIFIER (tracker_file_notifier_get_type ())
+#define TRACKER_FILE_NOTIFIER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_FILE_NOTIFIER, TrackerFileNotifier))
+#define TRACKER_FILE_NOTIFIER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_FILE_NOTIFIER, TrackerFileNotifierClass))
+#define TRACKER_IS_FILE_NOTIFIER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_FILE_NOTIFIER))
+#define TRACKER_IS_FILE_NOTIFIER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_FILE_NOTIFIER))
+#define TRACKER_FILE_NOTIFIER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_FILE_NOTIFIER, TrackerFileNotifierClass))
+
+typedef struct _TrackerFileNotifier TrackerFileNotifier;
+typedef struct _TrackerFileNotifierClass TrackerFileNotifierClass;
+
+struct _TrackerFileNotifier {
+ GObject parent_instance;
+ gpointer priv;
+};
+
+struct _TrackerFileNotifierClass {
+ GObjectClass parent_class;
+
+ void (* file_added) (TrackerFileNotifier *notifier,
+ GFile *file);
+ void (* file_updated) (TrackerFileNotifier *notifier,
+ GFile *file);
+ void (* file_deleted) (TrackerFileNotifier *notifier,
+ GFile *file);
+ void (* file_moved) (TrackerFileNotifier *notifier,
+ GFile *from,
+ GFile *to);
+};
+
+GType tracker_file_notifier_get_type (void) G_GNUC_CONST;
+
+TrackerFileNotifier* tracker_file_notifier_new (TrackerIndexingTree *indexing_tree);
+
+gboolean tracker_file_notifier_start (TrackerFileNotifier *notifier);
+void tracker_file_notifier_stop (TrackerFileNotifier *notifier);
+
+G_END_DECLS
+
+#endif /* __TRACKER_FILE_SYSTEM_H__ */
diff --git a/src/libtracker-miner/tracker-miner.h b/src/libtracker-miner/tracker-miner.h
index 824d897..0d3460b 100644
--- a/src/libtracker-miner/tracker-miner.h
+++ b/src/libtracker-miner/tracker-miner.h
@@ -35,6 +35,7 @@
#include <libtracker-miner/tracker-miner-enums.h>
#include <libtracker-miner/tracker-indexing-tree.h>
#include <libtracker-miner/tracker-file-system.h>
+#include <libtracker-miner/tracker-file-notifier.h>
#undef __LIBTRACKER_MINER_H_INSIDE__
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]