range-tree: Add API to remove data
It'll be useful to remove entries without knowing their range.
This commit is contained in:
@@ -473,6 +473,27 @@ count_entries_at_range (GDateTime *start,
|
|||||||
|
|
||||||
return GCAL_TRAVERSE_CONTINUE;
|
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
|
static void
|
||||||
gcal_range_tree_free (GcalRangeTree *self)
|
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);
|
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:
|
* gcal_range_tree_traverse:
|
||||||
* @self: a #GcalRangeTree
|
* @self: a #GcalRangeTree
|
||||||
|
|||||||
@@ -68,6 +68,9 @@ void gcal_range_tree_remove_range (GcalRangeTree
|
|||||||
GDateTime *end,
|
GDateTime *end,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
|
void gcal_range_tree_remove_data (GcalRangeTree *self,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
void gcal_range_tree_traverse (GcalRangeTree *self,
|
void gcal_range_tree_traverse (GcalRangeTree *self,
|
||||||
GTraverseType type,
|
GTraverseType type,
|
||||||
GcalRangeTraverseFunc func,
|
GcalRangeTraverseFunc func,
|
||||||
|
|||||||
@@ -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
|
gint
|
||||||
main (gint argc,
|
main (gint argc,
|
||||||
gchar *argv[])
|
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/insert", range_tree_insert);
|
||||||
g_test_add_func ("/range-tree/traverse", range_tree_traverse);
|
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/smaller-range", range_tree_smaller_range);
|
||||||
|
g_test_add_func ("/range-tree/remove-data", range_tree_remove_data);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user