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 Library 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 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library 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.
26 struct _GAllocator /* from gmem.c */
34 GNode *free_nodes; /* implementation specific */
37 static GAllocator *current_allocator = NULL;
40 g_node_push_allocator (GAllocator *allocator)
42 g_return_if_fail (allocator != NULL);
43 g_return_if_fail (allocator->is_unused == TRUE);
45 if (allocator->type != G_ALLOCATOR_NODE)
47 allocator->type = G_ALLOCATOR_NODE;
48 if (allocator->mem_chunk)
50 g_mem_chunk_destroy (allocator->mem_chunk);
51 allocator->mem_chunk = NULL;
55 if (!allocator->mem_chunk)
57 allocator->mem_chunk = g_mem_chunk_new (allocator->name,
59 sizeof (GNode) * allocator->n_preallocs,
61 allocator->free_nodes = NULL;
64 allocator->is_unused = FALSE;
65 allocator->last = current_allocator;
66 current_allocator = allocator;
70 g_node_pop_allocator (void)
72 if (current_allocator)
74 GAllocator *allocator;
76 allocator = current_allocator;
77 current_allocator = allocator->last;
78 allocator->last = NULL;
79 allocator->is_unused = TRUE;
84 /* --- functions --- */
86 g_node_new (gpointer data)
90 if (!current_allocator)
91 g_node_push_allocator (g_allocator_new ("GLib default GNode allocator", 1024));
93 if (!current_allocator->free_nodes)
94 node = g_chunk_new (GNode, current_allocator->mem_chunk);
97 node = current_allocator->free_nodes;
98 current_allocator->free_nodes = node->next;
105 node->children = NULL;
111 g_nodes_free (GNode *node)
118 if (parent->children)
119 g_nodes_free (parent->children);
121 parent = parent->next;
126 parent->next = current_allocator->free_nodes;
127 current_allocator->free_nodes = node;
131 g_node_destroy (GNode *root)
133 g_return_if_fail (root != NULL);
135 if (!G_NODE_IS_ROOT (root))
136 g_node_unlink (root);
142 g_node_unlink (GNode *node)
144 g_return_if_fail (node != NULL);
147 node->prev->next = node->next;
148 else if (node->parent)
149 node->parent->children = node->next;
153 node->next->prev = node->prev;
160 g_node_insert (GNode *parent,
164 g_return_val_if_fail (parent != NULL, node);
165 g_return_val_if_fail (node != NULL, node);
166 g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
169 return g_node_insert_before (parent,
170 g_node_nth_child (parent, position),
172 else if (position == 0)
173 return g_node_prepend (parent, node);
174 else /* if (position < 0) */
175 return g_node_append (parent, node);
179 g_node_insert_before (GNode *parent,
183 g_return_val_if_fail (parent != NULL, node);
184 g_return_val_if_fail (node != NULL, node);
185 g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
187 g_return_val_if_fail (sibling->parent == parent, node);
189 node->parent = parent;
195 node->prev = sibling->prev;
196 node->prev->next = node;
197 node->next = sibling;
198 sibling->prev = node;
202 node->parent->children = node;
203 node->next = sibling;
204 sibling->prev = node;
209 if (parent->children)
211 sibling = parent->children;
212 while (sibling->next)
213 sibling = sibling->next;
214 node->prev = sibling;
215 sibling->next = node;
218 node->parent->children = node;
225 g_node_prepend (GNode *parent,
228 g_return_val_if_fail (parent != NULL, node);
230 return g_node_insert_before (parent, parent->children, node);
234 g_node_get_root (GNode *node)
236 g_return_val_if_fail (node != NULL, NULL);
245 g_node_is_ancestor (GNode *node,
248 g_return_val_if_fail (node != NULL, FALSE);
249 g_return_val_if_fail (descendant != NULL, FALSE);
253 if (descendant->parent == node)
256 descendant = descendant->parent;
262 /* returns 1 for root, 2 for first level children,
263 * 3 for children's children...
266 g_node_depth (GNode *node)
268 register guint depth = 0;
280 g_node_reverse_children (GNode *node)
285 g_return_if_fail (node != NULL);
287 child = node->children;
293 last->next = last->prev;
296 node->children = last;
300 g_node_max_height (GNode *root)
302 register GNode *child;
303 register guint max_height = 0;
308 child = root->children;
311 register guint tmp_height;
313 tmp_height = g_node_max_height (child);
314 if (tmp_height > max_height)
315 max_height = tmp_height;
319 return max_height + 1;
323 g_node_traverse_pre_order (GNode *node,
324 GTraverseFlags flags,
325 GNodeTraverseFunc func,
332 if ((flags & G_TRAVERSE_NON_LEAFS) &&
336 child = node->children;
339 register GNode *current;
342 child = current->next;
343 if (g_node_traverse_pre_order (current, flags, func, data))
347 else if ((flags & G_TRAVERSE_LEAFS) &&
355 g_node_depth_traverse_pre_order (GNode *node,
356 GTraverseFlags flags,
358 GNodeTraverseFunc func,
365 if ((flags & G_TRAVERSE_NON_LEAFS) &&
373 child = node->children;
376 register GNode *current;
379 child = current->next;
380 if (g_node_depth_traverse_pre_order (current, flags, depth, func, data))
384 else if ((flags & G_TRAVERSE_LEAFS) &&
392 g_node_traverse_post_order (GNode *node,
393 GTraverseFlags flags,
394 GNodeTraverseFunc func,
401 child = node->children;
404 register GNode *current;
407 child = current->next;
408 if (g_node_traverse_post_order (current, flags, func, data))
412 if ((flags & G_TRAVERSE_NON_LEAFS) &&
417 else if ((flags & G_TRAVERSE_LEAFS) &&
425 g_node_depth_traverse_post_order (GNode *node,
426 GTraverseFlags flags,
428 GNodeTraverseFunc func,
438 child = node->children;
441 register GNode *current;
444 child = current->next;
445 if (g_node_depth_traverse_post_order (current, flags, depth, func, data))
450 if ((flags & G_TRAVERSE_NON_LEAFS) &&
455 else if ((flags & G_TRAVERSE_LEAFS) &&
463 g_node_traverse_in_order (GNode *node,
464 GTraverseFlags flags,
465 GNodeTraverseFunc func,
471 register GNode *current;
473 child = node->children;
475 child = current->next;
477 if (g_node_traverse_in_order (current, flags, func, data))
480 if ((flags & G_TRAVERSE_NON_LEAFS) &&
487 child = current->next;
488 if (g_node_traverse_in_order (current, flags, func, data))
492 else if ((flags & G_TRAVERSE_LEAFS) &&
500 g_node_depth_traverse_in_order (GNode *node,
501 GTraverseFlags flags,
503 GNodeTraverseFunc func,
512 register GNode *current;
514 child = node->children;
516 child = current->next;
518 if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
521 if ((flags & G_TRAVERSE_NON_LEAFS) &&
528 child = current->next;
529 if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
533 else if ((flags & G_TRAVERSE_NON_LEAFS) &&
537 else if ((flags & G_TRAVERSE_LEAFS) &&
545 g_node_traverse_children (GNode *node,
546 GTraverseFlags flags,
547 GNodeTraverseFunc func,
552 child = node->children;
556 register GNode *current;
559 child = current->next;
561 if (current->children)
563 if ((flags & G_TRAVERSE_NON_LEAFS) &&
564 func (current, data))
567 else if ((flags & G_TRAVERSE_LEAFS) &&
568 func (current, data))
572 child = node->children;
576 register GNode *current;
579 child = current->next;
581 if (current->children &&
582 g_node_traverse_children (current, flags, func, data))
590 g_node_depth_traverse_children (GNode *node,
591 GTraverseFlags flags,
593 GNodeTraverseFunc func,
598 child = node->children;
602 register GNode *current;
605 child = current->next;
607 if (current->children)
609 if ((flags & G_TRAVERSE_NON_LEAFS) &&
610 func (current, data))
613 else if ((flags & G_TRAVERSE_LEAFS) &&
614 func (current, data))
622 child = node->children;
626 register GNode *current;
629 child = current->next;
631 if (current->children &&
632 g_node_depth_traverse_children (current, flags, depth, func, data))
640 g_node_traverse (GNode *root,
642 GTraverseFlags flags,
644 GNodeTraverseFunc func,
647 g_return_if_fail (root != NULL);
648 g_return_if_fail (func != NULL);
649 g_return_if_fail (order <= G_LEVEL_ORDER);
650 g_return_if_fail (flags <= G_TRAVERSE_MASK);
651 g_return_if_fail (depth == -1 || depth > 0);
657 g_node_traverse_pre_order (root, flags, func, data);
659 g_node_depth_traverse_pre_order (root, flags, depth, func, data);
663 g_node_traverse_post_order (root, flags, func, data);
665 g_node_depth_traverse_post_order (root, flags, depth, func, data);
669 g_node_traverse_in_order (root, flags, func, data);
671 g_node_depth_traverse_in_order (root, flags, depth, func, data);
676 if (!((flags & G_TRAVERSE_NON_LEAFS) &&
680 g_node_traverse_children (root, flags, func, data);
685 g_node_depth_traverse_children (root, flags, depth, func, data);
689 else if (flags & G_TRAVERSE_LEAFS)
696 g_node_find_func (GNode *node,
699 register gpointer *d = data;
701 if (*d != node->data)
710 g_node_find (GNode *root,
712 GTraverseFlags flags,
717 g_return_val_if_fail (root != NULL, NULL);
718 g_return_val_if_fail (order <= G_LEVEL_ORDER, NULL);
719 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
724 g_node_traverse (root, order, flags, -1, g_node_find_func, d);
730 g_node_count_func (GNode *node,
731 GTraverseFlags flags,
738 if (flags & G_TRAVERSE_NON_LEAFS)
741 child = node->children;
744 g_node_count_func (child, flags, n);
748 else if (flags & G_TRAVERSE_LEAFS)
753 g_node_n_nodes (GNode *root,
754 GTraverseFlags flags)
758 g_return_val_if_fail (root != NULL, 0);
759 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, 0);
761 g_node_count_func (root, flags, &n);
767 g_node_last_child (GNode *node)
769 g_return_val_if_fail (node != NULL, NULL);
771 node = node->children;
780 g_node_nth_child (GNode *node,
783 g_return_val_if_fail (node != NULL, NULL);
785 node = node->children;
787 while ((n-- > 0) && node)
794 g_node_n_children (GNode *node)
798 g_return_val_if_fail (node != NULL, 0);
800 node = node->children;
811 g_node_find_child (GNode *node,
812 GTraverseFlags flags,
815 g_return_val_if_fail (node != NULL, NULL);
816 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
818 node = node->children;
821 if (node->data == data)
823 if (G_NODE_IS_LEAF (node))
825 if (flags & G_TRAVERSE_LEAFS)
830 if (flags & G_TRAVERSE_NON_LEAFS)
841 g_node_child_position (GNode *node,
844 register guint n = 0;
846 g_return_val_if_fail (node != NULL, -1);
847 g_return_val_if_fail (child != NULL, -1);
848 g_return_val_if_fail (child->parent == node, -1);
850 node = node->children;
863 g_node_child_index (GNode *node,
866 register guint n = 0;
868 g_return_val_if_fail (node != NULL, -1);
870 node = node->children;
873 if (node->data == data)
883 g_node_first_sibling (GNode *node)
885 g_return_val_if_fail (node != NULL, NULL);
894 g_node_last_sibling (GNode *node)
896 g_return_val_if_fail (node != NULL, NULL);
905 g_node_children_foreach (GNode *node,
906 GTraverseFlags flags,
907 GNodeForeachFunc func,
910 g_return_if_fail (node != NULL);
911 g_return_if_fail (flags <= G_TRAVERSE_MASK);
912 g_return_if_fail (func != NULL);
914 node = node->children;
917 register GNode *current;
920 node = current->next;
921 if (G_NODE_IS_LEAF (current))
923 if (flags & G_TRAVERSE_LEAFS)
924 func (current, data);
928 if (flags & G_TRAVERSE_NON_LEAFS)
929 func (current, data);