From b5cdc0bd38d8668f0fb90a1d433e89d4d9dd77f1 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 15 Apr 2020 20:32:25 -0300 Subject: [PATCH] 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 | 108 ++++++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 46 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; - if (range_diff < 0) + 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); + + /* 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; - events = gcal_range_tree_get_data_at_range (self->events, range); - if (events) - g_ptr_array_extend (events_to_add, events, NULL, NULL); + 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); + } } - 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); + /* End ranges diff */ + range_diff = g_date_time_compare (old_range_end, new_range_end); + if (range_diff != 0) + { + g_autoptr (GPtrArray) events = 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); + } } }