[gnome-calendar/gbsneto/range: 8/15] range-tree: Use GcalRange



commit 3efbc2436cc04f943d0c89ccf07c6ffdb8c2eede
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Mon Apr 13 10:30:23 2020 -0300

    range-tree: Use GcalRange

 src/core/gcal-range-tree.c | 249 +++++++++++++++++----------------------------
 src/core/gcal-range-tree.h |  17 ++--
 src/core/gcal-timeline.c   | 113 ++++++++++----------
 src/views/gcal-week-grid.c |  88 ++++++----------
 tests/test-range-tree.c    |  59 ++++++-----
 5 files changed, 221 insertions(+), 305 deletions(-)
---
diff --git a/src/core/gcal-range-tree.c b/src/core/gcal-range-tree.c
index ad77488c..59b66c6c 100644
--- a/src/core/gcal-range-tree.c
+++ b/src/core/gcal-range-tree.c
@@ -1,6 +1,6 @@
 /* gcal-range-tree.c
  *
- * Copyright (C) 2016 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ * Copyright (C) 2016-2020 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -46,8 +46,7 @@ typedef struct _Node
 {
   struct _Node       *left;
   struct _Node       *right;
-  GDateTime          *start;
-  GDateTime          *end;
+  GcalRange          *range;
   GDateTime          *max;
   guint16             hits;
   gint64              height;
@@ -74,8 +73,7 @@ destroy_tree (Node *n)
   destroy_tree (n->left);
   destroy_tree (n->right);
 
-  gcal_clear_date_time (&n->start);
-  gcal_clear_date_time (&n->end);
+  g_clear_pointer (&n->range, gcal_range_unref);
   gcal_clear_date_time (&n->max);
 
   g_ptr_array_unref (n->data_array);
@@ -100,71 +98,16 @@ balance (Node *n)
   return n ? height (n->left) - height (n->right) : 0;
 }
 
-/*
- * Compares the ranges A [a_start, a_end] and B [b_start, b_end]. A is
- * less rangy than B when either it starts before B, or starts at the
- * same point but ends before B.
- *
- * Some examples:
- *
- * 1. [-----A----]     =  0
- *    [-----B----]
- *
- * 2. [----A----]      =  1
- *      [----B----]
- *
- * 3. [------A-----]   = -1
- *    [----B----]
- *
- * 4.   [----A----]    = -1
- *    [----B----]
- *
- * This is *not* comparing the sizes of the ranges.
- */
-static inline gboolean
-compare_intervals (GDateTime *a_start,
-                   GDateTime *a_end,
-                   GDateTime *b_start,
-                   GDateTime *b_end)
-{
-  gint result = g_date_time_compare (b_start, a_start);
-
-  if (result == 0)
-    result = g_date_time_compare (b_end, a_end);
-
-  return result;
-}
-
-static inline gboolean
-is_interval_lower (Node      *n,
-                   GDateTime *start,
-                   GDateTime *end)
-{
-  gint a_compare = g_date_time_compare (start, n->start);
-  return a_compare < 0 || (a_compare == 0 && g_date_time_compare (end, n->end) < 0);
-}
-
-static inline gboolean
-is_interval_higher (Node      *n,
-                    GDateTime *start,
-                    GDateTime *end)
-{
-  gint a_compare = g_date_time_compare (start, n->start);
-  return a_compare > 0 || (a_compare == 0 && g_date_time_compare (end, n->end) > 0);
-}
-
 static Node*
-node_new (GDateTime      *start,
-          GDateTime      *end,
+node_new (GcalRange      *range,
           gpointer        data,
           GDestroyNotify  destroy_func)
 {
   Node *n;
 
   n = g_new0 (Node, 1);
-  n->start = g_date_time_ref (start);
-  n->end = g_date_time_ref (end);
-  n->max = g_date_time_ref (end);
+  n->range = gcal_range_ref (range);
+  n->max = gcal_range_get_end (range);
   n->height = 1;
   n->hits = 1;
 
@@ -246,31 +189,30 @@ rebalance (Node *n)
 
 static Node*
 insert (Node           *n,
-        GDateTime      *start,
-        GDateTime      *end,
+        GcalRange      *range,
         gpointer        data,
         GDestroyNotify  destroy_func)
 {
+  g_autoptr (GDateTime) range_end = NULL;
   gint result;
 
   if (!n)
-    return node_new (start, end, data, destroy_func);
+    return node_new (range, data, destroy_func);
 
-  result = compare_intervals (n->start, n->end, start, end);
+  result = gcal_range_compare (range, n->range);
 
   if (result < 0)
-    n->left = insert (n->left, start, end, data, destroy_func);
+    n->left = insert (n->left, range, data, destroy_func);
   else if (result > 0)
-    n->right = insert (n->right, start, end, data, destroy_func);
+    n->right = insert (n->right, range, data, destroy_func);
   else
     return hit_node (n, data);
 
+  range_end = gcal_range_get_end (range);
+
   /* Update the current node's maximum subrange value */
-  if (!n->max || g_date_time_compare (end, n->max) > 0)
-    {
-      gcal_clear_date_time (&n->max);
-      n->max = g_date_time_ref (end);
-    }
+  if (!n->max || g_date_time_compare (range_end, n->max) > 0)
+    gcal_set_date_time (&n->max, range_end);
 
   return rebalance (n);
 }
@@ -327,19 +269,32 @@ delete_node (Node     *n,
 
 static Node*
 remove_node (Node      *n,
-             GDateTime *start,
-             GDateTime *end,
+             GcalRange *range,
              gpointer   data)
 {
+  GcalRangePosition position;
+
   if (!n)
     return NULL;
 
-  if (is_interval_lower (n, start, end))
-    n->left = remove_node (n->left, start, end, data);
-  else if (is_interval_higher (n, start, end))
-    n->right = remove_node (n->right, start, end, data);
-  else
-    return delete_node (n, data);
+  gcal_range_calculate_overlap (range, n->range, &position);
+
+  switch (position)
+    {
+    case GCAL_RANGE_BEFORE:
+      n->left = remove_node (n->left, range, data);
+      break;
+
+    case GCAL_RANGE_MATCH:
+      return delete_node (n, data);
+
+    case GCAL_RANGE_AFTER:
+      n->right = remove_node (n->right, range, data);
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
 
   return rebalance (n);
 }
@@ -354,7 +309,7 @@ run_traverse_func (Node                  *n,
 
   for (i = 0; i < n->hits; i++)
     {
-      if (func (n->start, n->end, g_ptr_array_index (n->data_array, i), user_data))
+      if (func (n->range, g_ptr_array_index (n->data_array, i), user_data))
         return TRUE;
     }
 
@@ -399,8 +354,7 @@ traverse (Node                  *n,
 
 /* Internal traverse functions */
 static inline gboolean
-gather_all_data (GDateTime *start,
-                 GDateTime *end,
+gather_all_data (GcalRange *range,
                  gpointer   data,
                  gpointer   user_data)
 {
@@ -412,71 +366,66 @@ gather_all_data (GDateTime *start,
 }
 
 static inline gboolean
-gather_data_at_range (GDateTime *start,
-                      GDateTime *end,
+gather_data_at_range (GcalRange *range,
                       gpointer   data,
                       gpointer   user_data)
 {
+  GcalRangePosition position;
+  GcalRangeOverlap overlap;
+
   struct {
-    GDateTime *start, *end;
+    GcalRange *range;
     GPtrArray **array;
-  } *range = user_data;
+  } *gather_data = user_data;
 
-  /* Since we're traversing in order, stop here */
-  if (compare_intervals (range->start, range->end, start, end) > 0 &&
-      g_date_time_compare (start, range->end) >= 0)
+  overlap = gcal_range_calculate_overlap (range, gather_data->range, &position);
+
+  if (overlap == GCAL_RANGE_NO_OVERLAP)
     {
-      return GCAL_TRAVERSE_STOP;
+      if (position == GCAL_RANGE_BEFORE)
+        return GCAL_TRAVERSE_CONTINUE;
+      if (position == GCAL_RANGE_AFTER)
+        return GCAL_TRAVERSE_STOP;
     }
 
-  /*
-   * If the current range doesn't overlap but we're before the desired range, keep
-   * traversing the tree
-   */
-  if (g_date_time_compare (range->start, end) >= 0)
-    return GCAL_TRAVERSE_CONTINUE;
-
-  if (!*range->array)
-    *range->array = g_ptr_array_new ();
+  if (!*gather_data->array)
+    *gather_data->array = g_ptr_array_new ();
 
-  g_ptr_array_add (*range->array, data);
+  g_ptr_array_add (*gather_data->array, data);
 
   return GCAL_TRAVERSE_CONTINUE;
 }
 
 static inline gboolean
-count_entries_at_range (GDateTime *start,
-                        GDateTime *end,
+count_entries_at_range (GcalRange *range,
                         gpointer   data,
                         gpointer   user_data)
 {
+  GcalRangePosition position;
+  GcalRangeOverlap overlap;
+
   struct {
-    GDateTime *start, *end;
+    GcalRange *range;
     guint64 counter;
-  } *range = user_data;
+  } *gather_data = user_data;
 
-  /* Since we're traversing in order, stop here */
-  if (compare_intervals (range->start, range->end, start, end) > 0 &&
-      g_date_time_compare (start, range->end) >= 0)
+  overlap = gcal_range_calculate_overlap (range, gather_data->range, &position);
+
+  if (overlap == GCAL_RANGE_NO_OVERLAP)
     {
-      return GCAL_TRAVERSE_STOP;
+      if (position == GCAL_RANGE_BEFORE)
+        return GCAL_TRAVERSE_CONTINUE;
+      if (position == GCAL_RANGE_AFTER)
+        return GCAL_TRAVERSE_STOP;
     }
 
-  /*
-   * If the current range doesn't overlap but we're before the desired range, keep
-   * traversing the tree
-   */
-  if (g_date_time_compare (range->start, end) >= 0)
-    return GCAL_TRAVERSE_CONTINUE;
-
-  range->counter++;
+  gather_data->counter++;
 
   return GCAL_TRAVERSE_CONTINUE;
 }
 
 static inline gboolean
-remove_data_func (GDateTime *start,
-                  GDateTime *end,
+remove_data_func (GcalRange *range,
                   gpointer   data,
                   gpointer   user_data)
 {
@@ -487,7 +436,7 @@ remove_data_func (GDateTime *start,
 
   if (remove_data->data == data)
     {
-      gcal_range_tree_remove_range (remove_data->range_tree, start, end, data);
+      gcal_range_tree_remove_range (remove_data->range_tree, range, data);
       return GCAL_TRAVERSE_STOP;
     }
 
@@ -607,8 +556,7 @@ gcal_range_tree_unref (GcalRangeTree *self)
 /**
  * gcal_range_tree_add_range:
  * @self: a #GcalRangeTree
- * @start: start of the interval
- * @end: end of the interval
+ * @range: a #GcalRange
  * @data: user data
  *
  * Adds the range into @self, and attach @data do it. It is
@@ -618,37 +566,32 @@ gcal_range_tree_unref (GcalRangeTree *self)
  */
 void
 gcal_range_tree_add_range (GcalRangeTree *self,
-                           GDateTime     *start,
-                           GDateTime     *end,
+                           GcalRange     *range,
                            gpointer       data)
 {
   g_return_if_fail (self);
-  g_return_if_fail (end && start);
-  g_return_if_fail (g_date_time_compare (end, start) >= 0);
+  g_return_if_fail (range);
 
-  self->root = insert (self->root, start, end, data, self->destroy_func);
+  self->root = insert (self->root, range, data, self->destroy_func);
 }
 
 /**
  * gcal_range_tree_remove_range:
  * @self: a #GcalRangeTree
- * @start: the start of the range
- * @end: the end of the range
+ * @range: a #GcalRange
  * @data: user data
  *
  * Removes (or decreases the reference count) of the given interval.
  */
 void
 gcal_range_tree_remove_range (GcalRangeTree *self,
-                              GDateTime     *start,
-                              GDateTime     *end,
+                              GcalRange     *range,
                               gpointer       data)
 {
   g_return_if_fail (self);
-  g_return_if_fail (end && start);
-  g_return_if_fail (g_date_time_compare (end, start) >= 0);
+  g_return_if_fail (range);
 
-  self->root = remove_node (self->root, start, end, data);
+  self->root = remove_node (self->root, range, data);
 }
 
 /**
@@ -717,33 +660,30 @@ gcal_range_tree_get_all_data (GcalRangeTree *self)
 /**
  * gcal_range_tree_get_data_at_range:
  * @self: a #GcalRangeTree
- * @start: inclusive start of the range
- * @end: exclusive end of the range
+ * @range: a #GcalRange
  *
- * Retrieves the data of every node between @start and @end.
+ * Retrieves the data of every node within @range.
  *
  * Returns: (transfer full): a #GPtrArray. Unref with g_ptr_array_unref()
  * when finished.
  */
 GPtrArray*
 gcal_range_tree_get_data_at_range (GcalRangeTree *self,
-                                   GDateTime     *start,
-                                   GDateTime     *end)
+                                   GcalRange     *range)
 {
   GPtrArray *data;
 
   struct {
-    GDateTime *start, *end;
+    GcalRange *range;
     GPtrArray **array;
-  } range = { start, end, &data };
+  } gather_data = { range, &data };
 
   g_return_val_if_fail (self, NULL);
-  g_return_val_if_fail (end && start, NULL);
-  g_return_val_if_fail (g_date_time_compare (end, start) >= 0, NULL);
+  g_return_val_if_fail (range, NULL);
 
   data = NULL;
 
-  gcal_range_tree_traverse (self, G_IN_ORDER, gather_data_at_range, &range);
+  gcal_range_tree_traverse (self, G_IN_ORDER, gather_data_at_range, &gather_data);
 
   return data;
 }
@@ -751,8 +691,7 @@ gcal_range_tree_get_data_at_range (GcalRangeTree *self,
 /**
  * gcal_range_tree_count_entries_at_range:
  * @self: a #GcalRangeTree
- * @start: start of the range
- * @end: end of the range
+ * @range: a #GcalRange
  *
  * Counts the number of entries available in the given
  * range.
@@ -761,19 +700,17 @@ gcal_range_tree_get_data_at_range (GcalRangeTree *self,
  */
 guint64
 gcal_range_tree_count_entries_at_range (GcalRangeTree *self,
-                                        GDateTime     *start,
-                                        GDateTime     *end)
+                                        GcalRange     *range)
 {
   struct {
-    GDateTime *start, *end;
+    GcalRange *range;
     guint64 counter;
-  } range = { start, end, 0 };
+  } gather_data = { range, 0 };
 
   g_return_val_if_fail (self, 0);
-  g_return_val_if_fail (end && start, 0);
-  g_return_val_if_fail (g_date_time_compare (end, start) >= 0, 0);
+  g_return_val_if_fail (range, 0);
 
-  gcal_range_tree_traverse (self, G_IN_ORDER, count_entries_at_range, &range);
+  gcal_range_tree_traverse (self, G_IN_ORDER, count_entries_at_range, &gather_data);
 
-  return range.counter;
+  return gather_data.counter;
 }
diff --git a/src/core/gcal-range-tree.h b/src/core/gcal-range-tree.h
index b5e1bbc5..9bfa5f8a 100644
--- a/src/core/gcal-range-tree.h
+++ b/src/core/gcal-range-tree.h
@@ -18,6 +18,8 @@
 
 #pragma once
 
+#include "gcal-range.h"
+
 #include <glib-object.h>
 
 G_BEGIN_DECLS
@@ -37,8 +39,7 @@ typedef struct _GcalRangeTree GcalRangeTree;
  *
  * Returns: %TRUE to stop traversing, %FALSE to continue traversing
  */
-typedef gboolean    (*GcalRangeTraverseFunc)                     (GDateTime          *start,
-                                                                  GDateTime          *end,
+typedef gboolean    (*GcalRangeTraverseFunc)                     (GcalRange          *range,
                                                                   gpointer            data,
                                                                   gpointer            user_data);
 
@@ -58,13 +59,11 @@ GcalRangeTree*       gcal_range_tree_ref                         (GcalRangeTree
 void                 gcal_range_tree_unref                       (GcalRangeTree      *self);
 
 void                 gcal_range_tree_add_range                   (GcalRangeTree      *self,
-                                                                  GDateTime          *start,
-                                                                  GDateTime          *end,
+                                                                  GcalRange          *range,
                                                                   gpointer            data);
 
 void                 gcal_range_tree_remove_range                (GcalRangeTree      *self,
-                                                                  GDateTime          *start,
-                                                                  GDateTime          *end,
+                                                                  GcalRange          *range,
                                                                   gpointer            data);
 
 void                 gcal_range_tree_remove_data                 (GcalRangeTree      *self,
@@ -78,12 +77,10 @@ void                 gcal_range_tree_traverse                    (GcalRangeTree
 GPtrArray*           gcal_range_tree_get_all_data                (GcalRangeTree      *self);
 
 GPtrArray*           gcal_range_tree_get_data_at_range           (GcalRangeTree      *self,
-                                                                  GDateTime          *start,
-                                                                  GDateTime          *end);
+                                                                  GcalRange          *range);
 
 guint64              gcal_range_tree_count_entries_at_range      (GcalRangeTree      *self,
-                                                                  GDateTime          *start,
-                                                                  GDateTime          *end);
+                                                                  GcalRange          *range);
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GcalRangeTree, gcal_range_tree_unref)
 
diff --git a/src/core/gcal-timeline.c b/src/core/gcal-timeline.c
index d630e6a4..5732a313 100644
--- a/src/core/gcal-timeline.c
+++ b/src/core/gcal-timeline.c
@@ -308,20 +308,27 @@ update_range (GcalTimeline *self)
 static void
 calculate_changed_events (GcalTimeline            *self,
                           GcalTimelineSubscriber  *subscriber,
-                          GDateTime               *old_range_start,
-                          GDateTime               *old_range_end,
-                          GDateTime               *new_range_start,
-                          GDateTime               *new_range_end)
+                          GcalRange               *old_range,
+                          GcalRange               *new_range)
 {
   g_autoptr (GPtrArray) subscriber_array = NULL;
   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;
   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);
+
   /* Start ranges diff */
   range_diff = g_date_time_compare (old_range_start, new_range_start);
   if (range_diff != 0)
@@ -330,15 +337,19 @@ calculate_changed_events (GcalTimeline            *self,
 
       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, old_range_start, new_range_start);
+          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, new_range_start, old_range_start);
+          events = gcal_range_tree_get_data_at_range (self->events, range);
           if (events)
             g_ptr_array_extend (events_to_add, events, NULL, NULL);
         }
@@ -352,13 +363,17 @@ calculate_changed_events (GcalTimeline            *self,
 
       if (range_diff < 0)
         {
-          events = gcal_range_tree_get_data_at_range (self->events, old_range_end, new_range_end);
+          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)
         {
-          events = gcal_range_tree_get_data_at_range (self->events, new_range_end, old_range_end);
+          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);
         }
@@ -403,6 +418,7 @@ static void
 add_cached_events_to_subscriber (GcalTimeline           *self,
                                  GcalTimelineSubscriber *subscriber)
 {
+  g_autoptr (GcalRange) subscriber_range = NULL;
   g_autoptr (GDateTime) subscriber_start = NULL;
   g_autoptr (GDateTime) subscriber_end = NULL;
   g_autoptr (GPtrArray) subscriber_array = NULL;
@@ -413,8 +429,9 @@ add_cached_events_to_subscriber (GcalTimeline           *self,
 
   subscriber_start = gcal_timeline_subscriber_get_range_start (subscriber);
   subscriber_end = gcal_timeline_subscriber_get_range_end (subscriber);
+  subscriber_range = gcal_range_new (subscriber_start, subscriber_end, GCAL_RANGE_DEFAULT);
 
-  events_to_add = gcal_range_tree_get_data_at_range (self->events, subscriber_start, subscriber_end);
+  events_to_add = gcal_range_tree_get_data_at_range (self->events, subscriber_range);
 
   subscriber_array = g_ptr_array_new ();
   g_ptr_array_add (subscriber_array, subscriber);
@@ -441,8 +458,8 @@ static void
 update_subscriber_range (GcalTimeline           *self,
                          GcalTimelineSubscriber *subscriber)
 {
-  g_autoptr (GDateTime) new_range_start = NULL;
-  g_autoptr (GDateTime) new_range_end = NULL;
+  g_autoptr (GcalRange) old_range = NULL;
+  g_autoptr (GcalRange) new_range = NULL;
   SubscriberData *subscriber_data;
 
 
@@ -451,26 +468,23 @@ update_subscriber_range (GcalTimeline           *self,
   subscriber_data = g_hash_table_lookup (self->subscribers, subscriber);
   g_assert (subscriber_data != NULL);
 
-  new_range_start = gcal_timeline_subscriber_get_range_start (subscriber);
-  new_range_end = gcal_timeline_subscriber_get_range_end (subscriber);
+  old_range = gcal_range_new (subscriber_data->range_start, subscriber_data->range_end, GCAL_RANGE_DEFAULT);
+  new_range = gcal_range_new_take (gcal_timeline_subscriber_get_range_start (subscriber),
+                                   gcal_timeline_subscriber_get_range_end (subscriber),
+                                   GCAL_RANGE_DEFAULT);
 
   /* Diff new and old event ranges */
-  calculate_changed_events (self,
-                            subscriber,
-                            subscriber_data->range_start,
-                            subscriber_data->range_end,
-                            new_range_start,
-                            new_range_end);
+  calculate_changed_events (self, subscriber, old_range, new_range);
 
   /* Update the subscriber range */
   gcal_range_tree_remove_data (self->subscriber_ranges, subscriber);
-  gcal_range_tree_add_range (self->subscriber_ranges,
-                             new_range_start,
-                             new_range_end,
-                             subscriber);
+  gcal_range_tree_add_range (self->subscriber_ranges, new_range, subscriber);
 
-  gcal_set_date_time (&subscriber_data->range_start, new_range_start);
-  gcal_set_date_time (&subscriber_data->range_end, new_range_end);
+  gcal_clear_date_time (&subscriber_data->range_start);
+  subscriber_data->range_start = gcal_range_get_start (new_range);
+
+  gcal_clear_date_time (&subscriber_data->range_end);
+  subscriber_data->range_end = gcal_range_get_end (new_range);
 
   GCAL_EXIT;
 }
@@ -499,16 +513,14 @@ on_calendar_monitor_event_added_cb (GcalCalendarMonitor *monitor,
                                     GcalTimeline        *self)
 {
   g_autoptr (GPtrArray) subscribers_at_range = NULL;
-  GDateTime *event_start;
-  GDateTime *event_end;
+  GcalRange *event_range;
 
   GCAL_ENTRY;
 
-  event_start = gcal_event_get_date_start (event);
-  event_end = gcal_event_get_date_end (event);
+  event_range = gcal_event_get_range (event);
 
   /* Add to all subscribers within the event range */
-  subscribers_at_range = gcal_range_tree_get_data_at_range (self->subscriber_ranges, event_start, event_end);
+  subscribers_at_range = gcal_range_tree_get_data_at_range (self->subscriber_ranges, event_range);
 
   if (subscribers_at_range)
     queue_event_data (self, ADD_EVENT, subscribers_at_range, event, NULL, TRUE);
@@ -523,17 +535,15 @@ on_calendar_monitor_event_updated_cb (GcalCalendarMonitor *monitor,
                                       GcalTimeline        *self)
 {
   g_autoptr (GPtrArray) subscribers_at_range = NULL;
-  GDateTime *event_start;
-  GDateTime *event_end;
+  GcalRange *event_range;
 
   GCAL_ENTRY;
 
   /* Add the updated event to the (potentially new) range */
-  event_start = gcal_event_get_date_start (event);
-  event_end = gcal_event_get_date_end (event);
+  event_range = gcal_event_get_range (event);
 
   /* Add to all subscribers within the event range */
-  subscribers_at_range = gcal_range_tree_get_data_at_range (self->subscriber_ranges, event_start, event_end);
+  subscribers_at_range = gcal_range_tree_get_data_at_range (self->subscriber_ranges, event_range);
 
   if (subscribers_at_range)
     queue_event_data (self, UPDATE_EVENT, subscribers_at_range, event, old_event, TRUE);
@@ -547,16 +557,14 @@ on_calendar_monitor_event_removed_cb (GcalCalendarMonitor *monitor,
                                       GcalTimeline        *self)
 {
   g_autoptr (GPtrArray) subscribers_at_range = NULL;
-  GDateTime *event_start;
-  GDateTime *event_end;
+  GcalRange *event_range;
 
   GCAL_ENTRY;
 
-  event_start = gcal_event_get_date_start (event);
-  event_end = gcal_event_get_date_end (event);
+  event_range = gcal_event_get_range (event);
 
   /* Add to all subscribers within the event range */
-  subscribers_at_range = gcal_range_tree_get_data_at_range (self->subscriber_ranges, event_start, event_end);
+  subscribers_at_range = gcal_range_tree_get_data_at_range (self->subscriber_ranges, event_range);
 
   if (subscribers_at_range)
     queue_event_data (self, REMOVE_EVENT, subscribers_at_range, event, NULL, TRUE);
@@ -623,8 +631,7 @@ timeline_source_dispatch (GSource     *source,
 {
   TimelineSource *timeline_source;
   GcalTimeline *self;
-  GDateTime *event_start;
-  GDateTime *event_end;
+  GcalRange *event_range;
   QueueData *queue_data;
   GcalEvent *event;
   gint i;
@@ -636,8 +643,7 @@ timeline_source_dispatch (GSource     *source,
   queue_data = g_queue_pop_head (self->event_queue);
 
   event = queue_data->event;
-  event_start = gcal_event_get_date_start (event);
-  event_end = gcal_event_get_date_end (event);
+  event_range = gcal_event_get_range (event);
 
   switch (queue_data->queue_event)
     {
@@ -647,7 +653,7 @@ timeline_source_dispatch (GSource     *source,
                       gcal_event_get_uid (event));
 
       if (queue_data->update_range_tree)
-        gcal_range_tree_add_range (self->events, event_start, event_end, g_object_ref (event));
+        gcal_range_tree_add_range (self->events, event_range, g_object_ref (event));
 
       for (i = 0; queue_data->subscribers && i < queue_data->subscribers->len; i++)
         {
@@ -668,15 +674,13 @@ timeline_source_dispatch (GSource     *source,
 
         if (queue_data->update_range_tree)
           {
-            GDateTime *old_event_start;
-            GDateTime *old_event_end;
+            GcalRange *old_event_range;
 
             /* Remove the old event */
-            old_event_start = gcal_event_get_date_start (queue_data->old_event);
-            old_event_end = gcal_event_get_date_end (queue_data->old_event);
+            old_event_range = gcal_event_get_range (queue_data->old_event);
 
-            gcal_range_tree_remove_range (self->events, old_event_start, old_event_end, 
queue_data->old_event);
-            gcal_range_tree_add_range (self->events, event_start, event_end, g_object_ref (event));
+            gcal_range_tree_remove_range (self->events, old_event_range, queue_data->old_event);
+            gcal_range_tree_add_range (self->events, event_range, g_object_ref (event));
           }
 
         for (i = 0; queue_data->subscribers && i < queue_data->subscribers->len; i++)
@@ -703,7 +707,7 @@ timeline_source_dispatch (GSource     *source,
         }
 
       if (queue_data->update_range_tree)
-        gcal_range_tree_remove_range (self->events, event_start, event_end, event);
+        gcal_range_tree_remove_range (self->events, event_range, event);
       break;
     }
 
@@ -1007,13 +1011,14 @@ gcal_timeline_get_events_at_range (GcalTimeline *self,
                                    GDateTime    *range_end)
 {
   g_autoptr (GPtrArray) events_at_range = NULL;
+  g_autoptr (GcalRange) range = NULL;
 
   g_return_val_if_fail (GCAL_IS_TIMELINE (self), NULL);
   g_return_val_if_fail (range_start != NULL, NULL);
   g_return_val_if_fail (range_end != NULL, NULL);
-  g_return_val_if_fail (g_date_time_compare (range_start, range_end) < 0, NULL);
 
-  events_at_range = gcal_range_tree_get_data_at_range (self->events, range_start, range_end);
+  range = gcal_range_new (range_start, range_end, GCAL_RANGE_DEFAULT);
+  events_at_range = gcal_range_tree_get_data_at_range (self->events, range);
 
   return g_steal_pointer (&events_at_range);
 }
diff --git a/src/views/gcal-week-grid.c b/src/views/gcal-week-grid.c
index 5e2b7ab2..7a06774e 100644
--- a/src/views/gcal-week-grid.c
+++ b/src/views/gcal-week-grid.c
@@ -1,6 +1,6 @@
 /* gcal-week-grid.c
  *
- * Copyright (C) 2016 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ * Copyright (C) 2016-2020 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *                    Vamsi Krishna Gollapudi <pandu sonu yahoo com>
  *
  * This program is free software: you can redistribute it and/or modify
@@ -127,14 +127,13 @@ uint16_compare (gconstpointer a,
 
 static inline guint
 get_event_index (GcalRangeTree *tree,
-                 GDateTime     *start,
-                 GDateTime     *end)
+                 GcalRange     *range)
 {
   g_autoptr (GPtrArray) array;
   gint idx, i;
 
   i = idx = 0;
-  array = gcal_range_tree_get_data_at_range (tree, start, end);
+  array = gcal_range_tree_get_data_at_range (tree, range);
 
   if (!array)
     return 0;
@@ -154,59 +153,35 @@ get_event_index (GcalRangeTree *tree,
 
 static guint
 count_overlaps_at_range (GcalRangeTree *self,
-                         GDateTime     *start,
-                         GDateTime     *end)
+                         GcalRange     *range)
 {
+  g_autoptr (GDateTime) start = NULL;
+  g_autoptr (GDateTime) end = NULL;
   guint64 counter;
+  gint minutes;
+  gint i;
 
   g_return_val_if_fail (self, 0);
 
   counter = 0;
+  start = gcal_range_get_start (range);
+  end = gcal_range_get_end (range);
+  minutes = g_date_time_difference (end, start) / G_TIME_SPAN_MINUTE;
 
-  while (g_date_time_compare (start, end) < 0)
+  for (i = 0; i < minutes; i++)
     {
-      g_autoptr (GDateTime) start_plus_one = NULL;
+      g_autoptr (GcalRange) minute_range = NULL;
       guint n_events;
 
-      start_plus_one = g_date_time_add_minutes (start, 1);
-      n_events = gcal_range_tree_count_entries_at_range (self, start, start_plus_one);
+      minute_range = gcal_range_new_take (g_date_time_add_minutes (start, i),
+                                          g_date_time_add_minutes (start, i + 1),
+                                          GCAL_RANGE_DEFAULT);
+      n_events = gcal_range_tree_count_entries_at_range (self, minute_range);
 
       if (n_events == 0)
         break;
 
       counter = MAX (counter, n_events);
-
-      start = g_steal_pointer (&start_plus_one);
-    }
-
-  return counter;
-}
-
-static guint
-count_overlaps_of_event (GcalRangeTree *self,
-                         GDateTime     *day_start,
-                         GDateTime     *day_end,
-                         GDateTime     *event_start,
-                         GDateTime     *event_end)
-{
-  guint64 counter;
-
-  counter = count_overlaps_at_range (self, event_start, day_end);
-
-  while (g_date_time_compare (event_start, day_start) > 0)
-    {
-      g_autoptr (GDateTime) start_minus_one = NULL;
-      guint n_events;
-
-      start_minus_one = g_date_time_add_minutes (event_start, -1);
-      n_events = gcal_range_tree_count_entries_at_range (self, start_minus_one, event_start);
-
-      if (n_events == 0)
-        break;
-
-      counter = MAX (counter, n_events);
-
-      event_start = g_date_time_add_minutes (event_start, 1);
     }
 
   return counter;
@@ -589,20 +564,21 @@ gcal_week_grid_size_allocate (GtkWidget     *widget,
    */
   for (i = 0; i < 7; i++)
     {
-      g_autoptr (GDateTime) day_start = NULL;
-      g_autoptr (GDateTime) day_end = NULL;
+      g_autoptr (GcalRange) day_range = NULL;
       GPtrArray *widgets_data;
       guint j;
 
-      day_start = g_date_time_add_days (week_start, i);
-      day_end = g_date_time_add_days (day_start, 1);
-      widgets_data = gcal_range_tree_get_data_at_range (self->events, day_start, day_end);
+      day_range = gcal_range_new_take (g_date_time_add_days (week_start, i),
+                                       g_date_time_add_days (week_start, i + 1),
+                                       GCAL_RANGE_DEFAULT);
+      widgets_data = gcal_range_tree_get_data_at_range (self->events, day_range);
 
       for (j = 0; widgets_data && j < widgets_data->len; j++)
         {
           GtkStyleContext *context;
           GtkAllocation child_allocation;
           GtkWidget *event_widget;
+          GcalRange *event_range;
           GDateTime *event_start;
           GDateTime *event_end;
           ChildData *data;
@@ -617,15 +593,16 @@ gcal_week_grid_size_allocate (GtkWidget     *widget,
 
           data =  g_ptr_array_index (widgets_data, j);
           event_widget = data->widget;
+          event_range = gcal_event_get_range (data->event);
           event_start = gcal_event_get_date_start (data->event);
           event_end = gcal_event_get_date_end (data->event);
           context = gtk_widget_get_style_context (event_widget);
 
           /* The total number of events available in this range */
-          events_at_range = count_overlaps_of_event (self->events, day_start, day_end, event_start, 
event_end);
+          events_at_range = count_overlaps_at_range (self->events, event_range);
 
           /* The real horizontal position of this event */
-          widget_index = get_event_index (overlaps, event_start, event_end);
+          widget_index = get_event_index (overlaps, event_range);
 
           /* Gtk complains about that */
           gtk_widget_get_preferred_height (event_widget, NULL, &natural_height);
@@ -663,10 +640,7 @@ gcal_week_grid_size_allocate (GtkWidget     *widget,
            * Add the current event to the temporary overlaps tree so we have a way to
            * know how many events are already positioned in the current column.
            */
-          gcal_range_tree_add_range (overlaps,
-                                     event_start,
-                                     event_end,
-                                     GUINT_TO_POINTER (widget_index));
+          gcal_range_tree_add_range (overlaps, event_range, GUINT_TO_POINTER (widget_index));
         }
 
       g_clear_pointer (&widgets_data, g_ptr_array_unref);
@@ -1114,8 +1088,7 @@ gcal_week_grid_add_event (GcalWeekGrid *self,
                          NULL);
 
   gcal_range_tree_add_range (self->events,
-                             gcal_event_get_date_start (event),
-                             gcal_event_get_date_end (event),
+                             gcal_event_get_range (event),
                              child_data_new (widget, event));
 
   setup_event_widget (self, widget);
@@ -1146,10 +1119,7 @@ gcal_week_grid_remove_event (GcalWeekGrid *self,
       if (g_strcmp0 (gcal_event_get_uid (event), uid) != 0)
         continue;
 
-      gcal_range_tree_remove_range (self->events,
-                                    gcal_event_get_date_start (event),
-                                    gcal_event_get_date_end (event),
-                                    data);
+      gcal_range_tree_remove_range (self->events, gcal_event_get_range (event), data);
       destroy_event_widget (self, data->widget);
       gtk_widget_queue_allocate (GTK_WIDGET (self));
       g_object_unref (event);
diff --git a/tests/test-range-tree.c b/tests/test-range-tree.c
index 8315b435..ddc7e8a8 100644
--- a/tests/test-range-tree.c
+++ b/tests/test-range-tree.c
@@ -37,6 +37,7 @@ static void
 range_tree_insert (void)
 {
   g_autoptr (GcalRangeTree) range_tree = NULL;
+  g_autoptr (GcalRange) range = NULL;
   g_autoptr (GDateTime) start = NULL;
   g_autoptr (GDateTime) end = NULL;
 
@@ -45,15 +46,16 @@ range_tree_insert (void)
 
   start = g_date_time_new_local (2020, 3, 17, 9, 30, 0);
   end = g_date_time_add_hours (start, 1);
+  range = gcal_range_new (start, end, GCAL_RANGE_DEFAULT);
 
-  gcal_range_tree_add_range (range_tree, start, end, (gpointer) 0xdeadbeef);
-  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, start, end), ==, 1);
+  gcal_range_tree_add_range (range_tree, range, (gpointer) 0xdeadbeef);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, range), ==, 1);
 
-  gcal_range_tree_add_range (range_tree, start, end, (gpointer) 0x8badf00d);
-  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, start, end), ==, 2);
+  gcal_range_tree_add_range (range_tree, range, (gpointer) 0x8badf00d);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, range), ==, 2);
 
-  gcal_range_tree_add_range (range_tree, start, end, (gpointer) 0x0badcafe);
-  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, start, end), ==, 3);
+  gcal_range_tree_add_range (range_tree, range, (gpointer) 0x0badcafe);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, range), ==, 3);
 }
 
 
/*********************************************************************************************************************/
@@ -73,8 +75,7 @@ static struct {
 };
 
 static gboolean
-traverse_func (GDateTime *start,
-               GDateTime *end,
+traverse_func (GcalRange *range,
                gpointer   data,
                gpointer   user_data)
 {
@@ -96,13 +97,13 @@ range_tree_traverse (void)
   utc = g_time_zone_new_utc ();
   for (i = 0; i < G_N_ELEMENTS (ranges); i++)
     {
-      g_autoptr (GDateTime) start = NULL;
-      g_autoptr (GDateTime) end = NULL;
+      g_autoptr (GcalRange) range = NULL;
 
-      start = g_date_time_new_from_iso8601 (ranges[i].start, utc);
-      end = g_date_time_new_from_iso8601 (ranges[i].end, utc);
+      range = gcal_range_new_take (g_date_time_new_from_iso8601 (ranges[i].start, utc),
+                                   g_date_time_new_from_iso8601 (ranges[i].end, utc),
+                                   GCAL_RANGE_DEFAULT);
 
-      gcal_range_tree_add_range (range_tree, start, end, GINT_TO_POINTER (i));
+      gcal_range_tree_add_range (range_tree, range, GINT_TO_POINTER (i));
     }
 
   gcal_range_tree_traverse (range_tree, G_PRE_ORDER, traverse_func, NULL);
@@ -118,6 +119,8 @@ range_tree_smaller_range (void)
   g_autoptr (GcalRangeTree) range_tree = NULL;
   g_autoptr (GDateTime) range_start = NULL;
   g_autoptr (GDateTime) range_end = NULL;
+  g_autoptr (GcalRange) range1 = NULL;
+  g_autoptr (GcalRange) range2 = NULL;
   g_autoptr (GDateTime) start = NULL;
   g_autoptr (GDateTime) end = NULL;
 
@@ -126,14 +129,16 @@ range_tree_smaller_range (void)
 
   start = g_date_time_new_local (2020, 3, 17, 9, 30, 0);
   end = g_date_time_add_hours (start, 1);
+  range1 = gcal_range_new (start, end, GCAL_RANGE_DEFAULT);
 
-  gcal_range_tree_add_range (range_tree, start, end, (gpointer) 0xdeadbeef);
-  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, start, end), ==, 1);
+  gcal_range_tree_add_range (range_tree, range1, (gpointer) 0xdeadbeef);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, range1), ==, 1);
 
   range_start = g_date_time_new_local (2020, 3, 20, 9, 30, 0);
   range_end = g_date_time_add_hours (range_start, 1);
+  range2 = gcal_range_new (range_start, range_end, GCAL_RANGE_DEFAULT);
 
-  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, range_start, range_end), ==, 0);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, range2), ==, 0);
 }
 
 
/*********************************************************************************************************************/
@@ -142,6 +147,7 @@ static void
 range_tree_remove_data (void)
 {
   g_autoptr (GcalRangeTree) range_tree = NULL;
+  g_autoptr (GcalRange) range = NULL;
   g_autoptr (GDateTime) start = NULL;
   g_autoptr (GDateTime) end = NULL;
 
@@ -150,30 +156,31 @@ range_tree_remove_data (void)
 
   start = g_date_time_new_local (2020, 3, 17, 9, 30, 0);
   end = g_date_time_add_hours (start, 1);
+  range = gcal_range_new (start, end, GCAL_RANGE_DEFAULT);
 
-  gcal_range_tree_add_range (range_tree, start, end, (gpointer) 0xdeadbeef);
-  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, start, end), ==, 1);
+  gcal_range_tree_add_range (range_tree, range, (gpointer) 0xdeadbeef);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, range), ==, 1);
 
-  gcal_range_tree_add_range (range_tree, start, end, (gpointer) 0xdeadbeef);
-  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, start, end), ==, 2);
+  gcal_range_tree_add_range (range_tree, range, (gpointer) 0xdeadbeef);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, range), ==, 2);
 
-  gcal_range_tree_add_range (range_tree, start, end, (gpointer) 0xbadcafe);
-  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, start, end), ==, 3);
+  gcal_range_tree_add_range (range_tree, range, (gpointer) 0xbadcafe);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, range), ==, 3);
 
   /* Remove the 2 deadbeefs */
   gcal_range_tree_remove_data (range_tree, (gpointer) 0xdeadbeef);
-  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, start, end), ==, 2);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, range), ==, 2);
 
   gcal_range_tree_remove_data (range_tree, (gpointer) 0xdeadbeef);
-  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, start, end), ==, 1);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, range), ==, 1);
 
   /* Try again */
   gcal_range_tree_remove_data (range_tree, (gpointer) 0xdeadbeef);
-  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, start, end), ==, 1);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, range), ==, 1);
 
   /* Remove bad cafe */
   gcal_range_tree_remove_data (range_tree, (gpointer) 0xbadcafe);
-  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, start, end), ==, 0);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, range), ==, 0);
 }
 
 
/*********************************************************************************************************************/



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