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 struct _GAllocator /* from gmem.c */
46 GNode *free_nodes; /* implementation specific */
49 G_LOCK_DEFINE_STATIC (current_allocator);
50 static GAllocator *current_allocator = NULL;
52 /* HOLDS: current_allocator_lock */
54 g_node_validate_allocator (GAllocator *allocator)
56 g_return_if_fail (allocator != NULL);
57 g_return_if_fail (allocator->is_unused == TRUE);
59 if (allocator->type != G_ALLOCATOR_NODE)
61 allocator->type = G_ALLOCATOR_NODE;
62 if (allocator->mem_chunk)
64 g_mem_chunk_destroy (allocator->mem_chunk);
65 allocator->mem_chunk = NULL;
69 if (!allocator->mem_chunk)
71 allocator->mem_chunk = g_mem_chunk_new (allocator->name,
73 sizeof (GNode) * allocator->n_preallocs,
75 allocator->free_nodes = NULL;
78 allocator->is_unused = FALSE;
82 g_node_push_allocator (GAllocator *allocator)
84 G_LOCK (current_allocator);
85 g_node_validate_allocator (allocator);
86 allocator->last = current_allocator;
87 current_allocator = allocator;
88 G_UNLOCK (current_allocator);
92 g_node_pop_allocator (void)
94 G_LOCK (current_allocator);
95 if (current_allocator)
97 GAllocator *allocator;
99 allocator = current_allocator;
100 current_allocator = allocator->last;
101 allocator->last = NULL;
102 allocator->is_unused = TRUE;
104 G_UNLOCK (current_allocator);
108 /* --- functions --- */
110 g_node_new (gpointer data)
114 G_LOCK (current_allocator);
115 if (!current_allocator)
117 GAllocator *allocator = g_allocator_new ("GLib default GNode allocator",
119 g_node_validate_allocator (allocator);
120 allocator->last = NULL;
121 current_allocator = allocator;
123 if (!current_allocator->free_nodes)
124 node = g_chunk_new (GNode, current_allocator->mem_chunk);
127 node = current_allocator->free_nodes;
128 current_allocator->free_nodes = node->next;
130 G_UNLOCK (current_allocator);
136 node->children = NULL;
142 g_nodes_free (GNode *node)
149 if (parent->children)
150 g_nodes_free (parent->children);
152 #ifdef ENABLE_GC_FRIENDLY
155 parent->parent = NULL;
156 parent->children = NULL;
157 #endif /* ENABLE_GC_FRIENDLY */
160 parent = parent->next;
165 G_LOCK (current_allocator);
166 parent->next = current_allocator->free_nodes;
167 current_allocator->free_nodes = node;
168 G_UNLOCK (current_allocator);
172 g_node_destroy (GNode *root)
174 g_return_if_fail (root != NULL);
176 if (!G_NODE_IS_ROOT (root))
177 g_node_unlink (root);
183 g_node_unlink (GNode *node)
185 g_return_if_fail (node != NULL);
188 node->prev->next = node->next;
189 else if (node->parent)
190 node->parent->children = node->next;
194 node->next->prev = node->prev;
201 g_node_copy (GNode *node)
203 GNode *new_node = NULL;
209 new_node = g_node_new (node->data);
211 for (child = g_node_last_child (node); child; child = child->prev)
212 g_node_prepend (new_node, g_node_copy (child));
219 g_node_insert (GNode *parent,
223 g_return_val_if_fail (parent != NULL, node);
224 g_return_val_if_fail (node != NULL, node);
225 g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
228 return g_node_insert_before (parent,
229 g_node_nth_child (parent, position),
231 else if (position == 0)
232 return g_node_prepend (parent, node);
233 else /* if (position < 0) */
234 return g_node_append (parent, node);
238 g_node_insert_before (GNode *parent,
242 g_return_val_if_fail (parent != NULL, node);
243 g_return_val_if_fail (node != NULL, node);
244 g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
246 g_return_val_if_fail (sibling->parent == parent, node);
248 node->parent = parent;
254 node->prev = sibling->prev;
255 node->prev->next = node;
256 node->next = sibling;
257 sibling->prev = node;
261 node->parent->children = node;
262 node->next = sibling;
263 sibling->prev = node;
268 if (parent->children)
270 sibling = parent->children;
271 while (sibling->next)
272 sibling = sibling->next;
273 node->prev = sibling;
274 sibling->next = node;
277 node->parent->children = node;
284 g_node_prepend (GNode *parent,
287 g_return_val_if_fail (parent != NULL, node);
289 return g_node_insert_before (parent, parent->children, node);
293 g_node_get_root (GNode *node)
295 g_return_val_if_fail (node != NULL, NULL);
304 g_node_is_ancestor (GNode *node,
307 g_return_val_if_fail (node != NULL, FALSE);
308 g_return_val_if_fail (descendant != NULL, FALSE);
312 if (descendant->parent == node)
315 descendant = descendant->parent;
321 /* returns 1 for root, 2 for first level children,
322 * 3 for children's children...
325 g_node_depth (GNode *node)
327 register guint depth = 0;
339 g_node_reverse_children (GNode *node)
344 g_return_if_fail (node != NULL);
346 child = node->children;
352 last->next = last->prev;
355 node->children = last;
359 g_node_max_height (GNode *root)
361 register GNode *child;
362 register guint max_height = 0;
367 child = root->children;
370 register guint tmp_height;
372 tmp_height = g_node_max_height (child);
373 if (tmp_height > max_height)
374 max_height = tmp_height;
378 return max_height + 1;
382 g_node_traverse_pre_order (GNode *node,
383 GTraverseFlags flags,
384 GNodeTraverseFunc func,
391 if ((flags & G_TRAVERSE_NON_LEAFS) &&
395 child = node->children;
398 register GNode *current;
401 child = current->next;
402 if (g_node_traverse_pre_order (current, flags, func, data))
406 else if ((flags & G_TRAVERSE_LEAFS) &&
414 g_node_depth_traverse_pre_order (GNode *node,
415 GTraverseFlags flags,
417 GNodeTraverseFunc func,
424 if ((flags & G_TRAVERSE_NON_LEAFS) &&
432 child = node->children;
435 register GNode *current;
438 child = current->next;
439 if (g_node_depth_traverse_pre_order (current, flags, depth, func, data))
443 else if ((flags & G_TRAVERSE_LEAFS) &&
451 g_node_traverse_post_order (GNode *node,
452 GTraverseFlags flags,
453 GNodeTraverseFunc func,
460 child = node->children;
463 register GNode *current;
466 child = current->next;
467 if (g_node_traverse_post_order (current, flags, func, data))
471 if ((flags & G_TRAVERSE_NON_LEAFS) &&
476 else if ((flags & G_TRAVERSE_LEAFS) &&
484 g_node_depth_traverse_post_order (GNode *node,
485 GTraverseFlags flags,
487 GNodeTraverseFunc func,
497 child = node->children;
500 register GNode *current;
503 child = current->next;
504 if (g_node_depth_traverse_post_order (current, flags, depth, func, data))
509 if ((flags & G_TRAVERSE_NON_LEAFS) &&
514 else if ((flags & G_TRAVERSE_LEAFS) &&
522 g_node_traverse_in_order (GNode *node,
523 GTraverseFlags flags,
524 GNodeTraverseFunc func,
530 register GNode *current;
532 child = node->children;
534 child = current->next;
536 if (g_node_traverse_in_order (current, flags, func, data))
539 if ((flags & G_TRAVERSE_NON_LEAFS) &&
546 child = current->next;
547 if (g_node_traverse_in_order (current, flags, func, data))
551 else if ((flags & G_TRAVERSE_LEAFS) &&
559 g_node_depth_traverse_in_order (GNode *node,
560 GTraverseFlags flags,
562 GNodeTraverseFunc func,
571 register GNode *current;
573 child = node->children;
575 child = current->next;
577 if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
580 if ((flags & G_TRAVERSE_NON_LEAFS) &&
587 child = current->next;
588 if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
592 else if ((flags & G_TRAVERSE_NON_LEAFS) &&
596 else if ((flags & G_TRAVERSE_LEAFS) &&
604 g_node_traverse_children (GNode *node,
605 GTraverseFlags flags,
606 GNodeTraverseFunc func,
611 child = node->children;
615 register GNode *current;
618 child = current->next;
620 if (current->children)
622 if ((flags & G_TRAVERSE_NON_LEAFS) &&
623 func (current, data))
626 else if ((flags & G_TRAVERSE_LEAFS) &&
627 func (current, data))
631 child = node->children;
635 register GNode *current;
638 child = current->next;
640 if (current->children &&
641 g_node_traverse_children (current, flags, func, data))
649 g_node_depth_traverse_children (GNode *node,
650 GTraverseFlags flags,
652 GNodeTraverseFunc func,
657 child = node->children;
661 register GNode *current;
664 child = current->next;
666 if (current->children)
668 if ((flags & G_TRAVERSE_NON_LEAFS) &&
669 func (current, data))
672 else if ((flags & G_TRAVERSE_LEAFS) &&
673 func (current, data))
681 child = node->children;
685 register GNode *current;
688 child = current->next;
690 if (current->children &&
691 g_node_depth_traverse_children (current, flags, depth, func, data))
699 g_node_traverse (GNode *root,
701 GTraverseFlags flags,
703 GNodeTraverseFunc func,
706 g_return_if_fail (root != NULL);
707 g_return_if_fail (func != NULL);
708 g_return_if_fail (order <= G_LEVEL_ORDER);
709 g_return_if_fail (flags <= G_TRAVERSE_MASK);
710 g_return_if_fail (depth == -1 || depth > 0);
716 g_node_traverse_pre_order (root, flags, func, data);
718 g_node_depth_traverse_pre_order (root, flags, depth, func, data);
722 g_node_traverse_post_order (root, flags, func, data);
724 g_node_depth_traverse_post_order (root, flags, depth, func, data);
728 g_node_traverse_in_order (root, flags, func, data);
730 g_node_depth_traverse_in_order (root, flags, depth, func, data);
735 if (!((flags & G_TRAVERSE_NON_LEAFS) &&
739 g_node_traverse_children (root, flags, func, data);
744 g_node_depth_traverse_children (root, flags, depth, func, data);
748 else if (flags & G_TRAVERSE_LEAFS)
755 g_node_find_func (GNode *node,
758 register gpointer *d = data;
760 if (*d != node->data)
769 g_node_find (GNode *root,
771 GTraverseFlags flags,
776 g_return_val_if_fail (root != NULL, NULL);
777 g_return_val_if_fail (order <= G_LEVEL_ORDER, NULL);
778 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
783 g_node_traverse (root, order, flags, -1, g_node_find_func, d);
789 g_node_count_func (GNode *node,
790 GTraverseFlags flags,
797 if (flags & G_TRAVERSE_NON_LEAFS)
800 child = node->children;
803 g_node_count_func (child, flags, n);
807 else if (flags & G_TRAVERSE_LEAFS)
812 g_node_n_nodes (GNode *root,
813 GTraverseFlags flags)
817 g_return_val_if_fail (root != NULL, 0);
818 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, 0);
820 g_node_count_func (root, flags, &n);
826 g_node_last_child (GNode *node)
828 g_return_val_if_fail (node != NULL, NULL);
830 node = node->children;
839 g_node_nth_child (GNode *node,
842 g_return_val_if_fail (node != NULL, NULL);
844 node = node->children;
846 while ((n-- > 0) && node)
853 g_node_n_children (GNode *node)
857 g_return_val_if_fail (node != NULL, 0);
859 node = node->children;
870 g_node_find_child (GNode *node,
871 GTraverseFlags flags,
874 g_return_val_if_fail (node != NULL, NULL);
875 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
877 node = node->children;
880 if (node->data == data)
882 if (G_NODE_IS_LEAF (node))
884 if (flags & G_TRAVERSE_LEAFS)
889 if (flags & G_TRAVERSE_NON_LEAFS)
900 g_node_child_position (GNode *node,
903 register guint n = 0;
905 g_return_val_if_fail (node != NULL, -1);
906 g_return_val_if_fail (child != NULL, -1);
907 g_return_val_if_fail (child->parent == node, -1);
909 node = node->children;
922 g_node_child_index (GNode *node,
925 register guint n = 0;
927 g_return_val_if_fail (node != NULL, -1);
929 node = node->children;
932 if (node->data == data)
942 g_node_first_sibling (GNode *node)
944 g_return_val_if_fail (node != NULL, NULL);
947 return node->parent->children;
956 g_node_last_sibling (GNode *node)
958 g_return_val_if_fail (node != NULL, NULL);
967 g_node_children_foreach (GNode *node,
968 GTraverseFlags flags,
969 GNodeForeachFunc func,
972 g_return_if_fail (node != NULL);
973 g_return_if_fail (flags <= G_TRAVERSE_MASK);
974 g_return_if_fail (func != NULL);
976 node = node->children;
979 register GNode *current;
982 node = current->next;
983 if (G_NODE_IS_LEAF (current))
985 if (flags & G_TRAVERSE_LEAFS)
986 func (current, data);
990 if (flags & G_TRAVERSE_NON_LEAFS)
991 func (current, data);