[tracker/wip/miner-priority-queues: 11/19] libtracker-miner: Add TrackerTaskPool



commit 9867a7a1ad1da222a05688c41de06aecabacbce3
Author: Carlos Garnacho <carlos lanedo com>
Date:   Mon Jul 4 12:10:26 2011 +0200

    libtracker-miner: Add TrackerTaskPool
    
    This is a simple task pool implementation, where an external
    entity has to do task pushing/popping.
    
    Eventually, the TrackerProcessingPool object will be split
    into two of these objects, one for the wait queue, and
    another for the ready/processing queues.
    
    the ready/processing queues in TrackerProcessingPool
    will eventually

 src/libtracker-miner/Makefile.am         |    2 +
 src/libtracker-miner/tracker-task-pool.c |  343 ++++++++++++++++++++++++++++++
 src/libtracker-miner/tracker-task-pool.h |   92 ++++++++
 3 files changed, 437 insertions(+), 0 deletions(-)
---
diff --git a/src/libtracker-miner/Makefile.am b/src/libtracker-miner/Makefile.am
index b83a53c..6a23ce0 100644
--- a/src/libtracker-miner/Makefile.am
+++ b/src/libtracker-miner/Makefile.am
@@ -36,6 +36,8 @@ crawler_sources = 				       \
 private_sources = 				       \
 	tracker-priority-queue.h                       \
 	tracker-priority-queue.c                       \
+	tracker-task-pool.h                            \
+	tracker-task-pool.c                            \
 	tracker-miner-fs-processing-pool.h             \
 	tracker-miner-fs-processing-pool.c             \
 	tracker-storage.c                              \
diff --git a/src/libtracker-miner/tracker-task-pool.c b/src/libtracker-miner/tracker-task-pool.c
new file mode 100644
index 0000000..02a8b88
--- /dev/null
+++ b/src/libtracker-miner/tracker-task-pool.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2011, Carlos Garnacho <carlos lanedo 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.
+ */
+
+#include "tracker-task-pool.h"
+
+enum {
+	PROP_0,
+	PROP_LIMIT,
+	PROP_LIMIT_REACHED
+};
+
+G_DEFINE_TYPE (TrackerTaskPool, tracker_task_pool, G_TYPE_OBJECT)
+
+typedef struct _TrackerTaskPoolPrivate TrackerTaskPoolPrivate;
+
+struct _TrackerTaskPoolPrivate
+{
+	GHashTable *tasks;
+	guint limit;
+};
+
+struct _TrackerTask
+{
+	GFile *file;
+	gpointer data;
+	GDestroyNotify destroy_notify;
+	gint ref_count;
+};
+
+static void
+tracker_task_pool_finalize (GObject *object)
+{
+	TrackerTaskPoolPrivate *priv;
+
+	priv = TRACKER_TASK_POOL (object)->priv;
+	g_hash_table_destroy (priv->tasks);
+
+	G_OBJECT_CLASS (tracker_task_pool_parent_class)->finalize (object);
+}
+
+static void
+tracker_task_pool_set_property (GObject      *object,
+                                guint         param_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+	TrackerTaskPool *pool = TRACKER_TASK_POOL (object);
+
+
+	switch (param_id) {
+	case PROP_LIMIT:
+		tracker_task_pool_set_limit (pool,
+		                             g_value_get_uint (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+	}
+}
+
+static void
+tracker_task_pool_get_property (GObject    *object,
+                                guint       param_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+	TrackerTaskPool *pool = TRACKER_TASK_POOL (object);
+
+	switch (param_id) {
+	case PROP_LIMIT:
+		g_value_set_uint (value,
+		                  tracker_task_pool_get_limit (pool));
+		break;
+	case PROP_LIMIT_REACHED:
+		g_value_set_boolean (value,
+		                     tracker_task_pool_limit_reached (pool));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+	}
+}
+
+static void
+tracker_task_pool_class_init (TrackerTaskPoolClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = tracker_task_pool_finalize;
+	object_class->set_property = tracker_task_pool_set_property;
+	object_class->get_property = tracker_task_pool_get_property;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_LIMIT,
+	                                 g_param_spec_uint ("limit",
+	                                                    "Limit",
+	                                                    "Task limit",
+	                                                    1, G_MAXUINT, 1,
+	                                                    G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 PROP_LIMIT_REACHED,
+	                                 g_param_spec_boolean ("limit-reached",
+	                                                       "Limit reached",
+	                                                       "Task limit reached",
+	                                                       FALSE,
+	                                                       G_PARAM_READABLE));
+
+	g_type_class_add_private (klass, sizeof (TrackerTaskPoolPrivate));
+}
+
+static gboolean
+file_equal (GFile *file1,
+            GFile *file2)
+{
+	if (file1 == file2) {
+		return TRUE;
+	} else {
+		return g_file_equal (file1, file2);
+	}
+}
+
+static void
+tracker_task_pool_init (TrackerTaskPool *pool)
+{
+	TrackerTaskPoolPrivate *priv;
+
+	priv = pool->priv = G_TYPE_INSTANCE_GET_PRIVATE (pool,
+	                                                 TRACKER_TYPE_TASK_POOL,
+	                                                 TrackerTaskPoolPrivate);
+	priv->tasks = g_hash_table_new_full (g_file_hash,
+	                                     (GEqualFunc) file_equal, NULL,
+	                                     (GDestroyNotify) tracker_task_unref);
+	priv->limit = 0;
+}
+
+TrackerTaskPool *
+tracker_task_pool_new (guint limit)
+{
+	return g_object_new (TRACKER_TYPE_TASK_POOL,
+	                     "limit", limit,
+	                     NULL);
+}
+
+void
+tracker_task_pool_set_limit (TrackerTaskPool *pool,
+                             guint            limit)
+{
+	TrackerTaskPoolPrivate *priv;
+	gboolean old_limit_reached;
+
+	g_return_if_fail (TRACKER_IS_TASK_POOL (pool));
+
+	old_limit_reached = tracker_task_pool_limit_reached (pool);
+
+	priv = pool->priv;
+	priv->limit = limit;
+
+	if (old_limit_reached !=
+	    tracker_task_pool_limit_reached (pool)) {
+		g_object_notify (G_OBJECT (pool), "limit-reached");
+	}
+}
+
+guint
+tracker_task_pool_get_limit (TrackerTaskPool *pool)
+{
+	TrackerTaskPoolPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_TASK_POOL (pool), 0);
+
+	priv = pool->priv;
+	return priv->limit;
+}
+
+guint
+tracker_task_pool_get_size (TrackerTaskPool *pool)
+{
+	TrackerTaskPoolPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_TASK_POOL (pool), 0);
+
+	priv = pool->priv;
+	return g_hash_table_size (priv->tasks);
+}
+
+gboolean
+tracker_task_pool_limit_reached (TrackerTaskPool *pool)
+{
+	TrackerTaskPoolPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_TASK_POOL (pool), FALSE);
+
+	priv = pool->priv;
+	return (g_hash_table_size (priv->tasks) >= priv->limit);
+}
+
+void
+tracker_task_pool_add (TrackerTaskPool *pool,
+                       TrackerTask     *task)
+{
+	TrackerTaskPoolPrivate *priv;
+
+	g_return_if_fail (TRACKER_IS_TASK_POOL (pool));
+
+	priv = pool->priv;
+
+	g_hash_table_insert (priv->tasks,
+	                     tracker_task_get_file (task),
+	                     tracker_task_ref (task));
+
+	if (g_hash_table_size (priv->tasks) == priv->limit) {
+		g_object_notify (G_OBJECT (pool), "limit-reached");
+	}
+}
+
+gboolean
+tracker_task_pool_remove (TrackerTaskPool *pool,
+                          TrackerTask     *task)
+{
+	TrackerTaskPoolPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_TASK_POOL (pool), FALSE);
+
+	priv = pool->priv;
+
+	if (g_hash_table_remove (priv->tasks,
+	                         tracker_task_get_file (task))) {
+		if (g_hash_table_size (priv->tasks) == priv->limit - 1) {
+			/* We've gone below the threshold again */
+			g_object_notify (G_OBJECT (pool), "limit-reached");
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+void
+tracker_task_pool_foreach (TrackerTaskPool *pool,
+                           GFunc            func,
+                           gpointer         user_data)
+{
+	TrackerTaskPoolPrivate *priv;
+	GHashTableIter iter;
+	TrackerTask *task;
+
+	g_return_if_fail (TRACKER_IS_TASK_POOL (pool));
+	g_return_if_fail (func != NULL);
+
+	priv = pool->priv;
+	g_hash_table_iter_init (&iter, priv->tasks);
+
+	while (g_hash_table_iter_next (&iter, (gpointer *) &task, NULL)) {
+		(func) (task, user_data);
+	}
+}
+
+TrackerTask *
+tracker_task_pool_find (TrackerTaskPool *pool,
+                        GFile           *file)
+{
+	TrackerTaskPoolPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_TASK_POOL (pool), NULL);
+	g_return_val_if_fail (G_IS_FILE (file), NULL);
+
+	priv = pool->priv;
+	return g_hash_table_lookup (priv->tasks, file);
+}
+
+/* Task */
+TrackerTask *
+tracker_task_new (GFile          *file,
+                  gpointer        data,
+                  GDestroyNotify  destroy_notify)
+{
+	TrackerTask *task;
+
+	task = g_slice_new0 (TrackerTask);
+	task->file = g_object_ref (file);
+	task->destroy_notify = destroy_notify;
+	task->data = data;
+	task->ref_count = 1;
+
+	return task;
+}
+
+TrackerTask *
+tracker_task_ref (TrackerTask *task)
+{
+	g_return_val_if_fail (task != NULL, NULL);
+
+	g_atomic_int_inc (&task->ref_count);
+
+	return task;
+}
+void
+tracker_task_unref (TrackerTask *task)
+{
+	g_return_if_fail (task != NULL);
+
+	if (g_atomic_int_dec_and_test (&task->ref_count)) {
+		g_object_unref (task->file);
+
+		if (task->data &&
+		    task->destroy_notify) {
+			(task->destroy_notify) (task->data);
+		}
+
+		g_slice_free (TrackerTask, task);
+	}
+}
+
+GFile *
+tracker_task_get_file (TrackerTask *task)
+{
+	g_return_val_if_fail (task != NULL, NULL);
+
+	return task->file;
+}
+
+gpointer
+tracker_task_get_data (TrackerTask *task)
+{
+	g_return_val_if_fail (task != NULL, NULL);
+
+	return task->data;
+}
diff --git a/src/libtracker-miner/tracker-task-pool.h b/src/libtracker-miner/tracker-task-pool.h
new file mode 100644
index 0000000..fff5537
--- /dev/null
+++ b/src/libtracker-miner/tracker-task-pool.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011, Carlos Garnacho <carlos lanedo 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.
+ */
+
+#ifndef __TRACKER_TASK_POOL_H__
+#define __TRACKER_TASK_POOL_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+/* Task pool */
+#define TRACKER_TYPE_TASK_POOL         (tracker_task_pool_get_type())
+#define TRACKER_TASK_POOL(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_TASK_POOL, TrackerTaskPool))
+#define TRACKER_TASK_POOL_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c),    TRACKER_TYPE_TASK_POOL, TrackerTaskPoolClass))
+#define TRACKER_IS_TASK_POOL(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_TASK_POOL))
+#define TRACKER_IS_TASK_POOL_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c),    TRACKER_TYPE_TASK_POOL))
+#define TRACKER_TASK_POOL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),  TRACKER_TYPE_TASK_POOL, TrackerTaskPoolClass))
+
+typedef struct _TrackerTaskPool TrackerTaskPool;
+typedef struct _TrackerTaskPoolClass TrackerTaskPoolClass;
+typedef struct _TrackerTask TrackerTask;
+
+struct _TrackerTaskPool
+{
+	GObject parent_instance;
+	gpointer priv;
+};
+
+struct _TrackerTaskPoolClass
+{
+	GObjectClass parent_class;
+};
+
+GType    tracker_task_pool_get_type      (void) G_GNUC_CONST;
+
+TrackerTaskPool *tracker_task_pool_new   (guint limit);
+
+void     tracker_task_pool_set_limit     (TrackerTaskPool *pool,
+                                          guint            limit);
+guint    tracker_task_pool_get_limit     (TrackerTaskPool *pool);
+guint    tracker_task_pool_get_size      (TrackerTaskPool *pool);
+
+gboolean tracker_task_pool_limit_reached (TrackerTaskPool *pool);
+
+void     tracker_task_pool_add           (TrackerTaskPool *pool,
+                                          TrackerTask     *task);
+
+gboolean tracker_task_pool_remove        (TrackerTaskPool *pool,
+                                          TrackerTask     *task);
+
+void     tracker_task_pool_foreach       (TrackerTaskPool *pool,
+                                          GFunc            func,
+                                          gpointer         user_data);
+
+TrackerTask * tracker_task_pool_find     (TrackerTaskPool *pool,
+                                          GFile           *file);
+
+/* Task */
+TrackerTask * tracker_task_new         (GFile          *file,
+                                        gpointer        data,
+                                        GDestroyNotify  destroy_notify);
+
+GFile *       tracker_task_get_file    (TrackerTask    *task);
+
+TrackerTask * tracker_task_ref         (TrackerTask    *task);
+void          tracker_task_unref       (TrackerTask    *task);
+
+gpointer      tracker_task_get_data    (TrackerTask    *task);
+
+
+
+G_END_DECLS
+
+#endif /* __TRACKER_TASK_POOL_H__ */



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