1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * GNode: N-way tree implementation.
5 * Copyright (C) 1998 Tim Janik
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
25 * file for a list of people on the GLib Team. See the ChangeLog
26 * files for a list of changes. These files are distributed with
27 * GLib at ftp://ftp.gtk.org/pub/gtk/.
38 #ifndef DISABLE_MEM_POOLS
41 struct _GAllocator /* from gmem.c */
49 GNode *free_nodes; /* implementation specific */
52 G_LOCK_DEFINE_STATIC (current_allocator);
53 static GAllocator *current_allocator = NULL;
55 /* HOLDS: current_allocator_lock */
57 g_node_validate_allocator (GAllocator *allocator)
59 g_return_if_fail (allocator != NULL);
60 g_return_if_fail (allocator->is_unused == TRUE);
62 if (allocator->type != G_ALLOCATOR_NODE)
64 allocator->type = G_ALLOCATOR_NODE;
65 if (allocator->mem_chunk)
67 g_mem_chunk_destroy (allocator->mem_chunk);
68 allocator->mem_chunk = NULL;
72 if (!allocator->mem_chunk)
74 allocator->mem_chunk = g_mem_chunk_new (allocator->name,
76 sizeof (GNode) * allocator->n_preallocs,
78 allocator->free_nodes = NULL;
81 allocator->is_unused = FALSE;
85 g_node_push_allocator (GAllocator *allocator)
87 G_LOCK (current_allocator);
88 g_node_validate_allocator (allocator);
89 allocator->last = current_allocator;
90 current_allocator = allocator;
91 G_UNLOCK (current_allocator);
95 g_node_pop_allocator (void)
97 G_LOCK (current_allocator);
98 if (current_allocator)
100 GAllocator *allocator;
102 allocator = current_allocator;
103 current_allocator = allocator->last;
104 allocator->last = NULL;
105 allocator->is_unused = TRUE;
107 G_UNLOCK (current_allocator);
111 /* --- functions --- */
113 g_node_new (gpointer data)
117 G_LOCK (current_allocator);
118 if (!current_allocator)
120 GAllocator *allocator = g_allocator_new ("GLib default GNode allocator",
122 g_node_validate_allocator (allocator);
123 allocator->last = NULL;
124 current_allocator = allocator;
126 if (!current_allocator->free_nodes)
127 node = g_chunk_new (GNode, current_allocator->mem_chunk);
130 node = current_allocator->free_nodes;
131 current_allocator->free_nodes = node->next;
133 G_UNLOCK (current_allocator);
139 node->children = NULL;
145 g_nodes_free (GNode *node)
152 if (parent->children)
153 g_nodes_free (parent->children);
155 #ifdef ENABLE_GC_FRIENDLY
158 parent->parent = NULL;
159 parent->children = NULL;
160 #endif /* ENABLE_GC_FRIENDLY */
163 parent = parent->next;
168 G_LOCK (current_allocator);
169 parent->next = current_allocator->free_nodes;
170 current_allocator->free_nodes = node;
171 G_UNLOCK (current_allocator);
173 #else /* DISABLE_MEM_POOLS */
176 g_node_new (gpointer data)
180 node = g_new0 (GNode, 1);
188 g_nodes_free (GNode *root)
196 g_nodes_free (node->children);
204 g_node_destroy (GNode *root)
206 g_return_if_fail (root != NULL);
208 if (!G_NODE_IS_ROOT (root))
209 g_node_unlink (root);
215 g_node_unlink (GNode *node)
217 g_return_if_fail (node != NULL);
220 node->prev->next = node->next;
221 else if (node->parent)
222 node->parent->children = node->next;
226 node->next->prev = node->prev;
235 * @copy_func: the function which is called to copy the data inside each node,
236 * or %NULL to use the original data.
237 * @data: data to pass to @copy_func
239 * Recursively copies a #GNode and its data.
241 * Return value: a new #GNode containing copies of the data in @node.
246 g_node_copy_deep (GNode *node,
250 GNode *new_node = NULL;
252 if (copy_func == NULL)
253 return g_node_copy (node);
257 GNode *child, *new_child;
259 new_node = g_node_new (copy_func (node->data, data));
261 for (child = g_node_last_child (node); child; child = child->prev)
263 new_child = g_node_copy_deep (child, copy_func, data);
264 g_node_prepend (new_node, new_child);
272 g_node_copy (GNode *node)
274 GNode *new_node = NULL;
280 new_node = g_node_new (node->data);
282 for (child = g_node_last_child (node); child; child = child->prev)
283 g_node_prepend (new_node, g_node_copy (child));
290 g_node_insert (GNode *parent,
294 g_return_val_if_fail (parent != NULL, node);
295 g_return_val_if_fail (node != NULL, node);
296 g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
299 return g_node_insert_before (parent,
300 g_node_nth_child (parent, position),
302 else if (position == 0)
303 return g_node_prepend (parent, node);
304 else /* if (position < 0) */
305 return g_node_append (parent, node);
309 g_node_insert_before (GNode *parent,
313 g_return_val_if_fail (parent != NULL, node);
314 g_return_val_if_fail (node != NULL, node);
315 g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
317 g_return_val_if_fail (sibling->parent == parent, node);
319 node->parent = parent;
325 node->prev = sibling->prev;
326 node->prev->next = node;
327 node->next = sibling;
328 sibling->prev = node;
332 node->parent->children = node;
333 node->next = sibling;
334 sibling->prev = node;
339 if (parent->children)
341 sibling = parent->children;
342 while (sibling->next)
343 sibling = sibling->next;
344 node->prev = sibling;
345 sibling->next = node;
348 node->parent->children = node;
355 g_node_insert_after (GNode *parent,
359 g_return_val_if_fail (parent != NULL, node);
360 g_return_val_if_fail (node != NULL, node);
361 g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
363 g_return_val_if_fail (sibling->parent == parent, node);
365 node->parent = parent;
371 sibling->next->prev = node;
373 node->next = sibling->next;
374 node->prev = sibling;
375 sibling->next = node;
379 if (parent->children)
381 node->next = parent->children;
382 parent->children->prev = node;
384 parent->children = node;
391 g_node_prepend (GNode *parent,
394 g_return_val_if_fail (parent != NULL, node);
396 return g_node_insert_before (parent, parent->children, node);
400 g_node_get_root (GNode *node)
402 g_return_val_if_fail (node != NULL, NULL);
411 g_node_is_ancestor (GNode *node,
414 g_return_val_if_fail (node != NULL, FALSE);
415 g_return_val_if_fail (descendant != NULL, FALSE);
419 if (descendant->parent == node)
422 descendant = descendant->parent;
428 /* returns 1 for root, 2 for first level children,
429 * 3 for children's children...
432 g_node_depth (GNode *node)
434 register guint depth = 0;
446 g_node_reverse_children (GNode *node)
451 g_return_if_fail (node != NULL);
453 child = node->children;
459 last->next = last->prev;
462 node->children = last;
466 g_node_max_height (GNode *root)
468 register GNode *child;
469 register guint max_height = 0;
474 child = root->children;
477 register guint tmp_height;
479 tmp_height = g_node_max_height (child);
480 if (tmp_height > max_height)
481 max_height = tmp_height;
485 return max_height + 1;
489 g_node_traverse_pre_order (GNode *node,
490 GTraverseFlags flags,
491 GNodeTraverseFunc func,
498 if ((flags & G_TRAVERSE_NON_LEAFS) &&
502 child = node->children;
505 register GNode *current;
508 child = current->next;
509 if (g_node_traverse_pre_order (current, flags, func, data))
513 else if ((flags & G_TRAVERSE_LEAFS) &&
521 g_node_depth_traverse_pre_order (GNode *node,
522 GTraverseFlags flags,
524 GNodeTraverseFunc func,
531 if ((flags & G_TRAVERSE_NON_LEAFS) &&
539 child = node->children;
542 register GNode *current;
545 child = current->next;
546 if (g_node_depth_traverse_pre_order (current, flags, depth, func, data))
550 else if ((flags & G_TRAVERSE_LEAFS) &&
558 g_node_traverse_post_order (GNode *node,
559 GTraverseFlags flags,
560 GNodeTraverseFunc func,
567 child = node->children;
570 register GNode *current;
573 child = current->next;
574 if (g_node_traverse_post_order (current, flags, func, data))
578 if ((flags & G_TRAVERSE_NON_LEAFS) &&
583 else if ((flags & G_TRAVERSE_LEAFS) &&
591 g_node_depth_traverse_post_order (GNode *node,
592 GTraverseFlags flags,
594 GNodeTraverseFunc func,
604 child = node->children;
607 register GNode *current;
610 child = current->next;
611 if (g_node_depth_traverse_post_order (current, flags, depth, func, data))
616 if ((flags & G_TRAVERSE_NON_LEAFS) &&
621 else if ((flags & G_TRAVERSE_LEAFS) &&
629 g_node_traverse_in_order (GNode *node,
630 GTraverseFlags flags,
631 GNodeTraverseFunc func,
637 register GNode *current;
639 child = node->children;
641 child = current->next;
643 if (g_node_traverse_in_order (current, flags, func, data))
646 if ((flags & G_TRAVERSE_NON_LEAFS) &&
653 child = current->next;
654 if (g_node_traverse_in_order (current, flags, func, data))
658 else if ((flags & G_TRAVERSE_LEAFS) &&
666 g_node_depth_traverse_in_order (GNode *node,
667 GTraverseFlags flags,
669 GNodeTraverseFunc func,
678 register GNode *current;
680 child = node->children;
682 child = current->next;
684 if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
687 if ((flags & G_TRAVERSE_NON_LEAFS) &&
694 child = current->next;
695 if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
699 else if ((flags & G_TRAVERSE_NON_LEAFS) &&
703 else if ((flags & G_TRAVERSE_LEAFS) &&
711 g_node_traverse_level (GNode *node,
712 GTraverseFlags flags,
714 GNodeTraverseFunc func,
716 gboolean *more_levels)
723 return (flags & G_TRAVERSE_NON_LEAFS) && func (node, data);
727 return (flags & G_TRAVERSE_LEAFS) && func (node, data);
732 node = node->children;
736 if (g_node_traverse_level (node, flags, level - 1, func, data, more_levels))
747 g_node_depth_traverse_level (GNode *node,
748 GTraverseFlags flags,
750 GNodeTraverseFunc func,
754 gboolean more_levels;
757 while (level != depth)
760 if (g_node_traverse_level (node, flags, level, func, data, &more_levels))
770 g_node_traverse (GNode *root,
772 GTraverseFlags flags,
774 GNodeTraverseFunc func,
777 g_return_if_fail (root != NULL);
778 g_return_if_fail (func != NULL);
779 g_return_if_fail (order <= G_LEVEL_ORDER);
780 g_return_if_fail (flags <= G_TRAVERSE_MASK);
781 g_return_if_fail (depth == -1 || depth > 0);
787 g_node_traverse_pre_order (root, flags, func, data);
789 g_node_depth_traverse_pre_order (root, flags, depth, func, data);
793 g_node_traverse_post_order (root, flags, func, data);
795 g_node_depth_traverse_post_order (root, flags, depth, func, data);
799 g_node_traverse_in_order (root, flags, func, data);
801 g_node_depth_traverse_in_order (root, flags, depth, func, data);
804 g_node_depth_traverse_level (root, flags, depth, func, data);
810 g_node_find_func (GNode *node,
813 register gpointer *d = data;
815 if (*d != node->data)
824 g_node_find (GNode *root,
826 GTraverseFlags flags,
831 g_return_val_if_fail (root != NULL, NULL);
832 g_return_val_if_fail (order <= G_LEVEL_ORDER, NULL);
833 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
838 g_node_traverse (root, order, flags, -1, g_node_find_func, d);
844 g_node_count_func (GNode *node,
845 GTraverseFlags flags,
852 if (flags & G_TRAVERSE_NON_LEAFS)
855 child = node->children;
858 g_node_count_func (child, flags, n);
862 else if (flags & G_TRAVERSE_LEAFS)
867 g_node_n_nodes (GNode *root,
868 GTraverseFlags flags)
872 g_return_val_if_fail (root != NULL, 0);
873 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, 0);
875 g_node_count_func (root, flags, &n);
881 g_node_last_child (GNode *node)
883 g_return_val_if_fail (node != NULL, NULL);
885 node = node->children;
894 g_node_nth_child (GNode *node,
897 g_return_val_if_fail (node != NULL, NULL);
899 node = node->children;
901 while ((n-- > 0) && node)
908 g_node_n_children (GNode *node)
912 g_return_val_if_fail (node != NULL, 0);
914 node = node->children;
925 g_node_find_child (GNode *node,
926 GTraverseFlags flags,
929 g_return_val_if_fail (node != NULL, NULL);
930 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
932 node = node->children;
935 if (node->data == data)
937 if (G_NODE_IS_LEAF (node))
939 if (flags & G_TRAVERSE_LEAFS)
944 if (flags & G_TRAVERSE_NON_LEAFS)
955 g_node_child_position (GNode *node,
958 register guint n = 0;
960 g_return_val_if_fail (node != NULL, -1);
961 g_return_val_if_fail (child != NULL, -1);
962 g_return_val_if_fail (child->parent == node, -1);
964 node = node->children;
977 g_node_child_index (GNode *node,
980 register guint n = 0;
982 g_return_val_if_fail (node != NULL, -1);
984 node = node->children;
987 if (node->data == data)
997 g_node_first_sibling (GNode *node)
999 g_return_val_if_fail (node != NULL, NULL);
1002 return node->parent->children;
1011 g_node_last_sibling (GNode *node)
1013 g_return_val_if_fail (node != NULL, NULL);
1022 g_node_children_foreach (GNode *node,
1023 GTraverseFlags flags,
1024 GNodeForeachFunc func,
1027 g_return_if_fail (node != NULL);
1028 g_return_if_fail (flags <= G_TRAVERSE_MASK);
1029 g_return_if_fail (func != NULL);
1031 node = node->children;
1034 register GNode *current;
1037 node = current->next;
1038 if (G_NODE_IS_LEAF (current))
1040 if (flags & G_TRAVERSE_LEAFS)
1041 func (current, data);
1045 if (flags & G_TRAVERSE_NON_LEAFS)
1046 func (current, data);