[gnome-calendar/gnome-3-36] timeline: Cancel additions and removals



commit 4ead7338b13ab75288122ee56dcc76ff45536b4f
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Thu Apr 16 15:11:53 2020 -0300

    timeline: Cancel additions and removals
    
    When we add an event to the queue, and later remove it, if the
    event is still in the queue, we can just cancel both out and
    save the timeline some processing time.

 src/core/gcal-timeline.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 60 insertions(+), 2 deletions(-)
---
diff --git a/src/core/gcal-timeline.c b/src/core/gcal-timeline.c
index 2369651e..bacc2fa6 100644
--- a/src/core/gcal-timeline.c
+++ b/src/core/gcal-timeline.c
@@ -77,6 +77,7 @@ struct _GcalTimeline
 
   GCancellable       *cancellable;
 
+  GHashTable         *queued_adds;
   GQueue             *event_queue;
   GSource            *timeline_source;
 
@@ -101,6 +102,13 @@ static GParamSpec *properties [N_PROPS] = { NULL, };
  * Auxiliary methods
  */
 
+static gchar*
+format_subscriber_event_id (GcalTimelineSubscriber *subscriber,
+                            GcalEvent              *event)
+{
+  return g_strdup_printf ("%s:%s", G_OBJECT_TYPE_NAME (subscriber), gcal_event_get_uid (event));
+}
+
 static void
 queue_data_free (QueueData *queue_data)
 {
@@ -118,6 +126,7 @@ queue_event_data (GcalTimeline           *self,
                   GcalEvent              *old_event,
                   gboolean                update_range_tree)
 {
+  g_autofree gchar *subscriber_event_id = NULL;
   QueueData *queue_data;
 
   queue_data = g_new0 (QueueData, 1);
@@ -128,7 +137,49 @@ queue_event_data (GcalTimeline           *self,
   queue_data->old_event = old_event ? g_object_ref (old_event) : NULL;
   queue_data->update_range_tree = update_range_tree;
 
+  subscriber_event_id = format_subscriber_event_id (subscriber, event);
+
+  switch (queue_event)
+    {
+    case ADD_EVENT:
+    case UPDATE_EVENT:
+      break;
+    case REMOVE_EVENT:
+        {
+          GList *queued_add_link;
+
+          queued_add_link = g_hash_table_lookup (self->queued_adds, subscriber_event_id);
+          if (queued_add_link)
+            {
+              QueueData *queued_add = queued_add_link->data;
+
+              GCAL_TRACE_MSG ("Removing ADD_EVENT for event '%s' (%s) from event queue",
+                              gcal_event_get_summary (event),
+                              subscriber_event_id);
+
+              g_hash_table_remove (self->queued_adds, subscriber_event_id);
+              g_queue_delete_link (self->event_queue, queued_add_link);
+              queue_data_free (queued_add);
+              return;
+            }
+        }
+      break;
+    }
+
   g_queue_push_tail (self->event_queue, queue_data);
+
+  switch (queue_event)
+    {
+    case ADD_EVENT:
+      g_hash_table_insert (self->queued_adds,
+                           g_steal_pointer (&subscriber_event_id),
+                           g_queue_peek_tail_link (self->event_queue));
+      break;
+
+    case UPDATE_EVENT:
+    case REMOVE_EVENT:
+      break;
+    }
 }
 
 static inline gboolean
@@ -608,6 +659,7 @@ timeline_source_dispatch (GSource     *source,
   while (processed_events < BATCH_SIZE && !g_queue_is_empty (self->event_queue))
     {
       GcalTimelineSubscriber *subscriber;
+      g_autofree gchar *subscriber_event_id = NULL;
       GcalRange *event_range;
       QueueData *queue_data;
       GcalEvent *event;
@@ -617,10 +669,12 @@ timeline_source_dispatch (GSource     *source,
       event = queue_data->event;
       subscriber = queue_data->subscriber;
       event_range = gcal_event_get_range (event);
+      subscriber_event_id = format_subscriber_event_id (subscriber, event);
 
       /* The subscriber may have been removed already */
       if (!g_hash_table_contains (self->subscribers, subscriber))
         {
+          g_hash_table_remove (self->queued_adds, subscriber_event_id);
           queue_data_free (queue_data);
           continue;
         }
@@ -628,10 +682,12 @@ timeline_source_dispatch (GSource     *source,
       switch (queue_data->queue_event)
         {
         case ADD_EVENT:
-          GCAL_TRACE_MSG ("Processing ADD_EVENT for event '%s' (%s)",
+          GCAL_TRACE_MSG ("Processing ADD_EVENT for event '%s' (%s) (in queued_adds: %d)",
                           gcal_event_get_summary (event),
-                          gcal_event_get_uid (event));
+                          gcal_event_get_uid (event),
+                          g_hash_table_contains (self->queued_adds, subscriber_event_id));
 
+          g_hash_table_remove (self->queued_adds, subscriber_event_id);
           if (queue_data->update_range_tree)
             gcal_range_tree_add_range (self->events, event_range, g_object_ref (event));
 
@@ -708,6 +764,7 @@ gcal_timeline_finalize (GObject *object)
   g_clear_pointer (&self->events, gcal_range_tree_unref);
   g_clear_pointer (&self->calendars, g_hash_table_destroy);
   g_clear_pointer (&self->subscribers, g_hash_table_destroy);
+  g_clear_pointer (&self->queued_adds, g_hash_table_destroy);
   g_clear_pointer (&self->subscriber_ranges, gcal_range_tree_unref);
 
   g_source_destroy (self->timeline_source);
@@ -829,6 +886,7 @@ gcal_timeline_init (GcalTimeline *self)
   self->subscribers = g_hash_table_new_full (NULL, NULL, g_object_unref, (GDestroyNotify) gcal_range_unref);
   self->subscriber_ranges = gcal_range_tree_new ();
   self->event_queue = g_queue_new ();
+  self->queued_adds = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 
   /* Timeline source */
   timeline_source = (TimelineSource*) g_source_new (&timeline_source_funcs, sizeof (TimelineSource));


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