diff options
author | Philip Van Hoof <philip@codeminded.be> | 2010-08-17 15:32:28 +0200 |
---|---|---|
committer | Philip Van Hoof <philip@codeminded.be> | 2010-09-01 17:06:27 +0200 |
commit | 9cd24b43dff223b81ea4286203834d5e4e2872e8 (patch) | |
tree | 3f64cfcff622ff9793627ad159a9bdc4a6c9c162 /src/tracker-store/tracker-events.c | |
parent | 2c88a726c76cbcf91c8441896beda00a22fb23b3 (diff) | |
download | tracker-9cd24b43dff223b81ea4286203834d5e4e2872e8.tar.gz |
tracker-store: Storage of signal events as they arrive
Diffstat (limited to 'src/tracker-store/tracker-events.c')
-rw-r--r-- | src/tracker-store/tracker-events.c | 268 |
1 files changed, 186 insertions, 82 deletions
diff --git a/src/tracker-store/tracker-events.c b/src/tracker-store/tracker-events.c index 583e2bfb1..e577469d6 100644 --- a/src/tracker-store/tracker-events.c +++ b/src/tracker-store/tracker-events.c @@ -26,108 +26,207 @@ #include "tracker-events.h" -#define MAX_EVENTS 1000000 - typedef struct { + GHashTable *allowances_id; GHashTable *allowances; - GArray *events; - GStringChunk *chunk; + struct { + GArray *sub_pred_ids; + GArray *object_ids; + } deletes; + struct { + GArray *sub_pred_ids; + GArray *object_ids; + } inserts; gboolean frozen; } EventsPrivate; static EventsPrivate *private; static void -tracker_events_add_allow (const gchar *rdf_class) +get_from_array (GArray *sub_pred_ids, + GArray *object_ids_in, + GArray *subject_ids, + GArray *pred_ids, + GArray *object_ids) { - TrackerClass *cl; + guint i; - g_return_if_fail (private != NULL); + g_array_set_size (subject_ids, 0); + g_array_set_size (pred_ids, 0); + g_array_set_size (object_ids, 0); - cl = tracker_ontologies_get_class_by_uri (rdf_class); - if (!cl) { - g_critical ("Unknown class %s", rdf_class); - return; + for (i = 0; i < sub_pred_ids->len; i++) { + gint subject_id, pred_id, object_id; + gint64 sub_pred_id; + + sub_pred_id = g_array_index (sub_pred_ids, gint64, i); + subject_id = sub_pred_id >> 32; + pred_id = sub_pred_id << 32; + object_id = g_array_index (object_ids_in, gint, i); + + g_array_append_val (subject_ids, subject_id); + g_array_append_val (pred_ids, pred_id); + g_array_append_val (object_ids, object_id); } +} - g_hash_table_insert (private->allowances, cl, - GINT_TO_POINTER (TRUE)); +void +tracker_events_get_inserts (GArray *subject_ids, + GArray *pred_ids, + GArray *object_ids) +{ + g_return_if_fail (private != NULL); + g_return_if_fail (subject_ids != NULL); + g_return_if_fail (pred_ids != NULL); + g_return_if_fail (object_ids != NULL); + + get_from_array (private->inserts.sub_pred_ids, + private->inserts.object_ids, + subject_ids, + pred_ids, + object_ids); } -static gboolean -is_allowed (EventsPrivate *private, TrackerClass *rdf_class) +void +tracker_events_get_deletes (GArray *subject_ids, + GArray *pred_ids, + GArray *object_ids) { - return (g_hash_table_lookup (private->allowances, rdf_class) != NULL) ? TRUE : FALSE; + g_return_if_fail (private != NULL); + g_return_if_fail (subject_ids != NULL); + g_return_if_fail (pred_ids != NULL); + g_return_if_fail (object_ids != NULL); + + get_from_array (private->deletes.sub_pred_ids, + private->deletes.object_ids, + subject_ids, + pred_ids, + object_ids); } -static void -prepare_event_for_rdf_type (EventsPrivate *private, - TrackerClass *rdf_class , - const gchar *uri, - TrackerDBusEventsType type, - const gchar *predicate) +static gboolean +is_allowed (EventsPrivate *private, TrackerClass *rdf_class, gint class_id) { - TrackerEvent event; + gboolean ret; - if (!private->events) { - private->events = g_array_new (TRUE, FALSE, sizeof (TrackerEvent)); + if (rdf_class != NULL) { + ret = (g_hash_table_lookup (private->allowances, rdf_class) != NULL) ? TRUE : FALSE; + } else { + ret = (g_hash_table_lookup (private->allowances_id, GINT_TO_POINTER (class_id)) != NULL) ? TRUE : FALSE; } + return ret; +} - if (!private->chunk) { - private->chunk = g_string_chunk_new (4096); +static void +insert_vals_into_arrays (GArray *sub_pred_ids, + GArray *object_ids, + gint subject_id, + gint pred_id, + gint object_id) +{ + guint i; + gboolean inserted = FALSE; + gint64 sub_pred_id = (gint64) subject_id; + + sub_pred_id = sub_pred_id << 32 | pred_id; + + for (i = 0; i < sub_pred_ids->len; i++) { + if (sub_pred_id < g_array_index (sub_pred_ids, gint64, i)) { + g_array_insert_val (sub_pred_ids, i, sub_pred_id); + g_array_insert_val (object_ids, i, object_id); + inserted = TRUE; + break; + } } - event.type = type; - event.class = rdf_class; - event.predicate = tracker_ontologies_get_property_by_uri (predicate); - event.subject = g_string_chunk_insert_const (private->chunk, uri); + if (!inserted) { + g_array_append_val (sub_pred_ids, sub_pred_ids); + g_array_append_val (object_ids, object_id); + } - g_array_append_val (private->events, event); } void -tracker_events_insert (const gchar *uri, - const gchar *predicate, - const gchar *object, - GPtrArray *rdf_types, - TrackerDBusEventsType type) +tracker_events_add_insert (gint graph_id, + gint subject_id, + const gchar *subject, + gint pred_id, + gint object_id, + const gchar *object, + GPtrArray *rdf_types) { - g_return_if_fail (rdf_types || type != TRACKER_DBUS_EVENTS_TYPE_UPDATE); + TrackerProperty *rdf_type; + + g_return_if_fail (rdf_types != NULL); g_return_if_fail (private != NULL); if (private->frozen) { return; } - if (private->events && private->events->len > MAX_EVENTS) { - /* too many events would lead to high memory usage and to dbus signal messages - larger than maximum dbus message size, which results in dbus disconnect and tracker-store crash */ - g_warning ("Too many events pending, disabling events for current transaction"); - tracker_events_reset (); - private->frozen = TRUE; - } + rdf_type = tracker_ontologies_get_rdf_type (); - if (rdf_types && type == TRACKER_DBUS_EVENTS_TYPE_UPDATE) { + if (object_id != 0 && pred_id == tracker_property_get_id (rdf_type)) { + /* Resource create + * In case of create, object is the rdf:type */ + if (is_allowed (private, NULL, object_id)) { + insert_vals_into_arrays (private->inserts.sub_pred_ids, + private->inserts.object_ids, + subject_id, pred_id, object_id); + } + } else { guint i; for (i = 0; i < rdf_types->len; i++) { + if (is_allowed (private, rdf_types->pdata[i], 0)) { + insert_vals_into_arrays (private->inserts.sub_pred_ids, + private->inserts.object_ids, + subject_id, pred_id, object_id); + } + } + } +} + +void +tracker_events_add_delete (gint graph_id, + gint subject_id, + const gchar *subject, + gint pred_id, + gint object_id, + const gchar *object, + GPtrArray *rdf_types) +{ + TrackerProperty *rdf_type; - /* object is not very important for updates (we don't expose - * the value being set to the user's DBus API in tracker-store) */ - if (is_allowed (private, rdf_types->pdata[i])) { + g_return_if_fail (rdf_types != NULL); + g_return_if_fail (private != NULL); - prepare_event_for_rdf_type (private, rdf_types->pdata[i], - uri, type, predicate); - } + if (private->frozen) { + return; + } + + rdf_type = tracker_ontologies_get_rdf_type (); + + if (object_id != 0 && pred_id == tracker_property_get_id (rdf_type)) { + /* Resource delete + * In case of delete, object is the rdf:type */ + if (is_allowed (private, NULL, object_id)) { + insert_vals_into_arrays (private->deletes.sub_pred_ids, + private->deletes.object_ids, + subject_id, pred_id, object_id); } } else { - TrackerClass *class = tracker_ontologies_get_class_by_uri (object); - /* In case of delete and create, object is the rdf:type */ - if (is_allowed (private, class)) { - prepare_event_for_rdf_type (private, class, - uri, type, predicate); + guint i; + + for (i = 0; i < rdf_types->len; i++) { + if (is_allowed (private, rdf_types->pdata[i], 0)) { + insert_vals_into_arrays (private->deletes.sub_pred_ids, + private->deletes.object_ids, + subject_id, pred_id, object_id); + } } } + } void @@ -135,12 +234,11 @@ tracker_events_reset (void) { g_return_if_fail (private != NULL); - if (private->events) { - g_array_free (private->events, TRUE); - g_string_chunk_free (private->chunk); - private->chunk = NULL; - private->events = NULL; - } + g_array_set_size (private->deletes.sub_pred_ids, 0); + g_array_set_size (private->deletes.object_ids, 0); + g_array_set_size (private->inserts.sub_pred_ids, 0); + g_array_set_size (private->inserts.object_ids, 0); + private->frozen = FALSE; } @@ -152,37 +250,37 @@ tracker_events_freeze (void) private->frozen = TRUE; } -GArray * -tracker_events_get_pending (void) -{ - g_return_val_if_fail (private != NULL, NULL); - - return private->events; -} - static void free_private (EventsPrivate *private) { g_hash_table_unref (private->allowances); + g_hash_table_unref (private->allowances_id); + g_array_free (private->deletes.sub_pred_ids, TRUE); + g_array_free (private->deletes.object_ids, TRUE); + g_array_free (private->inserts.sub_pred_ids, TRUE); + g_array_free (private->inserts.object_ids, TRUE); g_free (private); } void tracker_events_init (TrackerNotifyClassGetter callback) { - GStrv classes_to_signal; - gint i, count; - - private = g_new0 (EventsPrivate, 1); - - private->allowances = g_hash_table_new (g_direct_hash, g_direct_equal); - - private->events = NULL; + GStrv classes_to_signal; + gint i, count; if (!callback) { return; } + private = g_new0 (EventsPrivate, 1); + + private->allowances = g_hash_table_new (g_direct_hash, g_direct_equal); + private->allowances_id = g_hash_table_new (g_direct_hash, g_direct_equal); + private->deletes.sub_pred_ids = g_array_new (FALSE, FALSE, sizeof (gint64)); + private->deletes.object_ids = g_array_new (FALSE, FALSE, sizeof (gint)); + private->inserts.sub_pred_ids = g_array_new (FALSE, FALSE, sizeof (gint64)); + private->inserts.object_ids = g_array_new (FALSE, FALSE, sizeof (gint)); + classes_to_signal = (*callback)(); if (!classes_to_signal) @@ -190,9 +288,16 @@ tracker_events_init (TrackerNotifyClassGetter callback) count = g_strv_length (classes_to_signal); for (i = 0; i < count; i++) { - tracker_events_add_allow (classes_to_signal[i]); + TrackerClass *class = tracker_ontologies_get_class_by_uri (classes_to_signal[i]); + if (class != NULL) { + g_hash_table_insert (private->allowances, + class, + GINT_TO_POINTER (TRUE)); + g_hash_table_insert (private->allowances_id, + GINT_TO_POINTER (tracker_class_get_id (class)), + GINT_TO_POINTER (TRUE)); + } } - g_strfreev (classes_to_signal); } @@ -200,7 +305,6 @@ void tracker_events_shutdown (void) { if (private != NULL) { - tracker_events_reset (); free_private (private); private = NULL; } else { |