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.
This commit is contained in:
Georges Basile Stavracas Neto
2020-04-15 20:35:04 -03:00
parent a1a4804315
commit b5cdc0bd38
+62 -46
View File
@@ -267,68 +267,84 @@ calculate_changed_events (GcalTimeline *self,
{ {
g_autoptr (GPtrArray) events_to_remove = NULL; g_autoptr (GPtrArray) events_to_remove = NULL;
g_autoptr (GPtrArray) events_to_add = NULL; g_autoptr (GPtrArray) events_to_add = NULL;
g_autoptr (GDateTime) old_range_start = NULL; GcalRangeOverlap overlap;
g_autoptr (GDateTime) old_range_end = NULL;
g_autoptr (GDateTime) new_range_start = NULL;
g_autoptr (GDateTime) new_range_end = NULL;
gint range_diff; gint range_diff;
gint i; gint i;
events_to_add = g_ptr_array_new (); events_to_add = g_ptr_array_new ();
events_to_remove = g_ptr_array_new (); events_to_remove = g_ptr_array_new ();
old_range_start = gcal_range_get_start (old_range); overlap = gcal_range_calculate_overlap (new_range, old_range, NULL);
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 */ if (overlap == GCAL_RANGE_NO_OVERLAP)
range_diff = g_date_time_compare (old_range_start, new_range_start);
if (range_diff != 0)
{ {
g_autoptr (GPtrArray) events = NULL; GCAL_TRACE_MSG ("Ranges don't overlap, doing a full cleanup");
if (range_diff < 0) 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);
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
/* End ranges diff */
range_diff = g_date_time_compare (old_range_end, new_range_end);
if (range_diff != 0)
{ {
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 (range_diff < 0)
if (events) {
g_ptr_array_extend (events_to_add, events, NULL, NULL); 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); /* End ranges diff */
if (events) range_diff = g_date_time_compare (old_range_end, new_range_end);
g_ptr_array_extend (events_to_remove, events, NULL, NULL); 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);
}
} }
} }