[gnome-calendar] timeline: Only diff when ranges intersect



commit b5cdc0bd38d8668f0fb90a1d433e89d4d9dd77f1
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Wed Apr 15 20:32:25 2020 -0300

    timeline: Only diff when ranges intersect
    
    When the old and the new range of the subscribers don't
    overlap entirely, we can't use the regular diff algorithm.
    It fails quite spectacularly.
    
    Do a full cleanup when ranges don't overlap.

 src/core/gcal-timeline.c | 106 +++++++++++++++++++++++++++--------------------
 1 file changed, 61 insertions(+), 45 deletions(-)
---
diff --git a/src/core/gcal-timeline.c b/src/core/gcal-timeline.c
index 7c51ea22..c39e7167 100644
--- a/src/core/gcal-timeline.c
+++ b/src/core/gcal-timeline.c
@@ -267,68 +267,84 @@ calculate_changed_events (GcalTimeline            *self,
 {
   g_autoptr (GPtrArray) events_to_remove = NULL;
   g_autoptr (GPtrArray) events_to_add = NULL;
-  g_autoptr (GDateTime) old_range_start = NULL;
-  g_autoptr (GDateTime) old_range_end = NULL;
-  g_autoptr (GDateTime) new_range_start = NULL;
-  g_autoptr (GDateTime) new_range_end = NULL;
+  GcalRangeOverlap overlap;
   gint range_diff;
   gint i;
 
   events_to_add = g_ptr_array_new ();
   events_to_remove = g_ptr_array_new ();
 
-  old_range_start = gcal_range_get_start (old_range);
-  old_range_end = gcal_range_get_end (old_range);
-  new_range_start = gcal_range_get_start (new_range);
-  new_range_end = gcal_range_get_end (new_range);
+  overlap = gcal_range_calculate_overlap (new_range, old_range, NULL);
 
-  /* Start ranges diff */
-  range_diff = g_date_time_compare (old_range_start, new_range_start);
-  if (range_diff != 0)
+  if (overlap == GCAL_RANGE_NO_OVERLAP)
     {
-      g_autoptr (GPtrArray) events = NULL;
+      GCAL_TRACE_MSG ("Ranges don't overlap, doing a full cleanup");
 
-      if (range_diff < 0)
-        {
-          g_autoptr (GcalRange) range = gcal_range_new (old_range_start, new_range_start, 
GCAL_RANGE_DEFAULT);
-
-          /* Removed */
-          events = gcal_range_tree_get_data_at_range (self->events, range);
-          if (events)
-            g_ptr_array_extend (events_to_remove, events, NULL, NULL);
-        }
-      else if (range_diff > 0)
-        {
-          g_autoptr (GcalRange) range = gcal_range_new (new_range_start, old_range_start, 
GCAL_RANGE_DEFAULT);
-
-          /* Added */
-          events = gcal_range_tree_get_data_at_range (self->events, range);
-          if (events)
-            g_ptr_array_extend (events_to_add, events, NULL, NULL);
-        }
+      events_to_remove = gcal_range_tree_get_data_at_range (self->events, old_range);
+      events_to_add = gcal_range_tree_get_data_at_range (self->events, new_range);
     }
-
-  /* End ranges diff */
-  range_diff = g_date_time_compare (old_range_end, new_range_end);
-  if (range_diff != 0)
+  else
     {
-      g_autoptr (GPtrArray) events = NULL;
+      g_autoptr (GDateTime) old_range_start = NULL;
+      g_autoptr (GDateTime) old_range_end = NULL;
+      g_autoptr (GDateTime) new_range_start = NULL;
+      g_autoptr (GDateTime) new_range_end = NULL;
+
+      GCAL_TRACE_MSG ("Ranges overlap, doing a diff");
+
+      old_range_start = gcal_range_get_start (old_range);
+      old_range_end = gcal_range_get_end (old_range);
+      new_range_start = gcal_range_get_start (new_range);
+      new_range_end = gcal_range_get_end (new_range);
 
-      if (range_diff < 0)
+      /* Start ranges diff */
+      range_diff = g_date_time_compare (old_range_start, new_range_start);
+      if (range_diff != 0)
         {
-          g_autoptr (GcalRange) range = gcal_range_new (old_range_end, new_range_end, GCAL_RANGE_DEFAULT);
+          g_autoptr (GPtrArray) events = NULL;
+
+          if (range_diff < 0)
+            {
+              g_autoptr (GcalRange) range = gcal_range_new (old_range_start, new_range_start, 
GCAL_RANGE_DEFAULT);
 
-          events = gcal_range_tree_get_data_at_range (self->events, range);
-          if (events)
-            g_ptr_array_extend (events_to_add, events, NULL, NULL);
+              /* Removed */
+              events = gcal_range_tree_get_data_at_range (self->events, range);
+              if (events)
+                g_ptr_array_extend (events_to_remove, events, NULL, NULL);
+            }
+          else if (range_diff > 0)
+            {
+              g_autoptr (GcalRange) range = gcal_range_new (new_range_start, old_range_start, 
GCAL_RANGE_DEFAULT);
+
+              /* Added */
+              events = gcal_range_tree_get_data_at_range (self->events, range);
+              if (events)
+                g_ptr_array_extend (events_to_add, events, NULL, NULL);
+            }
         }
-      else if (range_diff > 0)
+
+      /* End ranges diff */
+      range_diff = g_date_time_compare (old_range_end, new_range_end);
+      if (range_diff != 0)
         {
-          g_autoptr (GcalRange) range = gcal_range_new (new_range_end, old_range_end, GCAL_RANGE_DEFAULT);
+          g_autoptr (GPtrArray) events = NULL;
 
-          events = gcal_range_tree_get_data_at_range (self->events, range);
-          if (events)
-            g_ptr_array_extend (events_to_remove, events, NULL, NULL);
+          if (range_diff < 0)
+            {
+              g_autoptr (GcalRange) range = gcal_range_new (old_range_end, new_range_end, 
GCAL_RANGE_DEFAULT);
+
+              events = gcal_range_tree_get_data_at_range (self->events, range);
+              if (events)
+                g_ptr_array_extend (events_to_add, events, NULL, NULL);
+            }
+          else if (range_diff > 0)
+            {
+              g_autoptr (GcalRange) range = gcal_range_new (new_range_end, old_range_end, 
GCAL_RANGE_DEFAULT);
+
+              events = gcal_range_tree_get_data_at_range (self->events, range);
+              if (events)
+                g_ptr_array_extend (events_to_remove, events, NULL, NULL);
+            }
         }
     }
 


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