[gnome-calendar/gnome-3-36] range-tree: Add API to remove data



commit 4c17eb29d9f32bc4994961f9467ba26cb6a7222b
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue Mar 24 18:53:27 2020 -0300

    range-tree: Add API to remove data
    
    It'll be useful to remove entries without knowing their
    range.

 src/views/gcal-range-tree.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 src/views/gcal-range-tree.h |  3 +++
 tests/test-range-tree.c     | 41 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 86 insertions(+)
---
diff --git a/src/views/gcal-range-tree.c b/src/views/gcal-range-tree.c
index ec75425c..ad77488c 100644
--- a/src/views/gcal-range-tree.c
+++ b/src/views/gcal-range-tree.c
@@ -473,6 +473,27 @@ count_entries_at_range (GDateTime *start,
 
   return GCAL_TRAVERSE_CONTINUE;
 }
+
+static inline gboolean
+remove_data_func (GDateTime *start,
+                  GDateTime *end,
+                  gpointer   data,
+                  gpointer   user_data)
+{
+  struct {
+    GcalRangeTree *range_tree;
+    gpointer      *data;
+  } *remove_data = user_data;
+
+  if (remove_data->data == data)
+    {
+      gcal_range_tree_remove_range (remove_data->range_tree, start, end, data);
+      return GCAL_TRAVERSE_STOP;
+    }
+
+  return GCAL_TRAVERSE_CONTINUE;
+}
+
 static void
 gcal_range_tree_free (GcalRangeTree *self)
 {
@@ -630,6 +651,27 @@ gcal_range_tree_remove_range (GcalRangeTree *self,
   self->root = remove_node (self->root, start, end, data);
 }
 
+/**
+ * gcal_range_tree_remove_data:
+ * @self: a #GcalRangeTree
+ * @data: user data
+ *
+ * Removes the first instance of @data found in the range tree.
+ */
+void
+gcal_range_tree_remove_data (GcalRangeTree *self,
+                             gpointer       data)
+{
+  struct {
+    GcalRangeTree *range_tree;
+    gpointer      *data;
+  } remove_data = { self, data };
+
+  g_return_if_fail (self);
+
+  gcal_range_tree_traverse (self, G_IN_ORDER, remove_data_func, &remove_data);
+}
+
 /**
  * gcal_range_tree_traverse:
  * @self: a #GcalRangeTree
diff --git a/src/views/gcal-range-tree.h b/src/views/gcal-range-tree.h
index e1ff6077..53cff2f3 100644
--- a/src/views/gcal-range-tree.h
+++ b/src/views/gcal-range-tree.h
@@ -68,6 +68,9 @@ void                 gcal_range_tree_remove_range                (GcalRangeTree
                                                                   GDateTime          *end,
                                                                   gpointer            data);
 
+void                 gcal_range_tree_remove_data                 (GcalRangeTree      *self,
+                                                                  gpointer            data);
+
 void                 gcal_range_tree_traverse                    (GcalRangeTree      *self,
                                                                   GTraverseType       type,
                                                                   GcalRangeTraverseFunc func,
diff --git a/tests/test-range-tree.c b/tests/test-range-tree.c
index ed9974bb..8315b435 100644
--- a/tests/test-range-tree.c
+++ b/tests/test-range-tree.c
@@ -138,6 +138,46 @@ range_tree_smaller_range (void)
 
 
/*********************************************************************************************************************/
 
+static void
+range_tree_remove_data (void)
+{
+  g_autoptr (GcalRangeTree) range_tree = NULL;
+  g_autoptr (GDateTime) start = NULL;
+  g_autoptr (GDateTime) end = NULL;
+
+  range_tree = gcal_range_tree_new ();
+  g_assert_nonnull (range_tree);
+
+  start = g_date_time_new_local (2020, 3, 17, 9, 30, 0);
+  end = g_date_time_add_hours (start, 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), ==, 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, start, end, (gpointer) 0xbadcafe);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, start, end), ==, 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);
+
+  gcal_range_tree_remove_data (range_tree, (gpointer) 0xdeadbeef);
+  g_assert_cmpint (gcal_range_tree_count_entries_at_range (range_tree, start, end), ==, 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);
+
+  /* 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);
+}
+
+/*********************************************************************************************************************/
+
 gint
 main (gint   argc,
       gchar *argv[])
@@ -150,6 +190,7 @@ main (gint   argc,
   g_test_add_func ("/range-tree/insert", range_tree_insert);
   g_test_add_func ("/range-tree/traverse", range_tree_traverse);
   g_test_add_func ("/range-tree/smaller-range", range_tree_smaller_range);
+  g_test_add_func ("/range-tree/remove-data", range_tree_remove_data);
 
   return g_test_run ();
 }


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