Commit a6f8afad authored by Carlos Garnacho's avatar Carlos Garnacho

libtracker-miner: Avoid signals for TrackerCrawler file check functions

Make file/directory checks through a func given through a setter, in order
to avoid signal emission overhead. This saves a bit of time as we emit up
to 2 signals per file.
parent ca554ed9
......@@ -95,6 +95,11 @@ struct TrackerCrawlerPrivate {
gchar *file_attributes;
/* Check func */
TrackerCrawlerCheckFunc check_func;
gpointer check_func_data;
GDestroyNotify check_func_destroy;
/* Status */
gboolean is_running;
gboolean is_finished;
......@@ -102,9 +107,6 @@ struct TrackerCrawlerPrivate {
};
enum {
CHECK_DIRECTORY,
CHECK_FILE,
CHECK_DIRECTORY_CONTENTS,
DIRECTORY_CRAWLED,
FINISHED,
LAST_SIGNAL
......@@ -124,11 +126,6 @@ static void crawler_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec);
static void crawler_finalize (GObject *object);
static gboolean check_defaults (TrackerCrawler *crawler,
GFile *file);
static gboolean check_contents_defaults (TrackerCrawler *crawler,
GFile *file,
GList *contents);
static void data_provider_data_free (DataProviderData *dpd);
static void data_provider_begin (TrackerCrawler *crawler,
......@@ -148,48 +145,11 @@ static void
tracker_crawler_class_init (TrackerCrawlerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
TrackerCrawlerClass *crawler_class = TRACKER_CRAWLER_CLASS (klass);
object_class->set_property = crawler_set_property;
object_class->get_property = crawler_get_property;
object_class->finalize = crawler_finalize;
crawler_class->check_directory = check_defaults;
crawler_class->check_file = check_defaults;
crawler_class->check_directory_contents = check_contents_defaults;
signals[CHECK_DIRECTORY] =
g_signal_new ("check-directory",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (TrackerCrawlerClass, check_directory),
tracker_accumulator_check_file,
NULL,
NULL,
G_TYPE_BOOLEAN,
1,
G_TYPE_FILE);
signals[CHECK_FILE] =
g_signal_new ("check-file",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (TrackerCrawlerClass, check_file),
tracker_accumulator_check_file,
NULL,
NULL,
G_TYPE_BOOLEAN,
1,
G_TYPE_FILE);
signals[CHECK_DIRECTORY_CONTENTS] =
g_signal_new ("check-directory-contents",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (TrackerCrawlerClass, check_directory_contents),
tracker_accumulator_check_file,
NULL,
NULL,
G_TYPE_BOOLEAN,
2, G_TYPE_FILE, G_TYPE_POINTER);
signals[DIRECTORY_CRAWLED] =
g_signal_new ("directory-crawled",
G_TYPE_FROM_CLASS (klass),
......@@ -284,6 +244,10 @@ crawler_finalize (GObject *object)
priv = tracker_crawler_get_instance_private (TRACKER_CRAWLER (object));
if (priv->check_func_data && priv->check_func_destroy) {
priv->check_func_destroy (priv->check_func_data);
}
if (priv->idle_id) {
g_source_remove (priv->idle_id);
}
......@@ -305,21 +269,6 @@ crawler_finalize (GObject *object)
G_OBJECT_CLASS (tracker_crawler_parent_class)->finalize (object);
}
static gboolean
check_defaults (TrackerCrawler *crawler,
GFile *file)
{
return TRUE;
}
static gboolean
check_contents_defaults (TrackerCrawler *crawler,
GFile *file,
GList *contents)
{
return TRUE;
}
TrackerCrawler *
tracker_crawler_new (TrackerDataProvider *data_provider)
{
......@@ -348,6 +297,39 @@ tracker_crawler_new (TrackerDataProvider *data_provider)
return crawler;
}
void
tracker_crawler_set_check_func (TrackerCrawler *crawler,
TrackerCrawlerCheckFunc func,
gpointer user_data,
GDestroyNotify destroy_notify)
{
TrackerCrawlerPrivate *priv;
g_return_if_fail (TRACKER_IS_CRAWLER (crawler));
priv = tracker_crawler_get_instance_private (crawler);
priv->check_func = func;
priv->check_func_data = user_data;
priv->check_func_destroy = destroy_notify;
}
static gboolean
invoke_check (TrackerCrawler *crawler,
TrackerCrawlerCheckFlags flags,
GFile *file,
GList *children)
{
TrackerCrawlerPrivate *priv;
priv = tracker_crawler_get_instance_private (crawler);
if (!priv->check_func)
return TRUE;
return priv->check_func (crawler, flags, file, children,
priv->check_func_data);
}
static gboolean
check_file (TrackerCrawler *crawler,
DirectoryRootInfo *info,
......@@ -358,7 +340,7 @@ check_file (TrackerCrawler *crawler,
priv = tracker_crawler_get_instance_private (crawler);
g_signal_emit (crawler, signals[CHECK_FILE], 0, file, &use);
use = invoke_check (crawler, TRACKER_CRAWLER_CHECK_FILE, file, NULL);
/* Crawler may have been stopped while waiting for the 'use' value,
* and the DirectoryRootInfo already disposed... */
......@@ -385,7 +367,7 @@ check_directory (TrackerCrawler *crawler,
priv = tracker_crawler_get_instance_private (crawler);
g_signal_emit (crawler, signals[CHECK_DIRECTORY], 0, file, &use);
use = invoke_check (crawler, TRACKER_CRAWLER_CHECK_DIRECTORY, file, NULL);
/* Crawler may have been stopped while waiting for the 'use' value,
* and the DirectoryRootInfo already disposed... */
......@@ -752,7 +734,7 @@ data_provider_data_process (DataProviderData *dpd)
children = g_list_prepend (children, child_data->child);
}
g_signal_emit (crawler, signals[CHECK_DIRECTORY_CONTENTS], 0, dpd->dir_file, children, &use);
use = invoke_check (crawler, TRACKER_CRAWLER_CHECK_CONTENT, dpd->dir_file, children);
g_list_free (children);
if (!use) {
......
......@@ -45,6 +45,18 @@ typedef struct TrackerCrawler TrackerCrawler;
typedef struct TrackerCrawlerClass TrackerCrawlerClass;
typedef struct TrackerCrawlerPrivate TrackerCrawlerPrivate;
typedef enum {
TRACKER_CRAWLER_CHECK_FILE = 1 << 0,
TRACKER_CRAWLER_CHECK_DIRECTORY = 1 << 1,
TRACKER_CRAWLER_CHECK_CONTENT = 1 << 2,
} TrackerCrawlerCheckFlags;
typedef gboolean (*TrackerCrawlerCheckFunc) (TrackerCrawler *crawler,
TrackerCrawlerCheckFlags flags,
GFile *file,
const GList *children,
gpointer user_data);
struct TrackerCrawler {
GObject parent;
};
......@@ -52,13 +64,6 @@ struct TrackerCrawler {
struct TrackerCrawlerClass {
GObjectClass parent;
gboolean (* check_directory) (TrackerCrawler *crawler,
GFile *file);
gboolean (* check_file) (TrackerCrawler *crawler,
GFile *file);
gboolean (* check_directory_contents) (TrackerCrawler *crawler,
GFile *file,
GList *contents);
void (* directory_crawled) (TrackerCrawler *crawler,
GFile *directory,
GNode *tree,
......@@ -84,6 +89,11 @@ const gchar * tracker_crawler_get_file_attributes (TrackerCrawler *crawler);
GFileInfo * tracker_crawler_get_file_info (TrackerCrawler *crawler,
GFile *file);
void tracker_crawler_set_check_func (TrackerCrawler *crawler,
TrackerCrawlerCheckFunc func,
gpointer user_data,
GDestroyNotify destroy_notify);
G_END_DECLS
#endif /* __LIBTRACKER_MINER_CRAWLER_H__ */
......@@ -196,13 +196,12 @@ root_data_free (RootData *data)
/* Crawler signal handlers */
static gboolean
crawler_check_file_cb (TrackerCrawler *crawler,
GFile *file,
gpointer user_data)
check_file (TrackerFileNotifier *notifier,
GFile *file)
{
TrackerFileNotifierPrivate *priv;
priv = tracker_file_notifier_get_instance_private (user_data);
priv = tracker_file_notifier_get_instance_private (notifier);
return tracker_indexing_tree_file_is_indexable (priv->indexing_tree,
file,
......@@ -210,13 +209,12 @@ crawler_check_file_cb (TrackerCrawler *crawler,
}
static gboolean
crawler_check_directory_cb (TrackerCrawler *crawler,
GFile *directory,
gpointer user_data)
check_directory (TrackerFileNotifier *notifier,
GFile *directory)
{
TrackerFileNotifierPrivate *priv;
priv = tracker_file_notifier_get_instance_private (user_data);
priv = tracker_file_notifier_get_instance_private (notifier);
g_assert (priv->current_index_root != NULL);
/* If it's a config root itself, other than the one
......@@ -234,15 +232,14 @@ crawler_check_directory_cb (TrackerCrawler *crawler,
}
static gboolean
crawler_check_directory_contents_cb (TrackerCrawler *crawler,
GFile *parent,
GList *children,
gpointer user_data)
check_directory_contents (TrackerFileNotifier *notifier,
GFile *parent,
const GList *children)
{
TrackerFileNotifierPrivate *priv;
gboolean process = TRUE;
priv = tracker_file_notifier_get_instance_private (user_data);
priv = tracker_file_notifier_get_instance_private (notifier);
/* Do not let content filter apply to configured roots themselves. This
* is a measure to trim undesired portions of the filesystem, and if
......@@ -250,7 +247,7 @@ crawler_check_directory_contents_cb (TrackerCrawler *crawler,
*/
if (!tracker_indexing_tree_file_is_root (priv->indexing_tree, parent)) {
process = tracker_indexing_tree_parent_is_indexable (priv->indexing_tree,
parent, children);
parent, (GList*) children);
}
if (!process) {
......@@ -1381,6 +1378,33 @@ check_disable_monitor (TrackerFileNotifier *notifier)
g_clear_object (&cursor);
}
static gboolean
crawler_check_func (TrackerCrawler *crawler,
TrackerCrawlerCheckFlags flags,
GFile *file,
const GList *children,
gpointer user_data)
{
TrackerFileNotifier *notifier = user_data;
if (flags & TRACKER_CRAWLER_CHECK_FILE) {
if (!check_file (notifier, file))
return FALSE;
}
if (flags & TRACKER_CRAWLER_CHECK_DIRECTORY) {
if (!check_directory (notifier, file))
return FALSE;
}
if (flags & TRACKER_CRAWLER_CHECK_CONTENT) {
if (!check_directory_contents (notifier, file, children))
return FALSE;
}
return TRUE;
}
static void
tracker_file_notifier_constructed (GObject *object)
{
......@@ -1402,19 +1426,13 @@ tracker_file_notifier_constructed (GObject *object)
/* Set up crawler */
priv->crawler = tracker_crawler_new (priv->data_provider);
tracker_crawler_set_check_func (priv->crawler,
crawler_check_func,
object, NULL);
tracker_crawler_set_file_attributes (priv->crawler,
G_FILE_ATTRIBUTE_TIME_MODIFIED ","
G_FILE_ATTRIBUTE_STANDARD_TYPE);
g_signal_connect (priv->crawler, "check-file",
G_CALLBACK (crawler_check_file_cb),
object);
g_signal_connect (priv->crawler, "check-directory",
G_CALLBACK (crawler_check_directory_cb),
object);
g_signal_connect (priv->crawler, "check-directory-contents",
G_CALLBACK (crawler_check_directory_contents_cb),
object);
g_signal_connect (priv->crawler, "directory-crawled",
G_CALLBACK (crawler_directory_crawled_cb),
object);
......
......@@ -74,38 +74,20 @@ crawler_directory_crawled_cb (TrackerCrawler *crawler,
}
static gboolean
crawler_check_directory_cb (TrackerCrawler *crawler,
GFile *file,
gpointer user_data)
check_func (TrackerCrawler *crawler,
TrackerCrawlerCheckFlags flags,
GFile *file,
const GList *children,
gpointer user_data)
{
CrawlerTest *test = user_data;
test->n_check_directory++;
return TRUE;
}
static gboolean
crawler_check_file_cb (TrackerCrawler *crawler,
GFile *file,
gpointer user_data)
{
CrawlerTest *test = user_data;
test->n_check_file++;
return TRUE;
}
static gboolean
crawler_check_directory_contents_cb (TrackerCrawler *crawler,
GFile *file,
GList *contents,
gpointer user_data)
{
CrawlerTest *test = user_data;
test->n_check_directory_contents++;
if (flags & TRACKER_CRAWLER_CHECK_FILE)
test->n_check_file++;
if (flags & TRACKER_CRAWLER_CHECK_DIRECTORY)
test->n_check_directory++;
if (flags & TRACKER_CRAWLER_CHECK_CONTENT)
test->n_check_directory_contents++;
return TRUE;
}
......@@ -227,16 +209,11 @@ test_crawler_crawl_n_signals_non_recursive (void)
test.main_loop = g_main_loop_new (NULL, FALSE);
crawler = tracker_crawler_new (NULL);
tracker_crawler_set_check_func (crawler, check_func, &test, NULL);
g_signal_connect (crawler, "finished",
G_CALLBACK (crawler_finished_cb), &test);
g_signal_connect (crawler, "directory-crawled",
G_CALLBACK (crawler_directory_crawled_cb), &test);
g_signal_connect (crawler, "check-directory",
G_CALLBACK (crawler_check_directory_cb), &test);
g_signal_connect (crawler, "check-directory-contents",
G_CALLBACK (crawler_check_directory_contents_cb), &test);
g_signal_connect (crawler, "check-file",
G_CALLBACK (crawler_check_file_cb), &test);
file = g_file_new_for_path (TEST_DATA_DIR);
......
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