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.
24 * Modified by the GLib Team and others 1997-1999. 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 parent = parent->next;
157 G_LOCK (current_allocator);
158 parent->next = current_allocator->free_nodes;
159 current_allocator->free_nodes = node;
160 G_UNLOCK (current_allocator);
164 g_node_destroy (GNode *root)
166 g_return_if_fail (root != NULL);
168 if (!G_NODE_IS_ROOT (root))
169 g_node_unlink (root);
175 g_node_unlink (GNode *node)
177 g_return_if_fail (node != NULL);
180 node->prev->next = node->next;
181 else if (node->parent)
182 node->parent->children = node->next;
186 node->next->prev = node->prev;
193 g_node_copy (GNode *node)
195 GNode *new_node = NULL;
201 new_node = g_node_new (node->data);
203 for (child = g_node_last_child (node); child; child = child->prev)
204 g_node_prepend (new_node, g_node_copy (child));
211 g_node_insert (GNode *parent,
215 g_return_val_if_fail (parent != NULL, node);
216 g_return_val_if_fail (node != NULL, node);
217 g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
220 return g_node_insert_before (parent,
221 g_node_nth_child (parent, position),
223 else if (position == 0)
224 return g_node_prepend (parent, node);
225 else /* if (position < 0) */
226 return g_node_append (parent, node);
230 g_node_insert_before (GNode *parent,
234 g_return_val_if_fail (parent != NULL, node);
235 g_return_val_if_fail (node != NULL, node);
236 g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
238 g_return_val_if_fail (sibling->parent == parent, node);
240 node->parent = parent;
246 node->prev = sibling->prev;
247 node->prev->next = node;
248 node->next = sibling;
249 sibling->prev = node;
253 node->parent->children = node;
254 node->next = sibling;
255 sibling->prev = node;
260 if (parent->children)
262 sibling = parent->children;
263 while (sibling->next)
264 sibling = sibling->next;
265 node->prev = sibling;
266 sibling->next = node;
269 node->parent->children = node;
276 g_node_prepend (GNode *parent,
279 g_return_val_if_fail (parent != NULL, node);
281 return g_node_insert_before (parent, parent->children, node);
285 g_node_get_root (GNode *node)
287 g_return_val_if_fail (node != NULL, NULL);
296 g_node_is_ancestor (GNode *node,
299 g_return_val_if_fail (node != NULL, FALSE);
300 g_return_val_if_fail (descendant != NULL, FALSE);
304 if (descendant->parent == node)
307 descendant = descendant->parent;
313 /* returns 1 for root, 2 for first level children,
314 * 3 for children's children...
317 g_node_depth (GNode *node)
319 register guint depth = 0;
331 g_node_reverse_children (GNode *node)
336 g_return_if_fail (node != NULL);
338 child = node->children;
344 last->next = last->prev;
347 node->children = last;
351 g_node_max_height (GNode *root)
353 register GNode *child;
354 register guint max_height = 0;
359 child = root->children;
362 register guint tmp_height;
364 tmp_height = g_node_max_height (child);
365 if (tmp_height > max_height)
366 max_height = tmp_height;
370 return max_height + 1;
374 g_node_traverse_pre_order (GNode *node,
375 GTraverseFlags flags,
376 GNodeTraverseFunc func,
383 if ((flags & G_TRAVERSE_NON_LEAFS) &&
387 child = node->children;
390 register GNode *current;
393 child = current->next;
394 if (g_node_traverse_pre_order (current, flags, func, data))
398 else if ((flags & G_TRAVERSE_LEAFS) &&
406 g_node_depth_traverse_pre_order (GNode *node,
407 GTraverseFlags flags,
409 GNodeTraverseFunc func,
416 if ((flags & G_TRAVERSE_NON_LEAFS) &&
424 child = node->children;
427 register GNode *current;
430 child = current->next;
431 if (g_node_depth_traverse_pre_order (current, flags, depth, func, data))
435 else if ((flags & G_TRAVERSE_LEAFS) &&
443 g_node_traverse_post_order (GNode *node,
444 GTraverseFlags flags,
445 GNodeTraverseFunc func,
452 child = node->children;
455 register GNode *current;
458 child = current->next;
459 if (g_node_traverse_post_order (current, flags, func, data))
463 if ((flags & G_TRAVERSE_NON_LEAFS) &&
468 else if ((flags & G_TRAVERSE_LEAFS) &&
476 g_node_depth_traverse_post_order (GNode *node,
477 GTraverseFlags flags,
479 GNodeTraverseFunc func,
489 child = node->children;
492 register GNode *current;
495 child = current->next;
496 if (g_node_depth_traverse_post_order (current, flags, depth, func, data))
501 if ((flags & G_TRAVERSE_NON_LEAFS) &&
506 else if ((flags & G_TRAVERSE_LEAFS) &&
514 g_node_traverse_in_order (GNode *node,
515 GTraverseFlags flags,
516 GNodeTraverseFunc func,
522 register GNode *current;
524 child = node->children;
526 child = current->next;
528 if (g_node_traverse_in_order (current, flags, func, data))
531 if ((flags & G_TRAVERSE_NON_LEAFS) &&
538 child = current->next;
539 if (g_node_traverse_in_order (current, flags, func, data))
543 else if ((flags & G_TRAVERSE_LEAFS) &&
551 g_node_depth_traverse_in_order (GNode *node,
552 GTraverseFlags flags,
554 GNodeTraverseFunc func,
563 register GNode *current;
565 child = node->children;
567 child = current->next;
569 if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
572 if ((flags & G_TRAVERSE_NON_LEAFS) &&
579 child = current->next;
580 if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
584 else if ((flags & G_TRAVERSE_NON_LEAFS) &&
588 else if ((flags & G_TRAVERSE_LEAFS) &&
596 g_node_traverse_children (GNode *node,
597 GTraverseFlags flags,
598 GNodeTraverseFunc func,
603 child = node->children;
607 register GNode *current;
610 child = current->next;
612 if (current->children)
614 if ((flags & G_TRAVERSE_NON_LEAFS) &&
615 func (current, data))
618 else if ((flags & G_TRAVERSE_LEAFS) &&
619 func (current, data))
623 child = node->children;
627 register GNode *current;
630 child = current->next;
632 if (current->children &&
633 g_node_traverse_children (current, flags, func, data))
641 g_node_depth_traverse_children (GNode *node,
642 GTraverseFlags flags,
644 GNodeTraverseFunc func,
649 child = node->children;
653 register GNode *current;
656 child = current->next;
658 if (current->children)
660 if ((flags & G_TRAVERSE_NON_LEAFS) &&
661 func (current, data))
664 else if ((flags & G_TRAVERSE_LEAFS) &&
665 func (current, data))
673 child = node->children;
677 register GNode *current;
680 child = current->next;
682 if (current->children &&
683 g_node_depth_traverse_children (current, flags, depth, func, data))
691 g_node_traverse (GNode *root,
693 GTraverseFlags flags,
695 GNodeTraverseFunc func,
698 g_return_if_fail (root != NULL);
699 g_return_if_fail (func != NULL);
700 g_return_if_fail (order <= G_LEVEL_ORDER);
701 g_return_if_fail (flags <= G_TRAVERSE_MASK);
702 g_return_if_fail (depth == -1 || depth > 0);
708 g_node_traverse_pre_order (root, flags, func, data);
710 g_node_depth_traverse_pre_order (root, flags, depth, func, data);
714 g_node_traverse_post_order (root, flags, func, data);
716 g_node_depth_traverse_post_order (root, flags, depth, func, data);
720 g_node_traverse_in_order (root, flags, func, data);
722 g_node_depth_traverse_in_order (root, flags, depth, func, data);
727 if (!((flags & G_TRAVERSE_NON_LEAFS) &&
731 g_node_traverse_children (root, flags, func, data);
736 g_node_depth_traverse_children (root, flags, depth, func, data);
740 else if (flags & G_TRAVERSE_LEAFS)
747 g_node_find_func (GNode *node,
750 register gpointer *d = data;
752 if (*d != node->data)
761 g_node_find (GNode *root,
763 GTraverseFlags flags,
768 g_return_val_if_fail (root != NULL, NULL);
769 g_return_val_if_fail (order <= G_LEVEL_ORDER, NULL);
770 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
775 g_node_traverse (root, order, flags, -1, g_node_find_func, d);
781 g_node_count_func (GNode *node,
782 GTraverseFlags flags,
789 if (flags & G_TRAVERSE_NON_LEAFS)
792 child = node->children;
795 g_node_count_func (child, flags, n);
799 else if (flags & G_TRAVERSE_LEAFS)
804 g_node_n_nodes (GNode *root,
805 GTraverseFlags flags)
809 g_return_val_if_fail (root != NULL, 0);
810 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, 0);
812 g_node_count_func (root, flags, &n);
818 g_node_last_child (GNode *node)
820 g_return_val_if_fail (node != NULL, NULL);
822 node = node->children;
831 g_node_nth_child (GNode *node,
834 g_return_val_if_fail (node != NULL, NULL);
836 node = node->children;
838 while ((n-- > 0) && node)
845 g_node_n_children (GNode *node)
849 g_return_val_if_fail (node != NULL, 0);
851 node = node->children;
862 g_node_find_child (GNode *node,
863 GTraverseFlags flags,
866 g_return_val_if_fail (node != NULL, NULL);
867 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
869 node = node->children;
872 if (node->data == data)
874 if (G_NODE_IS_LEAF (node))
876 if (flags & G_TRAVERSE_LEAFS)
881 if (flags & G_TRAVERSE_NON_LEAFS)
892 g_node_child_position (GNode *node,
895 register guint n = 0;
897 g_return_val_if_fail (node != NULL, -1);
898 g_return_val_if_fail (child != NULL, -1);
899 g_return_val_if_fail (child->parent == node, -1);
901 node = node->children;
914 g_node_child_index (GNode *node,
917 register guint n = 0;
919 g_return_val_if_fail (node != NULL, -1);
921 node = node->children;
924 if (node->data == data)
934 g_node_first_sibling (GNode *node)
936 g_return_val_if_fail (node != NULL, NULL);
939 return node->parent->children;
948 g_node_last_sibling (GNode *node)
950 g_return_val_if_fail (node != NULL, NULL);
959 g_node_children_foreach (GNode *node,
960 GTraverseFlags flags,
961 GNodeForeachFunc func,
964 g_return_if_fail (node != NULL);
965 g_return_if_fail (flags <= G_TRAVERSE_MASK);
966 g_return_if_fail (func != NULL);
968 node = node->children;
971 register GNode *current;
974 node = current->next;
975 if (G_NODE_IS_LEAF (current))
977 if (flags & G_TRAVERSE_LEAFS)
978 func (current, data);
982 if (flags & G_TRAVERSE_NON_LEAFS)
983 func (current, data);