GTreeRootVersion *r; /* versioned root nodes of the tree. roots[0] is
the highest (latest) version. then
roots[1]..roots[nroots-1] are
- older versions in ascending order */
+ older versions in ascending order. Use first_v(),
+ next_v() and prev_v() to traverse the list. */
guint nr;
GCompareDataFunc key_compare;
GDestroyNotify key_destroy_func;
GTreeNodeData *data; /* the node's permanent data */
GTreeNodeVersion *v; /* versions of pointers for the node. v[0] is the
highest (latest) version. then v[1]..v[nv-1] are
- older versions in ascending order */
+ older versions in ascending order. Use first_v(),
+ next_v() and prev_v() to traverse the list. */
guint nv; /* number of versions stored in this node */
};
-#define NOW (0)
-
-#define version(i) v[i].version
-#define left(i) v[i].left
-#define right(i) v[i].right
-#define parent(i) v[i].parent
-
static GTreeNode* g_tree_node_new (GTree *tree,
gpointer key,
gpointer value);
}
g_slice_free1 (sizeof(GTreeNodeVersion) *
- (node->version(NOW) == 0 ? 1 : TABLE_SIZE),
+ (node->v[0].version == 0 ? 1 : TABLE_SIZE),
node->v);
node->v = NULL;
node->data = NULL;
if (!node)
return;
- g_tree_node_free_all (tree, node->left(NOW));
- g_tree_node_free_all (tree, node->right(NOW));
+ g_tree_node_free_all (tree, node->v[0].left);
+ g_tree_node_free_all (tree, node->v[0].right);
g_tree_node_free (tree, node);
}
return NULL;
/* node already has the current version */
- if (node->version(NOW) == tree->version)
+ if (node->v[0].version == tree->version)
return node;
/* if we filled the node's pointer table and need to make a new GTreeNode */
- else if (node->version(NOW) == 0 || node->nv >= TABLE_SIZE)
+ else if (node->v[0].version == 0 || node->nv >= TABLE_SIZE)
{
GTreeNode *newnode = g_slice_new(GTreeNode);
newnode->v = g_slice_alloc(sizeof(GTreeNodeVersion) * TABLE_SIZE);
g_assert (newnode != NULL);
/* find incoming edges to the old version of the node */
- oldparent = newnode->parent(NOW);
- if (oldparent && oldparent->left(NOW) != oldnode &&
- oldparent->right(NOW) != oldnode)
+ oldparent = newnode->v[0].parent;
+ if (oldparent && oldparent->v[0].left != oldnode &&
+ oldparent->v[0].right != oldnode)
oldparent = NULL;
- oldleft = newnode->left(NOW);
- if (oldleft && oldleft->parent(NOW) != oldnode)
+ oldleft = newnode->v[0].left;
+ if (oldleft && oldleft->v[0].parent != oldnode)
oldleft = NULL;
- oldright = newnode->right(NOW);
- if (oldright && oldright->parent(NOW) != oldnode)
+ oldright = newnode->v[0].right;
+ if (oldright && oldright->v[0].parent != oldnode)
oldright = NULL;
/* add new pointers for nodes that point to me, possibly creating new
/* 2. update my incoming nodes to point back to the new version of me */
if (newparent)
{
- if (newparent->left(NOW) == oldnode)
+ if (newparent->v[0].left == oldnode)
newparent->v[0].left = newnode;
else
newparent->v[0].right = newnode;
if (!oldnode)
return NULL;
- g_assert(oldnode->version(NOW) <= tree->version);
+ g_assert(oldnode->v[0].version <= tree->version);
newnode = g_tree_node_add_version (tree, oldnode);
g_tree_node_fix_incoming (tree, oldnode, newnode);
}
else if (cmp < 0)
{
- if (node->left(NOW))
- node = node->left(NOW);
+ if (node->v[0].left)
+ node = node->v[0].left;
else
{
child = g_tree_node_new (tree, key, value);
}
else
{
- if (node->right(NOW))
- node = node->right(NOW);
+ if (node->v[0].right)
+ node = node->v[0].right;
else
{
child = g_tree_node_new (tree, key, value);
/* rotate the new node up until the heap property is restored */
node = child;
- while (node->parent(NOW) &&
- g_tree_priority (node) < g_tree_priority (node->parent(NOW)))
+ while (node->v[0].parent &&
+ g_tree_priority (node) < g_tree_priority (node->v[0].parent))
{
GTreeNode *sp, *p;
/* we'll be changing both of these nodes */
- p = g_tree_node_next_version (tree, node->parent(NOW));
- sp = g_tree_node_next_version (tree, p->parent(NOW));
+ p = g_tree_node_next_version (tree, node->v[0].parent);
+ sp = g_tree_node_next_version (tree, p->v[0].parent);
- if (p->left(NOW) == node)
+ if (p->v[0].left == node)
node = g_tree_node_rotate_right (tree, p);
else
node = g_tree_node_rotate_left (tree, p);
g_tree_root_next_version (tree);
tree->r[0].root = node;
}
- else if (sp->left(NOW) == p)
+ else if (sp->v[0].left == p)
sp->v[0].left = node;
else
sp->v[0].right = node;
break;
else if (cmp < 0)
{
- if (!node->left(NOW))
+ if (!node->v[0].left)
return FALSE;
parent = node;
is_leftchild = TRUE;
- node = node->left(NOW);
+ node = node->v[0].left;
}
else
{
- if (!node->right(NOW))
+ if (!node->v[0].right)
return FALSE;
parent = node;
is_leftchild = FALSE;
- node = node->right(NOW);
+ node = node->v[0].right;
}
}
/* rotate the node down the tree, maintaining the heap property */
- while (node->left(NOW) || node->right(NOW))
+ while (node->v[0].left || node->v[0].right)
{
/* we're changing this node, make sure our pointer will stay valid
when we rotate it */
node = g_tree_node_next_version (tree, node);
/* getting the next version for the node may change where its parent
lies, so get a new pointer for it, from the node */
- parent = node->parent(NOW);
+ parent = node->v[0].parent;
- if (!node->left(NOW) ||
- (node->right(NOW) &&
- g_tree_priority (node->left(NOW)) >
- g_tree_priority (node->right(NOW))))
+ if (!node->v[0].left ||
+ (node->v[0].right &&
+ g_tree_priority (node->v[0].left) >
+ g_tree_priority (node->v[0].right)))
{
/* rotate the right child up */
if (!parent)
tree->nnodes--;
- if (node->version(NOW) == tree->version)
+ if (node->v[0].version == tree->version)
{
/* remove the entry from the node's pointer table */
node->v[0] = node->v[node->nv-1];
{
gint l = 0, r = 0;
if (node == NULL) return 0;
- if (node->left(NOW)) l = g_tree_node_height (node->left(NOW));
- if (node->right(NOW)) r = g_tree_node_height (node->right(NOW));
+ if (node->v[0].left) l = g_tree_node_height (node->v[0].left);
+ if (node->v[0].right) r = g_tree_node_height (node->v[0].right);
return 1 + MAX(l, r);
}
if ((*traverse_func) (node->data->key, node->data->value, data))
return TRUE;
- if (node->left(NOW))
+ if (node->v[0].left)
{
- if (g_tree_node_pre_order (node->left(NOW), traverse_func, data))
+ if (g_tree_node_pre_order (node->v[0].left, traverse_func, data))
return TRUE;
}
- if (node->right(NOW))
+ if (node->v[0].right)
{
- if (g_tree_node_pre_order (node->right(NOW), traverse_func, data))
+ if (g_tree_node_pre_order (node->v[0].right, traverse_func, data))
return TRUE;
}
GTraverseFunc traverse_func,
gpointer data)
{
- if (node->left(NOW))
+ if (node->v[0].left)
{
- if (g_tree_node_in_order (node->left(NOW), traverse_func, data))
+ if (g_tree_node_in_order (node->v[0].left, traverse_func, data))
return TRUE;
}
if ((*traverse_func) (node->data->key, node->data->value, data))
return TRUE;
- if (node->right(NOW))
+ if (node->v[0].right)
{
- if (g_tree_node_in_order (node->right(NOW), traverse_func, data))
+ if (g_tree_node_in_order (node->v[0].right, traverse_func, data))
return TRUE;
}
GTraverseFunc traverse_func,
gpointer data)
{
- if (node->left(NOW))
+ if (node->v[0].left)
{
- if (g_tree_node_post_order (node->left(NOW), traverse_func, data))
+ if (g_tree_node_post_order (node->v[0].left, traverse_func, data))
return TRUE;
}
- if (node->right(NOW))
+ if (node->v[0].right)
{
- if (g_tree_node_post_order (node->right(NOW), traverse_func, data))
+ if (g_tree_node_post_order (node->v[0].right, traverse_func, data))
return TRUE;
}
{
GTreeNode *right;
- g_assert (node->version(NOW) == tree->version);
+ g_assert (node->v[0].version == tree->version);
- right = g_tree_node_next_version (tree, node->right(NOW));
+ right = g_tree_node_next_version (tree, node->v[0].right);
- if (right->left(NOW))
+ if (right->v[0].left)
{
- node->v[0].right = g_tree_node_next_version (tree, right->left(NOW));
+ node->v[0].right = g_tree_node_next_version (tree, right->v[0].left);
node->v[0].right->v[0].parent = node;
}
else
node->v[0].right = NULL;
right->v[0].left = node;
- right->v[0].parent = node->parent(NOW);
+ right->v[0].parent = node->v[0].parent;
node->v[0].parent = right;
return right;
{
GTreeNode *left;
- g_assert (node->version(NOW) == tree->version);
+ g_assert (node->v[0].version == tree->version);
- left = g_tree_node_next_version (tree, node->left(NOW));
+ left = g_tree_node_next_version (tree, node->v[0].left);
- if (left->right(NOW))
+ if (left->v[0].right)
{
- node->v[0].left = g_tree_node_next_version (tree, left->right(NOW));
+ node->v[0].left = g_tree_node_next_version (tree, left->v[0].right);
node->v[0].left->v[0].parent = node;
}
else