{
gpointer key; /* key for this node */
gpointer value; /* value stored at this node */
+ guint ref_count;
};
struct _GTreeNode
node->data = g_slice_new(GTreeNodeData);
node->data->key = key;
node->data->value = value;
+ node->data->ref_count = 1;
/* for the version 0, only allocate one set of pointers for a node,
so that we don't use a lot more memory when persistence isn't even
/* we filled the node's pointer table and need to make a new GTreeNode */
GTreeNode *newnode = g_slice_new(GTreeNode);
newnode->data = node->data;
+ newnode->data->ref_count++;
newnode->v[0] = node->v[0]; /* copy the latest version to here */
newnode->v[0].version = tree->version;
newnode->nv = 1;
{
GTreeNode *node, *parent;
gboolean is_leftchild;
+ gboolean key_removed = FALSE;
g_return_val_if_fail (tree != NULL, FALSE);
it needs to be remembered */
if (node->nv == 1 && node->version(NOW) == tree->version)
{
- if (!steal)
+ /* free the node's data if it's the last node which is using it. just
+ because the version of the node was created in the latest version
+ of the tree, doesn't mean there aren't older versions around still */
+ if (--node->data->ref_count == 0)
{
- if (tree->key_destroy_func)
- tree->key_destroy_func (node->data->key);
- if (tree->value_destroy_func)
- tree->value_destroy_func (node->data->value);
+ if (!steal)
+ {
+ if (tree->key_destroy_func)
+ tree->key_destroy_func (node->data->key);
+ if (tree->value_destroy_func)
+ tree->value_destroy_func (node->data->value);
+ }
+ g_slice_free (GTreeNodeData, node->data);
+
+ key_removed = TRUE;
}
- g_slice_free (GTreeNodeData, node->data);
g_slice_free1 (sizeof(GTreeNodeVersion) *
(node->version(NOW) == 0 ? 1 : MAX_IN_DEGREE + 1),
node->v);
g_slice_free (GTreeNode, node);
-
- return TRUE;
}
- return FALSE;
+ return key_removed;
}
/**