summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2017-11-24 01:02:53 +0100
committerCarlos Garnacho <carlosg@gnome.org>2018-07-20 18:27:32 +0200
commitdffa19e78aa185db3bc3068a43e0035f13a5c83e (patch)
tree00f4706c07fef1d3e3fc8b5e0e7b7680abab27b5
parent7b25b9a25dff1227de91808d8e6e9eafcfaf0603 (diff)
downloadtracker-dffa19e78aa185db3bc3068a43e0035f13a5c83e.tar.gz
libtracker-data: Move TrackerClass event maintenance to tracker-store
This is solely used by tracker-store to keep the backlog of pending GraphUpdated events. This event tracking can move to tracker-store itself, implemented atop libtracker-data's insert/delete/commit/rollback callbacks.
-rw-r--r--src/libtracker-data/tracker-class.c279
-rw-r--r--src/libtracker-data/tracker-class.h29
-rw-r--r--src/tracker-store/tracker-backup.vala4
-rw-r--r--src/tracker-store/tracker-events.c345
-rw-r--r--src/tracker-store/tracker-events.h22
-rw-r--r--src/tracker-store/tracker-events.vapi13
-rw-r--r--src/tracker-store/tracker-main.vala2
-rw-r--r--src/tracker-store/tracker-resources.vala57
8 files changed, 339 insertions, 412 deletions
diff --git a/src/libtracker-data/tracker-class.c b/src/libtracker-data/tracker-class.c
index 6c9754e70..f216c8e94 100644
--- a/src/libtracker-data/tracker-class.c
+++ b/src/libtracker-data/tracker-class.c
@@ -49,27 +49,6 @@ struct _TrackerClassPrivate {
GArray *last_super_classes;
TrackerOntologies *ontologies;
-
- struct {
- struct {
- GArray *sub_pred_ids;
- GArray *obj_graph_ids;
- } pending;
- struct {
- GArray *sub_pred_ids;
- GArray *obj_graph_ids;
- } ready;
- } deletes;
- struct {
- struct {
- GArray *sub_pred_ids;
- GArray *obj_graph_ids;
- } pending;
- struct {
- GArray *sub_pred_ids;
- GArray *obj_graph_ids;
- } ready;
- } inserts;
};
static void class_finalize (GObject *object);
@@ -99,16 +78,6 @@ tracker_class_init (TrackerClass *service)
priv->last_domain_indexes = NULL;
priv->last_super_classes = NULL;
- priv->deletes.pending.sub_pred_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
- priv->deletes.pending.obj_graph_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
- priv->deletes.ready.sub_pred_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
- priv->deletes.ready.obj_graph_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
-
- priv->inserts.pending.sub_pred_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
- priv->inserts.pending.obj_graph_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
- priv->inserts.ready.sub_pred_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
- priv->inserts.ready.obj_graph_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
-
/* Make GET_PRIV working */
service->priv = priv;
}
@@ -126,16 +95,6 @@ class_finalize (GObject *object)
g_array_free (priv->super_classes, TRUE);
g_array_free (priv->domain_indexes, TRUE);
- g_array_free (priv->deletes.pending.sub_pred_ids, TRUE);
- g_array_free (priv->deletes.pending.obj_graph_ids, TRUE);
- g_array_free (priv->deletes.ready.sub_pred_ids, TRUE);
- g_array_free (priv->deletes.ready.obj_graph_ids, TRUE);
-
- g_array_free (priv->inserts.pending.sub_pred_ids, TRUE);
- g_array_free (priv->inserts.pending.obj_graph_ids, TRUE);
- g_array_free (priv->inserts.ready.sub_pred_ids, TRUE);
- g_array_free (priv->inserts.ready.obj_graph_ids, TRUE);
-
if (priv->last_domain_indexes) {
g_array_free (priv->last_domain_indexes, TRUE);
}
@@ -511,244 +470,6 @@ tracker_class_set_db_schema_changed (TrackerClass *service,
priv->db_schema_changed = value;
}
-gboolean
-tracker_class_has_insert_events (TrackerClass *class)
-{
- TrackerClassPrivate *priv;
-
- g_return_val_if_fail (TRACKER_IS_CLASS (class), FALSE);
-
- priv = GET_PRIV (class);
-
- return (priv->inserts.ready.sub_pred_ids->len > 0);
-}
-
-gboolean
-tracker_class_has_delete_events (TrackerClass *class)
-{
- TrackerClassPrivate *priv;
-
- g_return_val_if_fail (TRACKER_IS_CLASS (class), FALSE);
-
- priv = GET_PRIV (class);
-
- return (priv->deletes.ready.sub_pred_ids->len > 0);
-}
-
-void
-tracker_class_foreach_insert_event (TrackerClass *class,
- TrackerEventsForeach foreach,
- gpointer user_data)
-{
- guint i;
- TrackerClassPrivate *priv;
-
- g_return_if_fail (TRACKER_IS_CLASS (class));
- g_return_if_fail (foreach != NULL);
-
- priv = GET_PRIV (class);
-
- for (i = 0; i < priv->inserts.ready.sub_pred_ids->len; i++) {
- gint graph_id, subject_id, pred_id, object_id;
- gint64 sub_pred_id;
- gint64 obj_graph_id;
-
- sub_pred_id = g_array_index (priv->inserts.ready.sub_pred_ids, gint64, i);
- obj_graph_id = g_array_index (priv->inserts.ready.obj_graph_ids, gint64, i);
-
- pred_id = sub_pred_id & 0xffffffff;
- subject_id = sub_pred_id >> 32;
- graph_id = obj_graph_id & 0xffffffff;
- object_id = obj_graph_id >> 32;
-
- foreach (graph_id, subject_id, pred_id, object_id, user_data);
- }
-}
-
-void
-tracker_class_foreach_delete_event (TrackerClass *class,
- TrackerEventsForeach foreach,
- gpointer user_data)
-{
- guint i;
- TrackerClassPrivate *priv;
-
- g_return_if_fail (TRACKER_IS_CLASS (class));
- g_return_if_fail (foreach != NULL);
-
- priv = GET_PRIV (class);
-
- for (i = 0; i < priv->deletes.ready.sub_pred_ids->len; i++) {
- gint graph_id, subject_id, pred_id, object_id;
- gint64 sub_pred_id;
- gint64 obj_graph_id;
-
- sub_pred_id = g_array_index (priv->deletes.ready.sub_pred_ids, gint64, i);
- obj_graph_id = g_array_index (priv->deletes.ready.obj_graph_ids, gint64, i);
-
- pred_id = sub_pred_id & 0xffffffff;
- subject_id = sub_pred_id >> 32;
- graph_id = obj_graph_id & 0xffffffff;
- object_id = obj_graph_id >> 32;
-
- foreach (graph_id, subject_id, pred_id, object_id, user_data);
- }
-}
-
-void
-tracker_class_reset_ready_events (TrackerClass *class)
-{
- TrackerClassPrivate *priv;
-
- g_return_if_fail (TRACKER_IS_CLASS (class));
-
- priv = GET_PRIV (class);
-
- /* Reset */
- g_array_set_size (priv->deletes.ready.sub_pred_ids, 0);
- g_array_set_size (priv->deletes.ready.obj_graph_ids, 0);
-
- g_array_set_size (priv->inserts.ready.sub_pred_ids, 0);
- g_array_set_size (priv->inserts.ready.obj_graph_ids, 0);
-
-}
-
-void
-tracker_class_reset_pending_events (TrackerClass *class)
-{
- TrackerClassPrivate *priv;
-
- g_return_if_fail (TRACKER_IS_CLASS (class));
-
- priv = GET_PRIV (class);
-
- /* Reset */
- g_array_set_size (priv->deletes.pending.sub_pred_ids, 0);
- g_array_set_size (priv->deletes.pending.obj_graph_ids, 0);
-
- g_array_set_size (priv->inserts.pending.sub_pred_ids, 0);
- g_array_set_size (priv->inserts.pending.obj_graph_ids, 0);
-
-}
-
-void
-tracker_class_transact_events (TrackerClass *class)
-{
- TrackerClassPrivate *priv;
-
- g_return_if_fail (TRACKER_IS_CLASS (class));
- priv = GET_PRIV (class);
-
- /* Move */
- g_array_insert_vals (priv->deletes.ready.obj_graph_ids,
- priv->deletes.ready.obj_graph_ids->len,
- priv->deletes.pending.obj_graph_ids->data,
- priv->deletes.pending.obj_graph_ids->len);
-
- g_array_insert_vals (priv->deletes.ready.sub_pred_ids,
- priv->deletes.ready.sub_pred_ids->len,
- priv->deletes.pending.sub_pred_ids->data,
- priv->deletes.pending.sub_pred_ids->len);
-
- /* Reset */
- g_array_set_size (priv->deletes.pending.sub_pred_ids, 0);
- g_array_set_size (priv->deletes.pending.obj_graph_ids, 0);
-
-
- /* Move */
- g_array_insert_vals (priv->inserts.ready.obj_graph_ids,
- priv->inserts.ready.obj_graph_ids->len,
- priv->inserts.pending.obj_graph_ids->data,
- priv->inserts.pending.obj_graph_ids->len);
-
- g_array_insert_vals (priv->inserts.ready.sub_pred_ids,
- priv->inserts.ready.sub_pred_ids->len,
- priv->inserts.pending.sub_pred_ids->data,
- priv->inserts.pending.sub_pred_ids->len);
-
- /* Reset */
- g_array_set_size (priv->inserts.pending.sub_pred_ids, 0);
- g_array_set_size (priv->inserts.pending.obj_graph_ids, 0);
-
-}
-
-static void
-insert_vals_into_arrays (GArray *sub_pred_ids,
- GArray *obj_graph_ids,
- gint graph_id,
- gint subject_id,
- gint pred_id,
- gint object_id)
-{
- gint i, j, k;
- gint64 tmp;
- gint64 sub_pred_id;
- gint64 obj_graph_id;
-
- sub_pred_id = (gint64) subject_id;
- sub_pred_id = sub_pred_id << 32 | pred_id;
- obj_graph_id = (gint64) object_id;
- obj_graph_id = obj_graph_id << 32 | graph_id;
-
- i = 0;
- j = sub_pred_ids->len - 1;
-
- while (j - i > 0) {
- k = (i + j) / 2;
- tmp = g_array_index (sub_pred_ids, gint64, k);
- if (tmp == sub_pred_id) {
- i = k + 1;
- break;
- } else if (tmp > sub_pred_id)
- j = k;
- else
- i = k + 1;
- }
-
- g_array_insert_val (sub_pred_ids, i, sub_pred_id);
- g_array_insert_val (obj_graph_ids, i, obj_graph_id);
-}
-
-void
-tracker_class_add_insert_event (TrackerClass *class,
- gint graph_id,
- gint subject_id,
- gint pred_id,
- gint object_id)
-{
- TrackerClassPrivate *priv;
-
- g_return_if_fail (TRACKER_IS_CLASS (class));
- priv = GET_PRIV (class);
-
- insert_vals_into_arrays (priv->inserts.pending.sub_pred_ids,
- priv->inserts.pending.obj_graph_ids,
- graph_id,
- subject_id,
- pred_id,
- object_id);
-}
-
-void
-tracker_class_add_delete_event (TrackerClass *class,
- gint graph_id,
- gint subject_id,
- gint pred_id,
- gint object_id)
-{
- TrackerClassPrivate *priv;
-
- g_return_if_fail (TRACKER_IS_CLASS (class));
- priv = GET_PRIV (class);
-
- insert_vals_into_arrays (priv->deletes.pending.sub_pred_ids,
- priv->deletes.pending.obj_graph_ids,
- graph_id,
- subject_id,
- pred_id,
- object_id);
-}
-
void
tracker_class_set_ontologies (TrackerClass *class,
TrackerOntologies *ontologies)
diff --git a/src/libtracker-data/tracker-class.h b/src/libtracker-data/tracker-class.h
index c05634102..9ac46acd8 100644
--- a/src/libtracker-data/tracker-class.h
+++ b/src/libtracker-data/tracker-class.h
@@ -51,12 +51,6 @@ struct _TrackerClassClass {
GObjectClass parent_class;
};
-typedef void (*TrackerEventsForeach) (gint graph_id,
- gint subject_id,
- gint pred_id,
- gint object_id,
- gpointer user_data);
-
GType tracker_class_get_type (void) G_GNUC_CONST;
TrackerClass * tracker_class_new (gboolean use_gvdb);
const gchar * tracker_class_get_uri (TrackerClass *service);
@@ -96,29 +90,6 @@ void tracker_class_set_notify (TrackerClass *ser
void tracker_class_set_ontologies (TrackerClass *class,
TrackerOntologies *ontologies);
-/* For signals API */
-void tracker_class_foreach_delete_event (TrackerClass *class,
- TrackerEventsForeach foreach,
- gpointer user_data);
-void tracker_class_foreach_insert_event (TrackerClass *class,
- TrackerEventsForeach foreach,
- gpointer user_data);
-gboolean tracker_class_has_insert_events (TrackerClass *class);
-gboolean tracker_class_has_delete_events (TrackerClass *class);
-void tracker_class_reset_ready_events (TrackerClass *class);
-void tracker_class_reset_pending_events (TrackerClass *class);
-void tracker_class_transact_events (TrackerClass *class);
-void tracker_class_add_delete_event (TrackerClass *class,
- gint graph_id,
- gint subject_id,
- gint pred_id,
- gint object_id);
-void tracker_class_add_insert_event (TrackerClass *class,
- gint graph_id,
- gint subject_id,
- gint pred_id,
- gint object_id);
-
G_END_DECLS
#endif /* __LIBTRACKER_DATA_CLASS_H__ */
diff --git a/src/tracker-store/tracker-backup.vala b/src/tracker-store/tracker-backup.vala
index 5db075274..d589b227a 100644
--- a/src/tracker-store/tracker-backup.vala
+++ b/src/tracker-store/tracker-backup.vala
@@ -57,7 +57,7 @@ public class Tracker.Backup : Object {
throw e;
} finally {
if (resources != null) {
- Tracker.Events.init (Tracker.Main.get_data_manager ());
+ Tracker.Events.init ();
resources.enable_signals ();
}
@@ -95,7 +95,7 @@ public class Tracker.Backup : Object {
throw e;
} finally {
if (resources != null) {
- Tracker.Events.init (Tracker.Main.get_data_manager ());
+ Tracker.Events.init ();
resources.enable_signals ();
}
diff --git a/src/tracker-store/tracker-events.c b/src/tracker-store/tracker-events.c
index 870084709..05782b2c5 100644
--- a/src/tracker-store/tracker-events.c
+++ b/src/tracker-store/tracker-events.c
@@ -26,13 +26,198 @@
#include "tracker-events.h"
+typedef struct _TrackerEventBatch TrackerEventBatch;
+
+struct _TrackerEventBatch
+{
+ struct {
+ GArray *sub_pred_ids;
+ GArray *obj_graph_ids;
+ } deletes;
+ struct {
+ GArray *sub_pred_ids;
+ GArray *obj_graph_ids;
+ } inserts;
+};
+
typedef struct {
guint total;
- GPtrArray *notify_classes;
+ GHashTable *pending;
+ GHashTable *ready;
} EventsPrivate;
static EventsPrivate *private;
+static TrackerEventBatch *
+tracker_event_batch_new (void)
+{
+ TrackerEventBatch *events;
+
+ events = g_new0 (TrackerEventBatch, 1);
+ events->deletes.sub_pred_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
+ events->deletes.obj_graph_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
+ events->inserts.sub_pred_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
+ events->inserts.obj_graph_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
+
+ return events;
+}
+
+static void
+tracker_event_batch_free (TrackerEventBatch *events)
+{
+ g_array_unref (events->deletes.sub_pred_ids);
+ g_array_unref (events->deletes.obj_graph_ids);
+ g_array_unref (events->inserts.sub_pred_ids);
+ g_array_unref (events->inserts.obj_graph_ids);
+ g_free (events);
+}
+
+static void
+insert_vals_into_arrays (GArray *sub_pred_ids,
+ GArray *obj_graph_ids,
+ gint graph_id,
+ gint subject_id,
+ gint pred_id,
+ gint object_id)
+{
+ gint i, j, k;
+ gint64 tmp;
+ gint64 sub_pred_id;
+ gint64 obj_graph_id;
+
+ sub_pred_id = (gint64) subject_id;
+ sub_pred_id = sub_pred_id << 32 | pred_id;
+ obj_graph_id = (gint64) object_id;
+ obj_graph_id = obj_graph_id << 32 | graph_id;
+
+ i = 0;
+ j = sub_pred_ids->len - 1;
+
+ while (j - i > 0) {
+ k = (i + j) / 2;
+ tmp = g_array_index (sub_pred_ids, gint64, k);
+ if (tmp == sub_pred_id) {
+ i = k + 1;
+ break;
+ } else if (tmp > sub_pred_id)
+ j = k;
+ else
+ i = k + 1;
+ }
+
+ g_array_insert_val (sub_pred_ids, i, sub_pred_id);
+ g_array_insert_val (obj_graph_ids, i, obj_graph_id);
+}
+
+static void
+tracker_event_batch_add_insert_event (TrackerEventBatch *events,
+ gint graph_id,
+ gint subject_id,
+ gint pred_id,
+ gint object_id)
+{
+ insert_vals_into_arrays (events->inserts.sub_pred_ids,
+ events->inserts.obj_graph_ids,
+ graph_id,
+ subject_id,
+ pred_id,
+ object_id);
+}
+
+static void
+tracker_event_batch_add_delete_event (TrackerEventBatch *events,
+ gint graph_id,
+ gint subject_id,
+ gint pred_id,
+ gint object_id)
+{
+ insert_vals_into_arrays (events->deletes.sub_pred_ids,
+ events->deletes.obj_graph_ids,
+ graph_id,
+ subject_id,
+ pred_id,
+ object_id);
+}
+
+static void
+foreach_event_in_arrays (GArray *sub_pred_ids,
+ GArray *obj_graph_ids,
+ TrackerEventsForeach foreach,
+ gpointer user_data)
+{
+ guint i;
+
+ g_assert (sub_pred_ids->len == obj_graph_ids->len);
+
+ for (i = 0; i < sub_pred_ids->len; i++) {
+ gint graph_id, subject_id, pred_id, object_id;
+ gint64 sub_pred_id;
+ gint64 obj_graph_id;
+
+ sub_pred_id = g_array_index (sub_pred_ids, gint64, i);
+ obj_graph_id = g_array_index (obj_graph_ids, gint64, i);
+
+ pred_id = sub_pred_id & 0xffffffff;
+ subject_id = sub_pred_id >> 32;
+ graph_id = obj_graph_id & 0xffffffff;
+ object_id = obj_graph_id >> 32;
+
+ foreach (graph_id, subject_id, pred_id, object_id, user_data);
+ }
+}
+
+void
+tracker_event_batch_foreach_insert_event (TrackerEventBatch *events,
+ TrackerEventsForeach foreach,
+ gpointer user_data)
+{
+ g_return_if_fail (events != NULL);
+ g_return_if_fail (foreach != NULL);
+
+ foreach_event_in_arrays (events->inserts.sub_pred_ids,
+ events->inserts.obj_graph_ids,
+ foreach, user_data);
+}
+
+void
+tracker_event_batch_foreach_delete_event (TrackerEventBatch *events,
+ TrackerEventsForeach foreach,
+ gpointer user_data)
+{
+ g_return_if_fail (events != NULL);
+ g_return_if_fail (foreach != NULL);
+
+ foreach_event_in_arrays (events->deletes.sub_pred_ids,
+ events->deletes.obj_graph_ids,
+ foreach, user_data);
+}
+
+static GHashTable *
+tracker_event_batch_hashtable_new (void)
+{
+ return g_hash_table_new_full (NULL, NULL,
+ (GDestroyNotify) g_object_unref,
+ (GDestroyNotify) tracker_event_batch_free);
+}
+
+void
+tracker_event_batch_merge (TrackerEventBatch *dest,
+ TrackerEventBatch *to_copy)
+{
+ g_array_append_vals (dest->deletes.sub_pred_ids,
+ to_copy->deletes.sub_pred_ids->data,
+ to_copy->deletes.sub_pred_ids->len);
+ g_array_append_vals (dest->deletes.obj_graph_ids,
+ to_copy->deletes.obj_graph_ids->data,
+ to_copy->deletes.obj_graph_ids->len);
+ g_array_append_vals (dest->inserts.sub_pred_ids,
+ to_copy->inserts.sub_pred_ids->data,
+ to_copy->inserts.sub_pred_ids->len);
+ g_array_append_vals (dest->inserts.obj_graph_ids,
+ to_copy->inserts.obj_graph_ids->data,
+ to_copy->inserts.obj_graph_ids->len);
+}
+
guint
tracker_events_get_total (gboolean and_reset)
{
@@ -49,6 +234,28 @@ tracker_events_get_total (gboolean and_reset)
return total;
}
+static inline TrackerEventBatch *
+ensure_event_batch (TrackerClass *rdf_type)
+{
+ TrackerEventBatch *events;
+
+ g_assert (private != NULL);
+
+ if (!private->pending)
+ private->pending = tracker_event_batch_hashtable_new ();
+
+ events = g_hash_table_lookup (private->pending, rdf_type);
+
+ if (!events) {
+ events = tracker_event_batch_new ();
+ g_hash_table_insert (private->pending,
+ g_object_ref (rdf_type),
+ events);
+ }
+
+ return events;
+}
+
void
tracker_events_add_insert (gint graph_id,
gint subject_id,
@@ -58,20 +265,23 @@ tracker_events_add_insert (gint graph_id,
const gchar *object,
GPtrArray *rdf_types)
{
+ TrackerEventBatch *events;
guint i;
g_return_if_fail (rdf_types != NULL);
g_return_if_fail (private != NULL);
for (i = 0; i < rdf_types->len; i++) {
- if (tracker_class_get_notify (rdf_types->pdata[i])) {
- tracker_class_add_insert_event (rdf_types->pdata[i],
- graph_id,
- subject_id,
- pred_id,
- object_id);
- private->total++;
- }
+ if (!tracker_class_get_notify (rdf_types->pdata[i]))
+ continue;
+
+ events = ensure_event_batch (rdf_types->pdata[i]);
+ tracker_event_batch_add_insert_event (events,
+ graph_id,
+ subject_id,
+ pred_id,
+ object_id);
+ private->total++;
}
}
@@ -84,90 +294,82 @@ tracker_events_add_delete (gint graph_id,
const gchar *object,
GPtrArray *rdf_types)
{
+ TrackerEventBatch *events;
guint i;
g_return_if_fail (rdf_types != NULL);
g_return_if_fail (private != NULL);
for (i = 0; i < rdf_types->len; i++) {
- if (tracker_class_get_notify (rdf_types->pdata[i])) {
- tracker_class_add_delete_event (rdf_types->pdata[i],
- graph_id,
- subject_id,
- pred_id,
- object_id);
- private->total++;
- }
+ if (!tracker_class_get_notify (rdf_types->pdata[i]))
+ continue;
+
+ events = ensure_event_batch (rdf_types->pdata[i]);
+ tracker_event_batch_add_delete_event (events,
+ graph_id,
+ subject_id,
+ pred_id,
+ object_id);
+ private->total++;
}
}
void
-tracker_events_reset_pending (void)
+tracker_events_transact (void)
{
- guint i;
+ TrackerEventBatch *prev_events, *events;
+ TrackerClass *rdf_type;
+ GHashTableIter iter;
g_return_if_fail (private != NULL);
- for (i = 0; i < private->notify_classes->len; i++) {
- TrackerClass *class = g_ptr_array_index (private->notify_classes, i);
+ if (!private->pending || g_hash_table_size (private->pending) == 0)
+ return;
- tracker_class_reset_pending_events (class);
+ if (!private->ready) {
+ private->ready = tracker_event_batch_hashtable_new ();
}
-}
-static void
-free_private (EventsPrivate *private)
-{
- guint i;
-
- for (i = 0; i < private->notify_classes->len; i++) {
- TrackerClass *class = g_ptr_array_index (private->notify_classes, i);
-
- tracker_class_reset_pending_events (class);
-
- /* Perhaps hurry an emit of the ready events here? We're shutting down,
- * so I guess we're not required to do that here ... ? */
- tracker_class_reset_ready_events (class);
+ g_hash_table_iter_init (&iter, private->pending);
+
+ while (g_hash_table_iter_next (&iter,
+ (gpointer *) &rdf_type,
+ (gpointer *) &events)) {
+ prev_events = g_hash_table_lookup (private->ready,
+ rdf_type);
+ if (prev_events) {
+ tracker_event_batch_merge (prev_events, events);
+ g_hash_table_iter_remove (&iter);
+ } else {
+ g_hash_table_iter_steal (&iter);
+ g_hash_table_insert (private->ready,
+ g_object_ref (rdf_type),
+ events);
+ /* Drop the reference stolen from the pending HT */
+ g_object_unref (rdf_type);
+ }
}
-
- g_ptr_array_unref (private->notify_classes);
-
- g_free (private);
}
-TrackerClass **
-tracker_events_get_classes (guint *length)
+void
+tracker_events_reset_pending (void)
{
- g_return_val_if_fail (private != NULL, NULL);
+ g_return_if_fail (private != NULL);
- *length = private->notify_classes->len;
+ g_clear_pointer (&private->pending, g_hash_table_unref);
+}
- return (TrackerClass **) (private->notify_classes->pdata);
+static void
+free_private (EventsPrivate *private)
+{
+ tracker_events_reset_pending ();
+ g_free (private);
}
void
-tracker_events_init (TrackerDataManager *data_manager)
+tracker_events_init (void)
{
- TrackerOntologies *ontologies;
- TrackerClass **classes;
- guint length = 0, i;
-
private = g_new0 (EventsPrivate, 1);
-
- ontologies = tracker_data_manager_get_ontologies (data_manager);
- classes = tracker_ontologies_get_classes (ontologies, &length);
-
- private->notify_classes = g_ptr_array_sized_new (length);
- g_ptr_array_set_free_func (private->notify_classes, (GDestroyNotify) g_object_unref);
-
- for (i = 0; i < length; i++) {
- TrackerClass *class = classes[i];
-
- if (tracker_class_get_notify (class)) {
- g_ptr_array_add (private->notify_classes, g_object_ref (class));
- }
- }
-
}
void
@@ -180,3 +382,16 @@ tracker_events_shutdown (void)
g_warning ("tracker_events already shutdown");
}
}
+
+GHashTable *
+tracker_events_get_pending (void)
+{
+ GHashTable *pending;
+
+ g_return_val_if_fail (private != NULL, NULL);
+
+ pending = private->ready;
+ private->ready = NULL;
+
+ return pending;
+}
diff --git a/src/tracker-store/tracker-events.h b/src/tracker-store/tracker-events.h
index 1e962b90c..4d6ff4e1e 100644
--- a/src/tracker-store/tracker-events.h
+++ b/src/tracker-store/tracker-events.h
@@ -28,9 +28,15 @@
G_BEGIN_DECLS
-typedef GStrv (*TrackerNotifyClassGetter) (void);
+typedef struct _TrackerEventBatch TrackerEventBatch;
-void tracker_events_init (TrackerDataManager *data_manager);
+typedef void (*TrackerEventsForeach) (gint graph_id,
+ gint subject_id,
+ gint pred_id,
+ gint object_id,
+ gpointer user_data);
+
+void tracker_events_init (void);
void tracker_events_shutdown (void);
void tracker_events_add_insert (gint graph_id,
gint subject_id,
@@ -48,7 +54,17 @@ void tracker_events_add_delete (gint graph_id,
GPtrArray *rdf_types);
guint tracker_events_get_total (gboolean and_reset);
void tracker_events_reset_pending (void);
-TrackerClass** tracker_events_get_classes (guint *length);
+
+void tracker_events_transact (void);
+
+GHashTable * tracker_events_get_pending (void);
+
+void tracker_event_batch_foreach_insert_event (TrackerEventBatch *events,
+ TrackerEventsForeach foreach,
+ gpointer user_data);
+void tracker_event_batch_foreach_delete_event (TrackerEventBatch *events,
+ TrackerEventsForeach foreach,
+ gpointer user_data);
G_END_DECLS
diff --git a/src/tracker-store/tracker-events.vapi b/src/tracker-store/tracker-events.vapi
index fdd7b8af4..da47267b9 100644
--- a/src/tracker-store/tracker-events.vapi
+++ b/src/tracker-store/tracker-events.vapi
@@ -20,12 +20,21 @@
namespace Tracker {
[CCode (cheader_filename = "tracker-store/tracker-events.h")]
namespace Events {
- public void init (Tracker.Data.Manager data_manager);
+ public void init ();
public void shutdown ();
public void add_insert (int graph_id, int subject_id, string subject, int pred_id, int object_id, string object, GLib.PtrArray rdf_types);
public void add_delete (int graph_id, int subject_id, string subject, int pred_id, int object_id, string object, GLib.PtrArray rdf_types);
public uint get_total (bool and_reset);
public void reset_pending ();
- public unowned Class[] get_classes ();
+
+ public void transact ();
+ public GLib.HashTable<Tracker.Class, Batch> get_pending ();
+
+ [CCode (lower_case_cprefix="tracker_event_batch_", cname = "TrackerEventBatch")]
+ public class Batch {
+ public delegate void EventsForeach (int graph_id, int subject_id, int pred_id, int object_id);
+ public void foreach_delete_event (EventsForeach func);
+ public void foreach_insert_event (EventsForeach func);
+ }
}
}
diff --git a/src/tracker-store/tracker-main.vala b/src/tracker-store/tracker-main.vala
index 187ff6908..d14b12c8e 100644
--- a/src/tracker-store/tracker-main.vala
+++ b/src/tracker-store/tracker-main.vala
@@ -319,7 +319,7 @@ License which can be viewed at:
if (!shutdown) {
Tracker.DBus.register_prepare_class_signal ();
- Tracker.Events.init (data_manager);
+ Tracker.Events.init ();
Tracker.Writeback.init (data_manager, get_writeback_predicates);
Tracker.Store.resume ();
diff --git a/src/tracker-store/tracker-resources.vala b/src/tracker-store/tracker-resources.vala
index fe805e196..9b6069b6b 100644
--- a/src/tracker-store/tracker-resources.vala
+++ b/src/tracker-store/tracker-resources.vala
@@ -207,32 +207,33 @@ public class Tracker.Resources : Object {
/* no longer needed, just return */
}
- bool emit_graph_updated (Class cl) {
- if (cl.has_insert_events () || cl.has_delete_events ()) {
- var builder = new VariantBuilder ((VariantType) "a(iiii)");
- cl.foreach_delete_event ((graph_id, subject_id, pred_id, object_id) => {
- builder.add ("(iiii)", graph_id, subject_id, pred_id, object_id);
- });
- var deletes = builder.end ();
-
- builder = new VariantBuilder ((VariantType) "a(iiii)");
- cl.foreach_insert_event ((graph_id, subject_id, pred_id, object_id) => {
- builder.add ("(iiii)", graph_id, subject_id, pred_id, object_id);
- });
- var inserts = builder.end ();
-
- graph_updated (cl.uri, deletes, inserts);
-
- cl.reset_ready_events ();
-
- return true;
- }
- return false;
+ void emit_graph_updated (Class cl, Events.Batch events) {
+ var builder = new VariantBuilder ((VariantType) "a(iiii)");
+ events.foreach_delete_event ((graph_id, subject_id, pred_id, object_id) => {
+ builder.add ("(iiii)", graph_id, subject_id, pred_id, object_id);
+ });
+ var deletes = builder.end ();
+
+ builder = new VariantBuilder ((VariantType) "a(iiii)");
+ events.foreach_insert_event ((graph_id, subject_id, pred_id, object_id) => {
+ builder.add ("(iiii)", graph_id, subject_id, pred_id, object_id);
+ });
+ var inserts = builder.end ();
+
+ graph_updated (cl.uri, deletes, inserts);
}
bool on_emit_signals () {
- foreach (var cl in Tracker.Events.get_classes ()) {
- emit_graph_updated (cl);
+ var events = Tracker.Events.get_pending ();
+
+ if (events != null) {
+ var iter = HashTableIter<Tracker.Class, Tracker.Events.Batch> (events);
+ unowned Events.Batch class_events;
+ unowned Class cl;
+
+ while (iter.next (out cl, out class_events)) {
+ emit_graph_updated (cl, class_events);
+ }
}
/* Reset counter */
@@ -272,18 +273,12 @@ public class Tracker.Resources : Object {
}
void on_statements_committed () {
- /* Class signal feature */
-
- foreach (var cl in Tracker.Events.get_classes ()) {
- cl.transact_events ();
- }
+ Tracker.Events.transact ();
+ Tracker.Writeback.transact ();
if (signal_timeout == 0) {
signal_timeout = Timeout.add (config.graphupdated_delay, on_emit_signals);
}
-
- /* Writeback feature */
- Tracker.Writeback.transact ();
}
void on_statements_rolled_back () {