range-tree: Support destroy function

This commit is contained in:
Georges Basile Stavracas Neto
2020-04-01 21:06:50 -03:00
parent 78248bec5e
commit ec0c17f6fb
2 changed files with 39 additions and 12 deletions
+32 -7
View File
@@ -58,6 +58,7 @@ struct _GcalRangeTree
{ {
guint ref_count; guint ref_count;
GDestroyNotify destroy_func;
Node *root; Node *root;
}; };
@@ -155,7 +156,8 @@ is_interval_higher (Node *n,
static Node* static Node*
node_new (GDateTime *start, node_new (GDateTime *start,
GDateTime *end, GDateTime *end,
gpointer data) gpointer data,
GDestroyNotify destroy_func)
{ {
Node *n; Node *n;
@@ -166,7 +168,7 @@ node_new (GDateTime *start,
n->height = 1; n->height = 1;
n->hits = 1; n->hits = 1;
n->data_array = g_ptr_array_new (); n->data_array = g_ptr_array_new_with_free_func (destroy_func);
g_ptr_array_add (n->data_array, data); g_ptr_array_add (n->data_array, data);
return n; return n;
@@ -246,19 +248,20 @@ static Node*
insert (Node *n, insert (Node *n,
GDateTime *start, GDateTime *start,
GDateTime *end, GDateTime *end,
gpointer data) gpointer data,
GDestroyNotify destroy_func)
{ {
gint result; gint result;
if (!n) if (!n)
return node_new (start, end, data); return node_new (start, end, data, destroy_func);
result = compare_intervals (n->start, n->end, start, end); result = compare_intervals (n->start, n->end, start, end);
if (result < 0) if (result < 0)
n->left = insert (n->left, start, end, data); n->left = insert (n->left, start, end, data, destroy_func);
else if (result > 0) else if (result > 0)
n->right = insert (n->right, start, end, data); n->right = insert (n->right, start, end, data, destroy_func);
else else
return hit_node (n, data); return hit_node (n, data);
@@ -500,6 +503,28 @@ gcal_range_tree_new (void)
return self; return self;
} }
/**
* gcal_range_tree_new_with_free_func:
* @destroy_func: (nullable): a function to free elements with
*
* Creates a new range tree with @destroy_func as the function to
* destroy elements when removing them.
*
* Returns: (transfer full): a newly created #GcalRangeTree.
* Free with gcal_range_tree_unref() when done.
*/
GcalRangeTree*
gcal_range_tree_new_with_free_func (GDestroyNotify destroy_func)
{
GcalRangeTree *self;
self = g_slice_new0 (GcalRangeTree);
self->ref_count = 1;
self->destroy_func = destroy_func;
return self;
}
/** /**
* gcal_range_tree_copy: * gcal_range_tree_copy:
* @self: a #GcalRangeTree * @self: a #GcalRangeTree
@@ -580,7 +605,7 @@ gcal_range_tree_add_range (GcalRangeTree *self,
g_return_if_fail (end && start); g_return_if_fail (end && start);
g_return_if_fail (g_date_time_compare (end, start) >= 0); g_return_if_fail (g_date_time_compare (end, start) >= 0);
self->root = insert (self->root, start, end, data); self->root = insert (self->root, start, end, data, self->destroy_func);
} }
/** /**
+2
View File
@@ -50,6 +50,8 @@ GType gcal_range_tree_get_type (void) G_GNUC_C
GcalRangeTree* gcal_range_tree_new (void); GcalRangeTree* gcal_range_tree_new (void);
GcalRangeTree* gcal_range_tree_new_with_free_func (GDestroyNotify destroy_func);
GcalRangeTree* gcal_range_tree_copy (GcalRangeTree *self); GcalRangeTree* gcal_range_tree_copy (GcalRangeTree *self);
GcalRangeTree* gcal_range_tree_ref (GcalRangeTree *self); GcalRangeTree* gcal_range_tree_ref (GcalRangeTree *self);