mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 22:16:16 +01:00
fixed a typo in a comment.
2001-05-04 Sven Neumann <sven@convergence.de> * ghash.c: fixed a typo in a comment. * gtree.[ch]: added new functions g_tree_new_full(), g_tree_replace(), g_tree_steal() and g_tree_foreach() to adapt GTree to the GHashTable API. Moved comments into the C file. * docs/reference/glib/glib-sections.txt * docs/reference/glib/tmpl/glib-unused.sgml * docs/reference/glib/tmpl/hash_tables.sgml * docs/reference/glib/tmpl/linked_lists_double.sgml * docs/reference/glib/tmpl/linked_lists_single.sgml * docs/reference/glib/tmpl/macros_misc.sgml * docs/reference/glib/tmpl/trees-binary.sgml: updated documentation
This commit is contained in:
parent
0402b625ee
commit
d18b364dd7
16
ChangeLog
16
ChangeLog
@ -1,3 +1,19 @@
|
||||
2001-05-04 Sven Neumann <sven@convergence.de>
|
||||
|
||||
* ghash.c: fixed a typo in a comment.
|
||||
|
||||
* gtree.[ch]: added new functions g_tree_new_full(), g_tree_replace(),
|
||||
g_tree_steal() and g_tree_foreach() to adapt GTree to the GHashTable
|
||||
API. Moved comments into the C file.
|
||||
|
||||
* docs/reference/glib/glib-sections.txt
|
||||
* docs/reference/glib/tmpl/glib-unused.sgml
|
||||
* docs/reference/glib/tmpl/hash_tables.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_double.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_single.sgml
|
||||
* docs/reference/glib/tmpl/macros_misc.sgml
|
||||
* docs/reference/glib/tmpl/trees-binary.sgml: updated documentation
|
||||
|
||||
Thu May 3 06:38:28 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* g[s]list.c (g_[s]list_foreach) docs/Changes-2.0.txt: Make
|
||||
|
@ -1,3 +1,19 @@
|
||||
2001-05-04 Sven Neumann <sven@convergence.de>
|
||||
|
||||
* ghash.c: fixed a typo in a comment.
|
||||
|
||||
* gtree.[ch]: added new functions g_tree_new_full(), g_tree_replace(),
|
||||
g_tree_steal() and g_tree_foreach() to adapt GTree to the GHashTable
|
||||
API. Moved comments into the C file.
|
||||
|
||||
* docs/reference/glib/glib-sections.txt
|
||||
* docs/reference/glib/tmpl/glib-unused.sgml
|
||||
* docs/reference/glib/tmpl/hash_tables.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_double.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_single.sgml
|
||||
* docs/reference/glib/tmpl/macros_misc.sgml
|
||||
* docs/reference/glib/tmpl/trees-binary.sgml: updated documentation
|
||||
|
||||
Thu May 3 06:38:28 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* g[s]list.c (g_[s]list_foreach) docs/Changes-2.0.txt: Make
|
||||
|
@ -1,3 +1,19 @@
|
||||
2001-05-04 Sven Neumann <sven@convergence.de>
|
||||
|
||||
* ghash.c: fixed a typo in a comment.
|
||||
|
||||
* gtree.[ch]: added new functions g_tree_new_full(), g_tree_replace(),
|
||||
g_tree_steal() and g_tree_foreach() to adapt GTree to the GHashTable
|
||||
API. Moved comments into the C file.
|
||||
|
||||
* docs/reference/glib/glib-sections.txt
|
||||
* docs/reference/glib/tmpl/glib-unused.sgml
|
||||
* docs/reference/glib/tmpl/hash_tables.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_double.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_single.sgml
|
||||
* docs/reference/glib/tmpl/macros_misc.sgml
|
||||
* docs/reference/glib/tmpl/trees-binary.sgml: updated documentation
|
||||
|
||||
Thu May 3 06:38:28 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* g[s]list.c (g_[s]list_foreach) docs/Changes-2.0.txt: Make
|
||||
|
@ -1,3 +1,19 @@
|
||||
2001-05-04 Sven Neumann <sven@convergence.de>
|
||||
|
||||
* ghash.c: fixed a typo in a comment.
|
||||
|
||||
* gtree.[ch]: added new functions g_tree_new_full(), g_tree_replace(),
|
||||
g_tree_steal() and g_tree_foreach() to adapt GTree to the GHashTable
|
||||
API. Moved comments into the C file.
|
||||
|
||||
* docs/reference/glib/glib-sections.txt
|
||||
* docs/reference/glib/tmpl/glib-unused.sgml
|
||||
* docs/reference/glib/tmpl/hash_tables.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_double.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_single.sgml
|
||||
* docs/reference/glib/tmpl/macros_misc.sgml
|
||||
* docs/reference/glib/tmpl/trees-binary.sgml: updated documentation
|
||||
|
||||
Thu May 3 06:38:28 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* g[s]list.c (g_[s]list_foreach) docs/Changes-2.0.txt: Make
|
||||
|
@ -1,3 +1,19 @@
|
||||
2001-05-04 Sven Neumann <sven@convergence.de>
|
||||
|
||||
* ghash.c: fixed a typo in a comment.
|
||||
|
||||
* gtree.[ch]: added new functions g_tree_new_full(), g_tree_replace(),
|
||||
g_tree_steal() and g_tree_foreach() to adapt GTree to the GHashTable
|
||||
API. Moved comments into the C file.
|
||||
|
||||
* docs/reference/glib/glib-sections.txt
|
||||
* docs/reference/glib/tmpl/glib-unused.sgml
|
||||
* docs/reference/glib/tmpl/hash_tables.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_double.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_single.sgml
|
||||
* docs/reference/glib/tmpl/macros_misc.sgml
|
||||
* docs/reference/glib/tmpl/trees-binary.sgml: updated documentation
|
||||
|
||||
Thu May 3 06:38:28 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* g[s]list.c (g_[s]list_foreach) docs/Changes-2.0.txt: Make
|
||||
|
@ -1,3 +1,19 @@
|
||||
2001-05-04 Sven Neumann <sven@convergence.de>
|
||||
|
||||
* ghash.c: fixed a typo in a comment.
|
||||
|
||||
* gtree.[ch]: added new functions g_tree_new_full(), g_tree_replace(),
|
||||
g_tree_steal() and g_tree_foreach() to adapt GTree to the GHashTable
|
||||
API. Moved comments into the C file.
|
||||
|
||||
* docs/reference/glib/glib-sections.txt
|
||||
* docs/reference/glib/tmpl/glib-unused.sgml
|
||||
* docs/reference/glib/tmpl/hash_tables.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_double.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_single.sgml
|
||||
* docs/reference/glib/tmpl/macros_misc.sgml
|
||||
* docs/reference/glib/tmpl/trees-binary.sgml: updated documentation
|
||||
|
||||
Thu May 3 06:38:28 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* g[s]list.c (g_[s]list_foreach) docs/Changes-2.0.txt: Make
|
||||
|
@ -1,3 +1,19 @@
|
||||
2001-05-04 Sven Neumann <sven@convergence.de>
|
||||
|
||||
* ghash.c: fixed a typo in a comment.
|
||||
|
||||
* gtree.[ch]: added new functions g_tree_new_full(), g_tree_replace(),
|
||||
g_tree_steal() and g_tree_foreach() to adapt GTree to the GHashTable
|
||||
API. Moved comments into the C file.
|
||||
|
||||
* docs/reference/glib/glib-sections.txt
|
||||
* docs/reference/glib/tmpl/glib-unused.sgml
|
||||
* docs/reference/glib/tmpl/hash_tables.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_double.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_single.sgml
|
||||
* docs/reference/glib/tmpl/macros_misc.sgml
|
||||
* docs/reference/glib/tmpl/trees-binary.sgml: updated documentation
|
||||
|
||||
Thu May 3 06:38:28 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* g[s]list.c (g_[s]list_foreach) docs/Changes-2.0.txt: Make
|
||||
|
@ -1,3 +1,19 @@
|
||||
2001-05-04 Sven Neumann <sven@convergence.de>
|
||||
|
||||
* ghash.c: fixed a typo in a comment.
|
||||
|
||||
* gtree.[ch]: added new functions g_tree_new_full(), g_tree_replace(),
|
||||
g_tree_steal() and g_tree_foreach() to adapt GTree to the GHashTable
|
||||
API. Moved comments into the C file.
|
||||
|
||||
* docs/reference/glib/glib-sections.txt
|
||||
* docs/reference/glib/tmpl/glib-unused.sgml
|
||||
* docs/reference/glib/tmpl/hash_tables.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_double.sgml
|
||||
* docs/reference/glib/tmpl/linked_lists_single.sgml
|
||||
* docs/reference/glib/tmpl/macros_misc.sgml
|
||||
* docs/reference/glib/tmpl/trees-binary.sgml: updated documentation
|
||||
|
||||
Thu May 3 06:38:28 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* g[s]list.c (g_[s]list_foreach) docs/Changes-2.0.txt: Make
|
||||
|
@ -1214,6 +1214,7 @@ g_list_insert_sorted
|
||||
g_list_remove
|
||||
g_list_remove_link
|
||||
g_list_delete_link
|
||||
g_list_remove_all
|
||||
g_list_free
|
||||
|
||||
<SUBSECTION>
|
||||
@ -1238,6 +1239,7 @@ g_list_previous
|
||||
g_list_next
|
||||
g_list_nth
|
||||
g_list_nth_data
|
||||
g_list_nth_prev
|
||||
|
||||
<SUBSECTION>
|
||||
g_list_find
|
||||
@ -1265,6 +1267,7 @@ g_slist_insert_sorted
|
||||
g_slist_remove
|
||||
g_slist_remove_link
|
||||
g_slist_delete_link
|
||||
g_slist_remove_all
|
||||
g_slist_free
|
||||
g_slist_free_1
|
||||
|
||||
@ -1330,16 +1333,20 @@ g_trash_stack_height
|
||||
<FILE>hash_tables</FILE>
|
||||
GHashTable
|
||||
g_hash_table_new
|
||||
g_hash_table_new_full
|
||||
GHashFunc
|
||||
GEqualFunc
|
||||
g_hash_table_insert
|
||||
g_hash_table_replace
|
||||
g_hash_table_size
|
||||
g_hash_table_lookup
|
||||
g_hash_table_lookup_extended
|
||||
g_hash_table_foreach
|
||||
GHFunc
|
||||
g_hash_table_remove
|
||||
g_hash_table_steal
|
||||
g_hash_table_foreach_remove
|
||||
g_hash_table_foreach_steal
|
||||
GHRFunc
|
||||
g_hash_table_freeze
|
||||
g_hash_table_thaw
|
||||
@ -1462,15 +1469,21 @@ g_byte_array_free
|
||||
GTree
|
||||
g_tree_new
|
||||
g_tree_new_with_data
|
||||
g_tree_new_full
|
||||
GCompareDataFunc
|
||||
g_tree_insert
|
||||
g_tree_replace
|
||||
g_tree_nnodes
|
||||
g_tree_height
|
||||
g_tree_lookup
|
||||
g_tree_search
|
||||
g_tree_lookup_extended
|
||||
g_tree_foreach
|
||||
g_tree_traverse
|
||||
GTraverseFunc
|
||||
GTraverseType
|
||||
g_tree_search
|
||||
g_tree_remove
|
||||
g_tree_steal
|
||||
g_tree_destroy
|
||||
</SECTION>
|
||||
|
||||
|
@ -175,21 +175,6 @@ Turns the argument into a string literal by using the '#' stringizing operator.
|
||||
|
||||
@x: text to convert to a literal string.
|
||||
|
||||
<!-- ##### FUNCTION g_tree_lookup_extended ##### -->
|
||||
<para>
|
||||
Gets the original key and the associated value and a gboolean which is
|
||||
TRUE if the key was found. This is useful if you need to free the memory
|
||||
allocated for the original key, for example before calling g_tree_remove().
|
||||
Since a #GTree is automatically balanced as key/value pairs are added,
|
||||
key lookup is very fast.
|
||||
</para>
|
||||
|
||||
@tree: a #GTree.
|
||||
@lookup_key: the key to look up.
|
||||
@orig_key: returns the original key.
|
||||
@value: returns the value associated with the key.
|
||||
@Returns: TRUE if the key was found in the #GTree.
|
||||
|
||||
<!-- ##### MACRO getcwd ##### -->
|
||||
<para>
|
||||
|
||||
|
@ -69,6 +69,18 @@ It should only be accessed via the following functions.
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_hash_table_new_full ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@hash_func:
|
||||
@key_equal_func:
|
||||
@key_destroy_func:
|
||||
@value_destroy_func:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### USER_FUNCTION GHashFunc ##### -->
|
||||
<para>
|
||||
Specifies the type of the hash function which is passed to
|
||||
@ -115,6 +127,16 @@ FALSE otherwise.
|
||||
@value:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_hash_table_replace ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@hash_table:
|
||||
@key:
|
||||
@value:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_hash_table_size ##### -->
|
||||
<para>
|
||||
|
||||
@ -178,6 +200,16 @@ which is passed to g_hash_table_foreach().
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_hash_table_steal ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@hash_table:
|
||||
@key:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_hash_table_foreach_remove ##### -->
|
||||
<para>
|
||||
|
||||
@ -189,6 +221,17 @@ which is passed to g_hash_table_foreach().
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_hash_table_foreach_steal ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@hash_table:
|
||||
@func:
|
||||
@user_data:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### USER_FUNCTION GHRFunc ##### -->
|
||||
<para>
|
||||
Specifies the type of the function passed to g_hash_table_foreach_remove().
|
||||
|
@ -189,6 +189,16 @@ Deletes the node @link from @list.
|
||||
@Returns: the new head of @list
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_list_remove_all ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@list:
|
||||
@data:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_list_free ##### -->
|
||||
<para>
|
||||
Frees all of the memory used by a #GList.
|
||||
@ -383,6 +393,16 @@ Gets the data of the element at the given position.
|
||||
#GList.
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_list_nth_prev ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@list:
|
||||
@n:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_list_find ##### -->
|
||||
<para>
|
||||
Finds the element in a #GList which contains the given data.
|
||||
|
@ -209,6 +209,16 @@ Deletes a node of @list. Returns the new list head.
|
||||
@Returns: new head of @list
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_slist_remove_all ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@list:
|
||||
@data:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_slist_free ##### -->
|
||||
<para>
|
||||
Frees all of the memory used by a #GSList.
|
||||
|
@ -66,7 +66,6 @@ only one statement is expected by the compiler.
|
||||
Portable way to copy <type>va_list</type> variables.
|
||||
</para>
|
||||
|
||||
<!-- # Unused Parameters # -->
|
||||
@ap1: the <type>va_list</type> variable to place a copy of @ap2 in.
|
||||
@ap2: a <type>va_list</type>.
|
||||
|
||||
|
@ -26,7 +26,7 @@ To get the height of a #GTree, use g_tree_height().
|
||||
</para>
|
||||
<para>
|
||||
To traverse a #GTree, calling a function for each node visited in the
|
||||
traversal, use g_tree_traverse().
|
||||
traversal, use g_tree_foreach().
|
||||
</para>
|
||||
<para>
|
||||
To remove a key/value pair use g_tree_remove().
|
||||
@ -50,115 +50,123 @@ It should be accessed only by using the following functions.
|
||||
|
||||
<!-- ##### FUNCTION g_tree_new ##### -->
|
||||
<para>
|
||||
Creates a new #GTree.
|
||||
|
||||
</para>
|
||||
|
||||
@key_compare_func: the function used to order the nodes in the #GTree.
|
||||
It should return values similar to the standard <function>strcmp()</function>
|
||||
function -
|
||||
0 if the two arguments are equal, a negative value if the first argument comes
|
||||
before the second, or a positive value if the first argument comes after the
|
||||
second.
|
||||
@Returns: a new #GTree.
|
||||
@key_compare_func:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_tree_new_with_data ##### -->
|
||||
<para>
|
||||
Creates a new #GTree with a comparison function that accepts user data.
|
||||
See g_tree_new() for more details.
|
||||
|
||||
</para>
|
||||
|
||||
@key_compare_func: qsort()-style comparison function
|
||||
@user_data: data to pass to comparison function
|
||||
@Returns: a new #GTree
|
||||
@key_compare_func:
|
||||
@key_compare_data:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_tree_new_full ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@key_compare_func:
|
||||
@key_compare_data:
|
||||
@key_destroy_func:
|
||||
@value_destroy_func:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### USER_FUNCTION GCompareDataFunc ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@a:
|
||||
@b:
|
||||
@user_data:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_tree_insert ##### -->
|
||||
<para>
|
||||
Inserts a key/value pair into a #GTree.
|
||||
If the given key already exists in the #GTree it is set to the new value.
|
||||
(If you are using dynamically allocated keys and values you should be careful
|
||||
to ensure that the old values are freed.)
|
||||
</para>
|
||||
<para>
|
||||
The tree is automatically 'balanced' as new key/value pairs are added,
|
||||
so that the distance from the root to every leaf is as small as possible.
|
||||
|
||||
</para>
|
||||
|
||||
@tree: a #GTree.
|
||||
@key: the key to insert.
|
||||
@value: the value corresponding to the key.
|
||||
@tree:
|
||||
@key:
|
||||
@value:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_tree_replace ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@tree:
|
||||
@key:
|
||||
@value:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_tree_nnodes ##### -->
|
||||
<para>
|
||||
Gets the number of nodes in a #GTree.
|
||||
|
||||
</para>
|
||||
|
||||
@tree: a #GTree.
|
||||
@Returns: the number of nodes in the #GTree.
|
||||
@tree:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_tree_height ##### -->
|
||||
<para>
|
||||
Gets the height of a #GTree.
|
||||
</para>
|
||||
<para>
|
||||
If the #GTree contains no nodes, the height is 0.
|
||||
If the #GTree contains only one root node the height is 1.
|
||||
If the root node has children the height is 2, etc.
|
||||
|
||||
</para>
|
||||
|
||||
@tree: a #GTree.
|
||||
@Returns: the height of the #GTree.
|
||||
@tree:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_tree_lookup ##### -->
|
||||
<para>
|
||||
Gets the value corresponding to the given key.
|
||||
Since a #GTree is automatically balanced as key/value pairs are
|
||||
added, key lookup is very fast.
|
||||
|
||||
</para>
|
||||
|
||||
@tree: a #GTree.
|
||||
@key: the key to look up.
|
||||
@Returns: the value corresponding to the key.
|
||||
@tree:
|
||||
@key:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_tree_search ##### -->
|
||||
<!-- ##### FUNCTION g_tree_lookup_extended ##### -->
|
||||
|
||||
|
||||
@tree:
|
||||
@lookup_key:
|
||||
@orig_key:
|
||||
@value:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_tree_foreach ##### -->
|
||||
<para>
|
||||
Searches a #GTree using an alternative form of the comparison function.
|
||||
</para>
|
||||
<para>
|
||||
This function is not as useful as it sounds.
|
||||
It allows you to use a different function for performing the lookup of
|
||||
a key. However, since the tree is ordered according to the @key_compare_func
|
||||
function passed to g_tree_new(), the function you pass to g_tree_search() must
|
||||
return exactly the same value as would be returned by the comparison function,
|
||||
for each pair of tree nodes, or the search will not work.
|
||||
</para>
|
||||
<para>
|
||||
To search for a specific value, you can use g_tree_traverse().
|
||||
|
||||
</para>
|
||||
|
||||
@tree: a #GTree.
|
||||
@search_func: the comparison function used to search the #GTree.
|
||||
@data: the data passed as the second argument to the @search_func function.
|
||||
@Returns: the value corresponding to the found key, or NULL if the key is
|
||||
not found.
|
||||
@tree:
|
||||
@func:
|
||||
@user_data:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_tree_traverse ##### -->
|
||||
<para>
|
||||
Calls the given function for each node in the GTree.
|
||||
|
||||
</para>
|
||||
|
||||
@tree: a #GTree.
|
||||
@traverse_func: the function to call for each node visited. If this function
|
||||
returns TRUE, the traversal is stopped.
|
||||
@traverse_type: the order in which nodes are visited, one of %G_IN_ORDER,
|
||||
%G_PRE_ORDER and %G_POST_ORDER.
|
||||
@data: user data to pass to the traverse function.
|
||||
@tree:
|
||||
@traverse_func:
|
||||
@traverse_type:
|
||||
@user_data:
|
||||
|
||||
|
||||
<!-- ##### USER_FUNCTION GTraverseFunc ##### -->
|
||||
@ -206,23 +214,42 @@ each child.
|
||||
@G_POST_ORDER:
|
||||
@G_LEVEL_ORDER:
|
||||
|
||||
<!-- ##### FUNCTION g_tree_remove ##### -->
|
||||
<!-- ##### FUNCTION g_tree_search ##### -->
|
||||
<para>
|
||||
Removes a key/value pair from a #GTree.
|
||||
If the key or value is dynamically allocated you must remember to free them
|
||||
yourself.
|
||||
|
||||
</para>
|
||||
|
||||
@tree: a #GTree.
|
||||
@key: the key to remove.
|
||||
@tree:
|
||||
@search_func:
|
||||
@user_data:
|
||||
@Returns:
|
||||
<!-- # Unused Parameters # -->
|
||||
@data:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_tree_remove ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@tree:
|
||||
@key:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_tree_steal ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@tree:
|
||||
@key:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_tree_destroy ##### -->
|
||||
<para>
|
||||
Destroys the #GTree, freeing all of the memory allocated.
|
||||
But it doesn't free keys or values.
|
||||
|
||||
</para>
|
||||
|
||||
@tree: a #GTree.
|
||||
@tree:
|
||||
|
||||
|
||||
|
2
ghash.c
2
ghash.c
@ -114,7 +114,7 @@ g_hash_table_new (GHashFunc hash_func,
|
||||
* @key_equal_func: a function to check two keys for equality.
|
||||
* @key_destroy_func: a function to free the memory allocated for the key
|
||||
* used when removing the entry from the #GHashTable or #NULL if you
|
||||
* you don't want to supply such a function.
|
||||
* don't want to supply such a function.
|
||||
* @value_destroy_func: a function to free the memory allocated for the
|
||||
* value used when removing the entry from the #GHashTable or #NULL if
|
||||
* you don't want to supply such a function.
|
||||
|
@ -114,7 +114,7 @@ g_hash_table_new (GHashFunc hash_func,
|
||||
* @key_equal_func: a function to check two keys for equality.
|
||||
* @key_destroy_func: a function to free the memory allocated for the key
|
||||
* used when removing the entry from the #GHashTable or #NULL if you
|
||||
* you don't want to supply such a function.
|
||||
* don't want to supply such a function.
|
||||
* @value_destroy_func: a function to free the memory allocated for the
|
||||
* value used when removing the entry from the #GHashTable or #NULL if
|
||||
* you don't want to supply such a function.
|
||||
|
516
glib/gtree.c
516
glib/gtree.c
@ -42,7 +42,9 @@ struct _GRealTree
|
||||
{
|
||||
GTreeNode *root;
|
||||
GCompareDataFunc key_compare;
|
||||
gpointer key_compare_data;
|
||||
GDestroyNotify key_destroy_func;
|
||||
GDestroyNotify value_destroy_func;
|
||||
gpointer key_compare_data;
|
||||
};
|
||||
|
||||
struct _GTreeNode
|
||||
@ -55,47 +57,49 @@ struct _GTreeNode
|
||||
};
|
||||
|
||||
|
||||
static GTreeNode* g_tree_node_new (gpointer key,
|
||||
gpointer value);
|
||||
static void g_tree_node_destroy (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_insert (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer comp_data,
|
||||
gpointer key,
|
||||
gpointer value,
|
||||
gint *inserted);
|
||||
static GTreeNode* g_tree_node_remove (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer comp_data,
|
||||
gconstpointer key);
|
||||
static GTreeNode* g_tree_node_balance (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_remove_leftmost (GTreeNode *node,
|
||||
GTreeNode **leftmost);
|
||||
static GTreeNode* g_tree_node_restore_left_balance (GTreeNode *node,
|
||||
gint old_balance);
|
||||
static GTreeNode* g_tree_node_restore_right_balance (GTreeNode *node,
|
||||
gint old_balance);
|
||||
static GTreeNode* g_tree_node_lookup (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer comp_data,
|
||||
gconstpointer key);
|
||||
static gint g_tree_node_count (GTreeNode *node);
|
||||
static gint g_tree_node_pre_order (GTreeNode *node,
|
||||
GTraverseFunc traverse_func,
|
||||
gpointer data);
|
||||
static gint g_tree_node_in_order (GTreeNode *node,
|
||||
GTraverseFunc traverse_func,
|
||||
gpointer data);
|
||||
static gint g_tree_node_post_order (GTreeNode *node,
|
||||
GTraverseFunc traverse_func,
|
||||
gpointer data);
|
||||
static gpointer g_tree_node_search (GTreeNode *node,
|
||||
GCompareFunc search_func,
|
||||
gconstpointer data);
|
||||
static gint g_tree_node_height (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_rotate_left (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_rotate_right (GTreeNode *node);
|
||||
static void g_tree_node_check (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_new (gpointer key,
|
||||
gpointer value);
|
||||
static void g_tree_node_destroy (GTreeNode *node,
|
||||
GDestroyNotify key_destroy_func,
|
||||
GDestroyNotify value_destroy_func);
|
||||
static GTreeNode* g_tree_node_insert (GTree *tree,
|
||||
GTreeNode *node,
|
||||
gpointer key,
|
||||
gpointer value,
|
||||
gboolean replace,
|
||||
gboolean *inserted);
|
||||
static GTreeNode* g_tree_node_remove (GTree *tree,
|
||||
GTreeNode *node,
|
||||
gconstpointer key,
|
||||
gboolean notify);
|
||||
static GTreeNode* g_tree_node_balance (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_remove_leftmost (GTreeNode *node,
|
||||
GTreeNode **leftmost);
|
||||
static GTreeNode* g_tree_node_restore_left_balance (GTreeNode *node,
|
||||
gint old_balance);
|
||||
static GTreeNode* g_tree_node_restore_right_balance (GTreeNode *node,
|
||||
gint old_balance);
|
||||
static GTreeNode* g_tree_node_lookup (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer comp_data,
|
||||
gconstpointer key);
|
||||
static gint g_tree_node_count (GTreeNode *node);
|
||||
static gint g_tree_node_pre_order (GTreeNode *node,
|
||||
GTraverseFunc traverse_func,
|
||||
gpointer data);
|
||||
static gint g_tree_node_in_order (GTreeNode *node,
|
||||
GTraverseFunc traverse_func,
|
||||
gpointer data);
|
||||
static gint g_tree_node_post_order (GTreeNode *node,
|
||||
GTraverseFunc traverse_func,
|
||||
gpointer data);
|
||||
static gpointer g_tree_node_search (GTreeNode *node,
|
||||
GCompareFunc search_func,
|
||||
gconstpointer data);
|
||||
static gint g_tree_node_height (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_rotate_left (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_rotate_right (GTreeNode *node);
|
||||
static void g_tree_node_check (GTreeNode *node);
|
||||
|
||||
|
||||
G_LOCK_DEFINE_STATIC (g_tree_global);
|
||||
@ -137,13 +141,22 @@ g_tree_node_new (gpointer key,
|
||||
}
|
||||
|
||||
static void
|
||||
g_tree_node_destroy (GTreeNode *node)
|
||||
g_tree_node_destroy (GTreeNode *node,
|
||||
GDestroyNotify key_destroy_func,
|
||||
GDestroyNotify value_destroy_func)
|
||||
{
|
||||
if (node)
|
||||
{
|
||||
g_tree_node_destroy (node->right);
|
||||
g_tree_node_destroy (node->left);
|
||||
g_tree_node_destroy (node->right,
|
||||
key_destroy_func, value_destroy_func);
|
||||
g_tree_node_destroy (node->left,
|
||||
key_destroy_func, value_destroy_func);
|
||||
|
||||
if (key_destroy_func)
|
||||
key_destroy_func (node->key);
|
||||
if (value_destroy_func)
|
||||
value_destroy_func (node->value);
|
||||
|
||||
#ifdef ENABLE_GC_FRIENDLY
|
||||
node->left = NULL;
|
||||
node->key = NULL;
|
||||
@ -157,28 +170,94 @@ g_tree_node_destroy (GTreeNode *node)
|
||||
}
|
||||
}
|
||||
|
||||
GTree* g_tree_new_udata(GCompareDataFunc key_compare_func,
|
||||
gpointer key_compare_data)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
|
||||
g_return_val_if_fail (key_compare_func != NULL, NULL);
|
||||
|
||||
rtree = g_new (GRealTree, 1);
|
||||
rtree->root = NULL;
|
||||
rtree->key_compare = key_compare_func;
|
||||
rtree->key_compare_data = key_compare_data;
|
||||
|
||||
return (GTree*) rtree;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_new:
|
||||
* @key_compare_func: the function used to order the nodes in the #GTree.
|
||||
* It should return values similar to the standard
|
||||
* <function>strcmp()</function> function -
|
||||
* 0 if the two arguments are equal, a negative value if the first argument
|
||||
* comes before the second, or a positive value if the first argument comes
|
||||
* after the second.
|
||||
*
|
||||
* Creates a new #GTree.
|
||||
*
|
||||
* Return value: a new #GTree.
|
||||
**/
|
||||
GTree*
|
||||
g_tree_new (GCompareFunc key_compare_func)
|
||||
{
|
||||
return g_tree_new_udata ((GCompareDataFunc) key_compare_func, NULL);
|
||||
g_return_val_if_fail (key_compare_func != NULL, NULL);
|
||||
|
||||
return g_tree_new_full ((GCompareDataFunc) key_compare_func, NULL,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_new_with_data:
|
||||
* @key_compare_func: qsort()-style comparison function.
|
||||
* @key_compare_data: data to pass to comparison function.
|
||||
*
|
||||
* Creates a new #GTree with a comparison function that accepts user data.
|
||||
* See g_tree_new() for more details.
|
||||
*
|
||||
* Return value: a new #GTree.
|
||||
**/
|
||||
GTree*
|
||||
g_tree_new_with_data (GCompareDataFunc key_compare_func,
|
||||
gpointer key_compare_data)
|
||||
{
|
||||
g_return_val_if_fail (key_compare_func != NULL, NULL);
|
||||
|
||||
return g_tree_new_full (key_compare_func, key_compare_data,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_new_full:
|
||||
* @key_compare_func: qsort()-style comparison function.
|
||||
* @key_compare_data: data to pass to comparison function.
|
||||
* @key_destroy_func: a function to free the memory allocated for the key
|
||||
* used when removing the entry from the #GTree or #NULL if you don't
|
||||
* want to supply such a function.
|
||||
* @value_destroy_func: a function to free the memory allocated for the
|
||||
* value used when removing the entry from the #GTree or #NULL if you
|
||||
* don't want to supply such a function.
|
||||
*
|
||||
* Creates a new #GTree like g_tree_new() and allows to specify functions
|
||||
* to free the memory allocated for the key and value that get called when
|
||||
* removing the entry from the #GTree.
|
||||
*
|
||||
* Return value: a new #GTree.
|
||||
**/
|
||||
GTree*
|
||||
g_tree_new_full (GCompareDataFunc key_compare_func,
|
||||
gpointer key_compare_data,
|
||||
GDestroyNotify key_destroy_func,
|
||||
GDestroyNotify value_destroy_func)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
|
||||
g_return_val_if_fail (key_compare_func != NULL, NULL);
|
||||
|
||||
rtree = g_new (GRealTree, 1);
|
||||
rtree->root = NULL;
|
||||
rtree->key_compare = key_compare_func;
|
||||
rtree->key_destroy_func = key_destroy_func;
|
||||
rtree->value_destroy_func = value_destroy_func;
|
||||
rtree->key_compare_data = key_compare_data;
|
||||
|
||||
return (GTree*) rtree;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_destroy:
|
||||
* @tree: a #GTree.
|
||||
*
|
||||
* Destroys the #GTree. If keys and/or values are dynamically allocated, you
|
||||
* should either free them first or create the #GTree using g_tree_new_full().
|
||||
* In the latter case the destroy functions you supplied will be called on
|
||||
* all keys and values before destroying the #GTree.
|
||||
**/
|
||||
void
|
||||
g_tree_destroy (GTree *tree)
|
||||
{
|
||||
@ -188,28 +267,93 @@ g_tree_destroy (GTree *tree)
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
g_tree_node_destroy (rtree->root);
|
||||
g_tree_node_destroy (rtree->root,
|
||||
rtree->key_destroy_func,
|
||||
rtree->value_destroy_func);
|
||||
|
||||
g_free (rtree);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_insert:
|
||||
* @tree: a #Gtree.
|
||||
* @key: the key to insert.
|
||||
* @value: the value corresponding to the key.
|
||||
*
|
||||
* Inserts a key/value pair into a #GTree. If the given key already exists
|
||||
* in the #GTree it is set to the new value. If you supplied a
|
||||
* value_destroy_func when creating the #GTree, the old value is freed using
|
||||
* that function. If you supplied a key_destroy_func when creating the
|
||||
* #GTree, the passed key is freed using that function.
|
||||
*
|
||||
* The tree is automatically 'balanced' as new key/value pairs are added,
|
||||
* so that the distance from the root to every leaf is as small as possible.
|
||||
**/
|
||||
void
|
||||
g_tree_insert (GTree *tree,
|
||||
gpointer key,
|
||||
gpointer value)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
gint inserted;
|
||||
gboolean inserted;
|
||||
|
||||
g_return_if_fail (tree != NULL);
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
inserted = FALSE;
|
||||
rtree->root = g_tree_node_insert (rtree->root, rtree->key_compare,
|
||||
rtree->key_compare_data,
|
||||
key, value, &inserted);
|
||||
rtree->root = g_tree_node_insert (tree,
|
||||
rtree->root,
|
||||
key, value,
|
||||
FALSE, &inserted);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_replace:
|
||||
* @tree: a #Gtree.
|
||||
* @key: the key to insert.
|
||||
* @value: the value corresponding to the key.
|
||||
*
|
||||
* Inserts a new key and value into a #GTree similar to g_tree_insert().
|
||||
* The difference is that if the key already exists in the #GTree, it gets
|
||||
* replaced by the new key. If you supplied a value_destroy_func when
|
||||
* creating the #GTree, the old value is freed using that function. If you
|
||||
* supplied a key_destroy_func when creating the #GTree, the old key is
|
||||
* freed using that function.
|
||||
*
|
||||
* The tree is automatically 'balanced' as new key/value pairs are added,
|
||||
* so that the distance from the root to every leaf is as small as possible.
|
||||
**/
|
||||
void
|
||||
g_tree_replace (GTree *tree,
|
||||
gpointer key,
|
||||
gpointer value)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
gboolean inserted;
|
||||
|
||||
g_return_if_fail (tree != NULL);
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
inserted = FALSE;
|
||||
rtree->root = g_tree_node_insert (tree,
|
||||
rtree->root,
|
||||
key, value,
|
||||
TRUE, &inserted);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_remove:
|
||||
* @tree: a #Gtree.
|
||||
* @key: the key to remove.
|
||||
*
|
||||
* Removes a key/value pair from a #GTree.
|
||||
*
|
||||
* If the #GTree was created using g_tree_new_full(), the key and value
|
||||
* are freed using the supplied destroy_functions, otherwise you have to
|
||||
* make sure that any dynamically allocated values are freed yourself.
|
||||
**/
|
||||
void
|
||||
g_tree_remove (GTree *tree,
|
||||
gconstpointer key)
|
||||
@ -220,10 +364,41 @@ g_tree_remove (GTree *tree,
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
rtree->root = g_tree_node_remove (rtree->root, rtree->key_compare,
|
||||
rtree->key_compare_data, key);
|
||||
rtree->root = g_tree_node_remove (tree, rtree->root, key, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_steal:
|
||||
* @tree: a #Gtree.
|
||||
* @key: the key to remove.
|
||||
*
|
||||
* Removes a key and its associated value from a #GTree without calling
|
||||
* the key and value destroy functions.
|
||||
**/
|
||||
void
|
||||
g_tree_steal (GTree *tree,
|
||||
gconstpointer key)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
|
||||
g_return_if_fail (tree != NULL);
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
rtree->root = g_tree_node_remove (tree, rtree->root, key, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_lookup:
|
||||
* @tree: a #GTree.
|
||||
* @key: the key to look up.
|
||||
*
|
||||
* Gets the value corresponding to the given key. Since a #GTree is
|
||||
* automatically balanced as key/value pairs are added, key lookup is very
|
||||
* fast.
|
||||
*
|
||||
* Return value: the value corresponding to the key.
|
||||
**/
|
||||
gpointer
|
||||
g_tree_lookup (GTree *tree,
|
||||
gconstpointer key)
|
||||
@ -235,12 +410,26 @@ g_tree_lookup (GTree *tree,
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
node = g_tree_node_lookup (rtree->root, rtree->key_compare,
|
||||
rtree->key_compare_data, key);
|
||||
node = g_tree_node_lookup (rtree->root,
|
||||
rtree->key_compare, rtree->key_compare_data, key);
|
||||
|
||||
return node ? node->value : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_lookup_extended:
|
||||
* @tree: a #GTree.
|
||||
* @lookup_key: the key to look up.
|
||||
* @orig_key: returns the original key.
|
||||
* @value: returns the value associated with the key.
|
||||
*
|
||||
* Looks up a key in the #GTree, returning the original key and the
|
||||
* associated value and a gboolean which is TRUE if the key was found. This
|
||||
* is useful if you need to free the memory allocated for the original key,
|
||||
* for example before calling g_tree_remove().
|
||||
*
|
||||
* Return value: #TRUE if the key was found in the #GTree.
|
||||
**/
|
||||
gboolean
|
||||
g_tree_lookup_extended (GTree *tree,
|
||||
gconstpointer lookup_key,
|
||||
@ -255,9 +444,7 @@ g_tree_lookup_extended (GTree *tree,
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
node = g_tree_node_lookup (rtree->root,
|
||||
rtree->key_compare,
|
||||
rtree->key_compare_data,
|
||||
lookup_key);
|
||||
rtree->key_compare, rtree->key_compare_data, lookup_key);
|
||||
|
||||
if (node)
|
||||
{
|
||||
@ -271,11 +458,51 @@ g_tree_lookup_extended (GTree *tree,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_foreach:
|
||||
* @tree: a #GTree.
|
||||
* @func: the function to call for each node visited. If this function
|
||||
* returns TRUE, the traversal is stopped.
|
||||
* @user_data: user data to pass to the function.
|
||||
*
|
||||
* Calls the given function for each of the key/value pairs in the #GTree.
|
||||
* The function is passed the key and value of each pair, and the given
|
||||
* @data parameter.
|
||||
**/
|
||||
void
|
||||
g_tree_foreach (GTree *tree,
|
||||
GTraverseFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
|
||||
g_return_if_fail (tree != NULL);
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
if (!rtree->root)
|
||||
return;
|
||||
|
||||
g_tree_node_in_order (rtree->root, func, user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_traverse:
|
||||
* @tree: a #GTree.
|
||||
* @traverse_func: the function to call for each node visited. If this
|
||||
* function returns TRUE, the traversal is stopped.
|
||||
* @traverse_type: the order in which nodes are visited, one of %G_IN_ORDER,
|
||||
* %G_PRE_ORDER and %G_POST_ORDER.
|
||||
* @user_data: user data to pass to the function.
|
||||
*
|
||||
* Calls the given function for each node in the GTree. This function is
|
||||
* deprecated, use g_tree_foreach() instead.
|
||||
**/
|
||||
void
|
||||
g_tree_traverse (GTree *tree,
|
||||
GTraverseFunc traverse_func,
|
||||
GTraverseType traverse_type,
|
||||
gpointer data)
|
||||
gpointer user_data)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
|
||||
@ -289,15 +516,15 @@ g_tree_traverse (GTree *tree,
|
||||
switch (traverse_type)
|
||||
{
|
||||
case G_PRE_ORDER:
|
||||
g_tree_node_pre_order (rtree->root, traverse_func, data);
|
||||
g_tree_node_pre_order (rtree->root, traverse_func, user_data);
|
||||
break;
|
||||
|
||||
case G_IN_ORDER:
|
||||
g_tree_node_in_order (rtree->root, traverse_func, data);
|
||||
g_tree_node_in_order (rtree->root, traverse_func, user_data);
|
||||
break;
|
||||
|
||||
case G_POST_ORDER:
|
||||
g_tree_node_post_order (rtree->root, traverse_func, data);
|
||||
g_tree_node_post_order (rtree->root, traverse_func, user_data);
|
||||
break;
|
||||
|
||||
case G_LEVEL_ORDER:
|
||||
@ -306,10 +533,32 @@ g_tree_traverse (GTree *tree,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_search:
|
||||
* @tree: a #GTree.
|
||||
* @search_func: the comparison function used to search the #GTree.
|
||||
* @user_data: the data passed as the second argument to the @search_func
|
||||
* function.
|
||||
*
|
||||
* Searches a #GTree using an alternative form of the comparison function.
|
||||
*
|
||||
* This function is not as useful as it sounds.
|
||||
* It allows you to use a different function for performing the lookup of
|
||||
* a key. However, since the tree is ordered according to the @key_compare_func
|
||||
* function passed to g_tree_new(), the function you pass to g_tree_search()
|
||||
* must return exactly the same value as would be returned by the comparison
|
||||
* function, for each pair of tree nodes, or the search will not work.
|
||||
*
|
||||
* To search for a specific value, you can use g_tree_foreach() or
|
||||
* g_tree_traverse().
|
||||
*
|
||||
* Return value: the value corresponding to the found key, or NULL if the key
|
||||
* is not found.
|
||||
**/
|
||||
gpointer
|
||||
g_tree_search (GTree *tree,
|
||||
GCompareFunc search_func,
|
||||
gconstpointer data)
|
||||
g_tree_search (GTree *tree,
|
||||
GCompareFunc search_func,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
|
||||
@ -318,11 +567,23 @@ g_tree_search (GTree *tree,
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
if (rtree->root)
|
||||
return g_tree_node_search (rtree->root, search_func, data);
|
||||
return g_tree_node_search (rtree->root, search_func, user_data);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_height:
|
||||
* @tree: a #GTree.
|
||||
*
|
||||
* Gets the height of a #GTree.
|
||||
*
|
||||
* If the #GTree contains no nodes, the height is 0.
|
||||
* If the #GTree contains only one root node the height is 1.
|
||||
* If the root node has children the height is 2, etc.
|
||||
*
|
||||
* Return value: the height of the #GTree.
|
||||
**/
|
||||
gint
|
||||
g_tree_height (GTree *tree)
|
||||
{
|
||||
@ -338,6 +599,14 @@ g_tree_height (GTree *tree)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_nnodes:
|
||||
* @tree: a #GTree.
|
||||
*
|
||||
* Gets the number of nodes in a #GTree.
|
||||
*
|
||||
* Return value: the number of nodes in the #GTree.
|
||||
**/
|
||||
gint
|
||||
g_tree_nnodes (GTree *tree)
|
||||
{
|
||||
@ -354,15 +623,18 @@ g_tree_nnodes (GTree *tree)
|
||||
}
|
||||
|
||||
static GTreeNode*
|
||||
g_tree_node_insert (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer compare_data,
|
||||
gpointer key,
|
||||
gpointer value,
|
||||
gint *inserted)
|
||||
g_tree_node_insert (GTree *tree,
|
||||
GTreeNode *node,
|
||||
gpointer key,
|
||||
gpointer value,
|
||||
gboolean replace,
|
||||
gboolean *inserted)
|
||||
{
|
||||
gint old_balance;
|
||||
gint cmp;
|
||||
GRealTree *rtree;
|
||||
gint old_balance;
|
||||
gint cmp;
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
if (!node)
|
||||
{
|
||||
@ -370,11 +642,30 @@ g_tree_node_insert (GTreeNode *node,
|
||||
return g_tree_node_new (key, value);
|
||||
}
|
||||
|
||||
cmp = (* compare) (key, node->key, compare_data);
|
||||
cmp = rtree->key_compare (key, node->key, rtree->key_compare_data);
|
||||
if (cmp == 0)
|
||||
{
|
||||
*inserted = FALSE;
|
||||
|
||||
if (rtree->value_destroy_func)
|
||||
rtree->value_destroy_func (node->value);
|
||||
|
||||
node->value = value;
|
||||
|
||||
if (replace)
|
||||
{
|
||||
if (rtree->key_destroy_func)
|
||||
rtree->key_destroy_func (node->key);
|
||||
|
||||
node->key = key;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* free the passed key */
|
||||
if (rtree->key_destroy_func)
|
||||
rtree->key_destroy_func (key);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -383,8 +674,10 @@ g_tree_node_insert (GTreeNode *node,
|
||||
if (node->left)
|
||||
{
|
||||
old_balance = node->left->balance;
|
||||
node->left = g_tree_node_insert (node->left, compare, compare_data,
|
||||
key, value, inserted);
|
||||
node->left = g_tree_node_insert (tree,
|
||||
node->left,
|
||||
key, value,
|
||||
replace, inserted);
|
||||
|
||||
if ((old_balance != node->left->balance) && node->left->balance)
|
||||
node->balance -= 1;
|
||||
@ -401,8 +694,10 @@ g_tree_node_insert (GTreeNode *node,
|
||||
if (node->right)
|
||||
{
|
||||
old_balance = node->right->balance;
|
||||
node->right = g_tree_node_insert (node->right, compare, compare_data,
|
||||
key, value, inserted);
|
||||
node->right = g_tree_node_insert (tree,
|
||||
node->right,
|
||||
key, value,
|
||||
replace, inserted);
|
||||
|
||||
if ((old_balance != node->right->balance) && node->right->balance)
|
||||
node->balance += 1;
|
||||
@ -425,11 +720,12 @@ g_tree_node_insert (GTreeNode *node,
|
||||
}
|
||||
|
||||
static GTreeNode*
|
||||
g_tree_node_remove (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer compare_data,
|
||||
gconstpointer key)
|
||||
g_tree_node_remove (GTree *tree,
|
||||
GTreeNode *node,
|
||||
gconstpointer key,
|
||||
gboolean notify)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
GTreeNode *new_root;
|
||||
gint old_balance;
|
||||
gint cmp;
|
||||
@ -437,7 +733,9 @@ g_tree_node_remove (GTreeNode *node,
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
cmp = (* compare) (key, node->key, compare_data);
|
||||
rtree = (GRealTree *) tree;
|
||||
|
||||
cmp = rtree->key_compare (key, node->key, rtree->key_compare_data);
|
||||
if (cmp == 0)
|
||||
{
|
||||
GTreeNode *garbage;
|
||||
@ -458,6 +756,14 @@ g_tree_node_remove (GTreeNode *node,
|
||||
node = g_tree_node_restore_right_balance (new_root, old_balance);
|
||||
}
|
||||
|
||||
if (notify)
|
||||
{
|
||||
if (rtree->key_destroy_func)
|
||||
rtree->key_destroy_func (garbage->key);
|
||||
if (rtree->value_destroy_func)
|
||||
rtree->value_destroy_func (garbage->value);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_GC_FRIENDLY
|
||||
garbage->left = NULL;
|
||||
garbage->key = NULL;
|
||||
@ -474,7 +780,7 @@ g_tree_node_remove (GTreeNode *node,
|
||||
if (node->left)
|
||||
{
|
||||
old_balance = node->left->balance;
|
||||
node->left = g_tree_node_remove (node->left, compare, compare_data, key);
|
||||
node->left = g_tree_node_remove (tree, node->left, key, notify);
|
||||
node = g_tree_node_restore_left_balance (node, old_balance);
|
||||
}
|
||||
}
|
||||
@ -483,7 +789,7 @@ g_tree_node_remove (GTreeNode *node,
|
||||
if (node->right)
|
||||
{
|
||||
old_balance = node->right->balance;
|
||||
node->right = g_tree_node_remove (node->right, compare, compare_data, key);
|
||||
node->right = g_tree_node_remove (tree, node->right, key, notify);
|
||||
node = g_tree_node_restore_right_balance (node, old_balance);
|
||||
}
|
||||
}
|
||||
@ -558,10 +864,10 @@ g_tree_node_restore_right_balance (GTreeNode *node,
|
||||
}
|
||||
|
||||
static GTreeNode *
|
||||
g_tree_node_lookup (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer compare_data,
|
||||
gconstpointer key)
|
||||
g_tree_node_lookup (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer compare_data,
|
||||
gconstpointer key)
|
||||
{
|
||||
gint cmp;
|
||||
|
||||
|
18
glib/gtree.h
18
glib/gtree.h
@ -41,26 +41,38 @@ typedef gint (*GTraverseFunc) (gpointer key,
|
||||
*/
|
||||
GTree* g_tree_new (GCompareFunc key_compare_func);
|
||||
GTree* g_tree_new_with_data (GCompareDataFunc key_compare_func,
|
||||
gpointer user_data);
|
||||
gpointer key_compare_data);
|
||||
GTree* g_tree_new_full (GCompareDataFunc key_compare_func,
|
||||
gpointer key_compare_data,
|
||||
GDestroyNotify key_destroy_func,
|
||||
GDestroyNotify value_destroy_func);
|
||||
void g_tree_destroy (GTree *tree);
|
||||
void g_tree_insert (GTree *tree,
|
||||
gpointer key,
|
||||
gpointer value);
|
||||
void g_tree_replace (GTree *tree,
|
||||
gpointer key,
|
||||
gpointer value);
|
||||
void g_tree_remove (GTree *tree,
|
||||
gconstpointer key);
|
||||
void g_tree_steal (GTree *tree,
|
||||
gconstpointer key);
|
||||
gpointer g_tree_lookup (GTree *tree,
|
||||
gconstpointer key);
|
||||
gboolean g_tree_lookup_extended (GTree *tree,
|
||||
gconstpointer lookup_key,
|
||||
gpointer *orig_key,
|
||||
gpointer *value);
|
||||
void g_tree_foreach (GTree *tree,
|
||||
GTraverseFunc func,
|
||||
gpointer user_data);
|
||||
void g_tree_traverse (GTree *tree,
|
||||
GTraverseFunc traverse_func,
|
||||
GTraverseType traverse_type,
|
||||
gpointer data);
|
||||
gpointer user_data);
|
||||
gpointer g_tree_search (GTree *tree,
|
||||
GCompareFunc search_func,
|
||||
gconstpointer data);
|
||||
gconstpointer user_data);
|
||||
gint g_tree_height (GTree *tree);
|
||||
gint g_tree_nnodes (GTree *tree);
|
||||
|
||||
|
516
gtree.c
516
gtree.c
@ -42,7 +42,9 @@ struct _GRealTree
|
||||
{
|
||||
GTreeNode *root;
|
||||
GCompareDataFunc key_compare;
|
||||
gpointer key_compare_data;
|
||||
GDestroyNotify key_destroy_func;
|
||||
GDestroyNotify value_destroy_func;
|
||||
gpointer key_compare_data;
|
||||
};
|
||||
|
||||
struct _GTreeNode
|
||||
@ -55,47 +57,49 @@ struct _GTreeNode
|
||||
};
|
||||
|
||||
|
||||
static GTreeNode* g_tree_node_new (gpointer key,
|
||||
gpointer value);
|
||||
static void g_tree_node_destroy (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_insert (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer comp_data,
|
||||
gpointer key,
|
||||
gpointer value,
|
||||
gint *inserted);
|
||||
static GTreeNode* g_tree_node_remove (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer comp_data,
|
||||
gconstpointer key);
|
||||
static GTreeNode* g_tree_node_balance (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_remove_leftmost (GTreeNode *node,
|
||||
GTreeNode **leftmost);
|
||||
static GTreeNode* g_tree_node_restore_left_balance (GTreeNode *node,
|
||||
gint old_balance);
|
||||
static GTreeNode* g_tree_node_restore_right_balance (GTreeNode *node,
|
||||
gint old_balance);
|
||||
static GTreeNode* g_tree_node_lookup (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer comp_data,
|
||||
gconstpointer key);
|
||||
static gint g_tree_node_count (GTreeNode *node);
|
||||
static gint g_tree_node_pre_order (GTreeNode *node,
|
||||
GTraverseFunc traverse_func,
|
||||
gpointer data);
|
||||
static gint g_tree_node_in_order (GTreeNode *node,
|
||||
GTraverseFunc traverse_func,
|
||||
gpointer data);
|
||||
static gint g_tree_node_post_order (GTreeNode *node,
|
||||
GTraverseFunc traverse_func,
|
||||
gpointer data);
|
||||
static gpointer g_tree_node_search (GTreeNode *node,
|
||||
GCompareFunc search_func,
|
||||
gconstpointer data);
|
||||
static gint g_tree_node_height (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_rotate_left (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_rotate_right (GTreeNode *node);
|
||||
static void g_tree_node_check (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_new (gpointer key,
|
||||
gpointer value);
|
||||
static void g_tree_node_destroy (GTreeNode *node,
|
||||
GDestroyNotify key_destroy_func,
|
||||
GDestroyNotify value_destroy_func);
|
||||
static GTreeNode* g_tree_node_insert (GTree *tree,
|
||||
GTreeNode *node,
|
||||
gpointer key,
|
||||
gpointer value,
|
||||
gboolean replace,
|
||||
gboolean *inserted);
|
||||
static GTreeNode* g_tree_node_remove (GTree *tree,
|
||||
GTreeNode *node,
|
||||
gconstpointer key,
|
||||
gboolean notify);
|
||||
static GTreeNode* g_tree_node_balance (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_remove_leftmost (GTreeNode *node,
|
||||
GTreeNode **leftmost);
|
||||
static GTreeNode* g_tree_node_restore_left_balance (GTreeNode *node,
|
||||
gint old_balance);
|
||||
static GTreeNode* g_tree_node_restore_right_balance (GTreeNode *node,
|
||||
gint old_balance);
|
||||
static GTreeNode* g_tree_node_lookup (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer comp_data,
|
||||
gconstpointer key);
|
||||
static gint g_tree_node_count (GTreeNode *node);
|
||||
static gint g_tree_node_pre_order (GTreeNode *node,
|
||||
GTraverseFunc traverse_func,
|
||||
gpointer data);
|
||||
static gint g_tree_node_in_order (GTreeNode *node,
|
||||
GTraverseFunc traverse_func,
|
||||
gpointer data);
|
||||
static gint g_tree_node_post_order (GTreeNode *node,
|
||||
GTraverseFunc traverse_func,
|
||||
gpointer data);
|
||||
static gpointer g_tree_node_search (GTreeNode *node,
|
||||
GCompareFunc search_func,
|
||||
gconstpointer data);
|
||||
static gint g_tree_node_height (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_rotate_left (GTreeNode *node);
|
||||
static GTreeNode* g_tree_node_rotate_right (GTreeNode *node);
|
||||
static void g_tree_node_check (GTreeNode *node);
|
||||
|
||||
|
||||
G_LOCK_DEFINE_STATIC (g_tree_global);
|
||||
@ -137,13 +141,22 @@ g_tree_node_new (gpointer key,
|
||||
}
|
||||
|
||||
static void
|
||||
g_tree_node_destroy (GTreeNode *node)
|
||||
g_tree_node_destroy (GTreeNode *node,
|
||||
GDestroyNotify key_destroy_func,
|
||||
GDestroyNotify value_destroy_func)
|
||||
{
|
||||
if (node)
|
||||
{
|
||||
g_tree_node_destroy (node->right);
|
||||
g_tree_node_destroy (node->left);
|
||||
g_tree_node_destroy (node->right,
|
||||
key_destroy_func, value_destroy_func);
|
||||
g_tree_node_destroy (node->left,
|
||||
key_destroy_func, value_destroy_func);
|
||||
|
||||
if (key_destroy_func)
|
||||
key_destroy_func (node->key);
|
||||
if (value_destroy_func)
|
||||
value_destroy_func (node->value);
|
||||
|
||||
#ifdef ENABLE_GC_FRIENDLY
|
||||
node->left = NULL;
|
||||
node->key = NULL;
|
||||
@ -157,28 +170,94 @@ g_tree_node_destroy (GTreeNode *node)
|
||||
}
|
||||
}
|
||||
|
||||
GTree* g_tree_new_udata(GCompareDataFunc key_compare_func,
|
||||
gpointer key_compare_data)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
|
||||
g_return_val_if_fail (key_compare_func != NULL, NULL);
|
||||
|
||||
rtree = g_new (GRealTree, 1);
|
||||
rtree->root = NULL;
|
||||
rtree->key_compare = key_compare_func;
|
||||
rtree->key_compare_data = key_compare_data;
|
||||
|
||||
return (GTree*) rtree;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_new:
|
||||
* @key_compare_func: the function used to order the nodes in the #GTree.
|
||||
* It should return values similar to the standard
|
||||
* <function>strcmp()</function> function -
|
||||
* 0 if the two arguments are equal, a negative value if the first argument
|
||||
* comes before the second, or a positive value if the first argument comes
|
||||
* after the second.
|
||||
*
|
||||
* Creates a new #GTree.
|
||||
*
|
||||
* Return value: a new #GTree.
|
||||
**/
|
||||
GTree*
|
||||
g_tree_new (GCompareFunc key_compare_func)
|
||||
{
|
||||
return g_tree_new_udata ((GCompareDataFunc) key_compare_func, NULL);
|
||||
g_return_val_if_fail (key_compare_func != NULL, NULL);
|
||||
|
||||
return g_tree_new_full ((GCompareDataFunc) key_compare_func, NULL,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_new_with_data:
|
||||
* @key_compare_func: qsort()-style comparison function.
|
||||
* @key_compare_data: data to pass to comparison function.
|
||||
*
|
||||
* Creates a new #GTree with a comparison function that accepts user data.
|
||||
* See g_tree_new() for more details.
|
||||
*
|
||||
* Return value: a new #GTree.
|
||||
**/
|
||||
GTree*
|
||||
g_tree_new_with_data (GCompareDataFunc key_compare_func,
|
||||
gpointer key_compare_data)
|
||||
{
|
||||
g_return_val_if_fail (key_compare_func != NULL, NULL);
|
||||
|
||||
return g_tree_new_full (key_compare_func, key_compare_data,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_new_full:
|
||||
* @key_compare_func: qsort()-style comparison function.
|
||||
* @key_compare_data: data to pass to comparison function.
|
||||
* @key_destroy_func: a function to free the memory allocated for the key
|
||||
* used when removing the entry from the #GTree or #NULL if you don't
|
||||
* want to supply such a function.
|
||||
* @value_destroy_func: a function to free the memory allocated for the
|
||||
* value used when removing the entry from the #GTree or #NULL if you
|
||||
* don't want to supply such a function.
|
||||
*
|
||||
* Creates a new #GTree like g_tree_new() and allows to specify functions
|
||||
* to free the memory allocated for the key and value that get called when
|
||||
* removing the entry from the #GTree.
|
||||
*
|
||||
* Return value: a new #GTree.
|
||||
**/
|
||||
GTree*
|
||||
g_tree_new_full (GCompareDataFunc key_compare_func,
|
||||
gpointer key_compare_data,
|
||||
GDestroyNotify key_destroy_func,
|
||||
GDestroyNotify value_destroy_func)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
|
||||
g_return_val_if_fail (key_compare_func != NULL, NULL);
|
||||
|
||||
rtree = g_new (GRealTree, 1);
|
||||
rtree->root = NULL;
|
||||
rtree->key_compare = key_compare_func;
|
||||
rtree->key_destroy_func = key_destroy_func;
|
||||
rtree->value_destroy_func = value_destroy_func;
|
||||
rtree->key_compare_data = key_compare_data;
|
||||
|
||||
return (GTree*) rtree;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_destroy:
|
||||
* @tree: a #GTree.
|
||||
*
|
||||
* Destroys the #GTree. If keys and/or values are dynamically allocated, you
|
||||
* should either free them first or create the #GTree using g_tree_new_full().
|
||||
* In the latter case the destroy functions you supplied will be called on
|
||||
* all keys and values before destroying the #GTree.
|
||||
**/
|
||||
void
|
||||
g_tree_destroy (GTree *tree)
|
||||
{
|
||||
@ -188,28 +267,93 @@ g_tree_destroy (GTree *tree)
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
g_tree_node_destroy (rtree->root);
|
||||
g_tree_node_destroy (rtree->root,
|
||||
rtree->key_destroy_func,
|
||||
rtree->value_destroy_func);
|
||||
|
||||
g_free (rtree);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_insert:
|
||||
* @tree: a #Gtree.
|
||||
* @key: the key to insert.
|
||||
* @value: the value corresponding to the key.
|
||||
*
|
||||
* Inserts a key/value pair into a #GTree. If the given key already exists
|
||||
* in the #GTree it is set to the new value. If you supplied a
|
||||
* value_destroy_func when creating the #GTree, the old value is freed using
|
||||
* that function. If you supplied a key_destroy_func when creating the
|
||||
* #GTree, the passed key is freed using that function.
|
||||
*
|
||||
* The tree is automatically 'balanced' as new key/value pairs are added,
|
||||
* so that the distance from the root to every leaf is as small as possible.
|
||||
**/
|
||||
void
|
||||
g_tree_insert (GTree *tree,
|
||||
gpointer key,
|
||||
gpointer value)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
gint inserted;
|
||||
gboolean inserted;
|
||||
|
||||
g_return_if_fail (tree != NULL);
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
inserted = FALSE;
|
||||
rtree->root = g_tree_node_insert (rtree->root, rtree->key_compare,
|
||||
rtree->key_compare_data,
|
||||
key, value, &inserted);
|
||||
rtree->root = g_tree_node_insert (tree,
|
||||
rtree->root,
|
||||
key, value,
|
||||
FALSE, &inserted);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_replace:
|
||||
* @tree: a #Gtree.
|
||||
* @key: the key to insert.
|
||||
* @value: the value corresponding to the key.
|
||||
*
|
||||
* Inserts a new key and value into a #GTree similar to g_tree_insert().
|
||||
* The difference is that if the key already exists in the #GTree, it gets
|
||||
* replaced by the new key. If you supplied a value_destroy_func when
|
||||
* creating the #GTree, the old value is freed using that function. If you
|
||||
* supplied a key_destroy_func when creating the #GTree, the old key is
|
||||
* freed using that function.
|
||||
*
|
||||
* The tree is automatically 'balanced' as new key/value pairs are added,
|
||||
* so that the distance from the root to every leaf is as small as possible.
|
||||
**/
|
||||
void
|
||||
g_tree_replace (GTree *tree,
|
||||
gpointer key,
|
||||
gpointer value)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
gboolean inserted;
|
||||
|
||||
g_return_if_fail (tree != NULL);
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
inserted = FALSE;
|
||||
rtree->root = g_tree_node_insert (tree,
|
||||
rtree->root,
|
||||
key, value,
|
||||
TRUE, &inserted);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_remove:
|
||||
* @tree: a #Gtree.
|
||||
* @key: the key to remove.
|
||||
*
|
||||
* Removes a key/value pair from a #GTree.
|
||||
*
|
||||
* If the #GTree was created using g_tree_new_full(), the key and value
|
||||
* are freed using the supplied destroy_functions, otherwise you have to
|
||||
* make sure that any dynamically allocated values are freed yourself.
|
||||
**/
|
||||
void
|
||||
g_tree_remove (GTree *tree,
|
||||
gconstpointer key)
|
||||
@ -220,10 +364,41 @@ g_tree_remove (GTree *tree,
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
rtree->root = g_tree_node_remove (rtree->root, rtree->key_compare,
|
||||
rtree->key_compare_data, key);
|
||||
rtree->root = g_tree_node_remove (tree, rtree->root, key, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_steal:
|
||||
* @tree: a #Gtree.
|
||||
* @key: the key to remove.
|
||||
*
|
||||
* Removes a key and its associated value from a #GTree without calling
|
||||
* the key and value destroy functions.
|
||||
**/
|
||||
void
|
||||
g_tree_steal (GTree *tree,
|
||||
gconstpointer key)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
|
||||
g_return_if_fail (tree != NULL);
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
rtree->root = g_tree_node_remove (tree, rtree->root, key, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_lookup:
|
||||
* @tree: a #GTree.
|
||||
* @key: the key to look up.
|
||||
*
|
||||
* Gets the value corresponding to the given key. Since a #GTree is
|
||||
* automatically balanced as key/value pairs are added, key lookup is very
|
||||
* fast.
|
||||
*
|
||||
* Return value: the value corresponding to the key.
|
||||
**/
|
||||
gpointer
|
||||
g_tree_lookup (GTree *tree,
|
||||
gconstpointer key)
|
||||
@ -235,12 +410,26 @@ g_tree_lookup (GTree *tree,
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
node = g_tree_node_lookup (rtree->root, rtree->key_compare,
|
||||
rtree->key_compare_data, key);
|
||||
node = g_tree_node_lookup (rtree->root,
|
||||
rtree->key_compare, rtree->key_compare_data, key);
|
||||
|
||||
return node ? node->value : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_lookup_extended:
|
||||
* @tree: a #GTree.
|
||||
* @lookup_key: the key to look up.
|
||||
* @orig_key: returns the original key.
|
||||
* @value: returns the value associated with the key.
|
||||
*
|
||||
* Looks up a key in the #GTree, returning the original key and the
|
||||
* associated value and a gboolean which is TRUE if the key was found. This
|
||||
* is useful if you need to free the memory allocated for the original key,
|
||||
* for example before calling g_tree_remove().
|
||||
*
|
||||
* Return value: #TRUE if the key was found in the #GTree.
|
||||
**/
|
||||
gboolean
|
||||
g_tree_lookup_extended (GTree *tree,
|
||||
gconstpointer lookup_key,
|
||||
@ -255,9 +444,7 @@ g_tree_lookup_extended (GTree *tree,
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
node = g_tree_node_lookup (rtree->root,
|
||||
rtree->key_compare,
|
||||
rtree->key_compare_data,
|
||||
lookup_key);
|
||||
rtree->key_compare, rtree->key_compare_data, lookup_key);
|
||||
|
||||
if (node)
|
||||
{
|
||||
@ -271,11 +458,51 @@ g_tree_lookup_extended (GTree *tree,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_foreach:
|
||||
* @tree: a #GTree.
|
||||
* @func: the function to call for each node visited. If this function
|
||||
* returns TRUE, the traversal is stopped.
|
||||
* @user_data: user data to pass to the function.
|
||||
*
|
||||
* Calls the given function for each of the key/value pairs in the #GTree.
|
||||
* The function is passed the key and value of each pair, and the given
|
||||
* @data parameter.
|
||||
**/
|
||||
void
|
||||
g_tree_foreach (GTree *tree,
|
||||
GTraverseFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
|
||||
g_return_if_fail (tree != NULL);
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
if (!rtree->root)
|
||||
return;
|
||||
|
||||
g_tree_node_in_order (rtree->root, func, user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_traverse:
|
||||
* @tree: a #GTree.
|
||||
* @traverse_func: the function to call for each node visited. If this
|
||||
* function returns TRUE, the traversal is stopped.
|
||||
* @traverse_type: the order in which nodes are visited, one of %G_IN_ORDER,
|
||||
* %G_PRE_ORDER and %G_POST_ORDER.
|
||||
* @user_data: user data to pass to the function.
|
||||
*
|
||||
* Calls the given function for each node in the GTree. This function is
|
||||
* deprecated, use g_tree_foreach() instead.
|
||||
**/
|
||||
void
|
||||
g_tree_traverse (GTree *tree,
|
||||
GTraverseFunc traverse_func,
|
||||
GTraverseType traverse_type,
|
||||
gpointer data)
|
||||
gpointer user_data)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
|
||||
@ -289,15 +516,15 @@ g_tree_traverse (GTree *tree,
|
||||
switch (traverse_type)
|
||||
{
|
||||
case G_PRE_ORDER:
|
||||
g_tree_node_pre_order (rtree->root, traverse_func, data);
|
||||
g_tree_node_pre_order (rtree->root, traverse_func, user_data);
|
||||
break;
|
||||
|
||||
case G_IN_ORDER:
|
||||
g_tree_node_in_order (rtree->root, traverse_func, data);
|
||||
g_tree_node_in_order (rtree->root, traverse_func, user_data);
|
||||
break;
|
||||
|
||||
case G_POST_ORDER:
|
||||
g_tree_node_post_order (rtree->root, traverse_func, data);
|
||||
g_tree_node_post_order (rtree->root, traverse_func, user_data);
|
||||
break;
|
||||
|
||||
case G_LEVEL_ORDER:
|
||||
@ -306,10 +533,32 @@ g_tree_traverse (GTree *tree,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_search:
|
||||
* @tree: a #GTree.
|
||||
* @search_func: the comparison function used to search the #GTree.
|
||||
* @user_data: the data passed as the second argument to the @search_func
|
||||
* function.
|
||||
*
|
||||
* Searches a #GTree using an alternative form of the comparison function.
|
||||
*
|
||||
* This function is not as useful as it sounds.
|
||||
* It allows you to use a different function for performing the lookup of
|
||||
* a key. However, since the tree is ordered according to the @key_compare_func
|
||||
* function passed to g_tree_new(), the function you pass to g_tree_search()
|
||||
* must return exactly the same value as would be returned by the comparison
|
||||
* function, for each pair of tree nodes, or the search will not work.
|
||||
*
|
||||
* To search for a specific value, you can use g_tree_foreach() or
|
||||
* g_tree_traverse().
|
||||
*
|
||||
* Return value: the value corresponding to the found key, or NULL if the key
|
||||
* is not found.
|
||||
**/
|
||||
gpointer
|
||||
g_tree_search (GTree *tree,
|
||||
GCompareFunc search_func,
|
||||
gconstpointer data)
|
||||
g_tree_search (GTree *tree,
|
||||
GCompareFunc search_func,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
|
||||
@ -318,11 +567,23 @@ g_tree_search (GTree *tree,
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
if (rtree->root)
|
||||
return g_tree_node_search (rtree->root, search_func, data);
|
||||
return g_tree_node_search (rtree->root, search_func, user_data);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_height:
|
||||
* @tree: a #GTree.
|
||||
*
|
||||
* Gets the height of a #GTree.
|
||||
*
|
||||
* If the #GTree contains no nodes, the height is 0.
|
||||
* If the #GTree contains only one root node the height is 1.
|
||||
* If the root node has children the height is 2, etc.
|
||||
*
|
||||
* Return value: the height of the #GTree.
|
||||
**/
|
||||
gint
|
||||
g_tree_height (GTree *tree)
|
||||
{
|
||||
@ -338,6 +599,14 @@ g_tree_height (GTree *tree)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_tree_nnodes:
|
||||
* @tree: a #GTree.
|
||||
*
|
||||
* Gets the number of nodes in a #GTree.
|
||||
*
|
||||
* Return value: the number of nodes in the #GTree.
|
||||
**/
|
||||
gint
|
||||
g_tree_nnodes (GTree *tree)
|
||||
{
|
||||
@ -354,15 +623,18 @@ g_tree_nnodes (GTree *tree)
|
||||
}
|
||||
|
||||
static GTreeNode*
|
||||
g_tree_node_insert (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer compare_data,
|
||||
gpointer key,
|
||||
gpointer value,
|
||||
gint *inserted)
|
||||
g_tree_node_insert (GTree *tree,
|
||||
GTreeNode *node,
|
||||
gpointer key,
|
||||
gpointer value,
|
||||
gboolean replace,
|
||||
gboolean *inserted)
|
||||
{
|
||||
gint old_balance;
|
||||
gint cmp;
|
||||
GRealTree *rtree;
|
||||
gint old_balance;
|
||||
gint cmp;
|
||||
|
||||
rtree = (GRealTree*) tree;
|
||||
|
||||
if (!node)
|
||||
{
|
||||
@ -370,11 +642,30 @@ g_tree_node_insert (GTreeNode *node,
|
||||
return g_tree_node_new (key, value);
|
||||
}
|
||||
|
||||
cmp = (* compare) (key, node->key, compare_data);
|
||||
cmp = rtree->key_compare (key, node->key, rtree->key_compare_data);
|
||||
if (cmp == 0)
|
||||
{
|
||||
*inserted = FALSE;
|
||||
|
||||
if (rtree->value_destroy_func)
|
||||
rtree->value_destroy_func (node->value);
|
||||
|
||||
node->value = value;
|
||||
|
||||
if (replace)
|
||||
{
|
||||
if (rtree->key_destroy_func)
|
||||
rtree->key_destroy_func (node->key);
|
||||
|
||||
node->key = key;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* free the passed key */
|
||||
if (rtree->key_destroy_func)
|
||||
rtree->key_destroy_func (key);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -383,8 +674,10 @@ g_tree_node_insert (GTreeNode *node,
|
||||
if (node->left)
|
||||
{
|
||||
old_balance = node->left->balance;
|
||||
node->left = g_tree_node_insert (node->left, compare, compare_data,
|
||||
key, value, inserted);
|
||||
node->left = g_tree_node_insert (tree,
|
||||
node->left,
|
||||
key, value,
|
||||
replace, inserted);
|
||||
|
||||
if ((old_balance != node->left->balance) && node->left->balance)
|
||||
node->balance -= 1;
|
||||
@ -401,8 +694,10 @@ g_tree_node_insert (GTreeNode *node,
|
||||
if (node->right)
|
||||
{
|
||||
old_balance = node->right->balance;
|
||||
node->right = g_tree_node_insert (node->right, compare, compare_data,
|
||||
key, value, inserted);
|
||||
node->right = g_tree_node_insert (tree,
|
||||
node->right,
|
||||
key, value,
|
||||
replace, inserted);
|
||||
|
||||
if ((old_balance != node->right->balance) && node->right->balance)
|
||||
node->balance += 1;
|
||||
@ -425,11 +720,12 @@ g_tree_node_insert (GTreeNode *node,
|
||||
}
|
||||
|
||||
static GTreeNode*
|
||||
g_tree_node_remove (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer compare_data,
|
||||
gconstpointer key)
|
||||
g_tree_node_remove (GTree *tree,
|
||||
GTreeNode *node,
|
||||
gconstpointer key,
|
||||
gboolean notify)
|
||||
{
|
||||
GRealTree *rtree;
|
||||
GTreeNode *new_root;
|
||||
gint old_balance;
|
||||
gint cmp;
|
||||
@ -437,7 +733,9 @@ g_tree_node_remove (GTreeNode *node,
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
cmp = (* compare) (key, node->key, compare_data);
|
||||
rtree = (GRealTree *) tree;
|
||||
|
||||
cmp = rtree->key_compare (key, node->key, rtree->key_compare_data);
|
||||
if (cmp == 0)
|
||||
{
|
||||
GTreeNode *garbage;
|
||||
@ -458,6 +756,14 @@ g_tree_node_remove (GTreeNode *node,
|
||||
node = g_tree_node_restore_right_balance (new_root, old_balance);
|
||||
}
|
||||
|
||||
if (notify)
|
||||
{
|
||||
if (rtree->key_destroy_func)
|
||||
rtree->key_destroy_func (garbage->key);
|
||||
if (rtree->value_destroy_func)
|
||||
rtree->value_destroy_func (garbage->value);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_GC_FRIENDLY
|
||||
garbage->left = NULL;
|
||||
garbage->key = NULL;
|
||||
@ -474,7 +780,7 @@ g_tree_node_remove (GTreeNode *node,
|
||||
if (node->left)
|
||||
{
|
||||
old_balance = node->left->balance;
|
||||
node->left = g_tree_node_remove (node->left, compare, compare_data, key);
|
||||
node->left = g_tree_node_remove (tree, node->left, key, notify);
|
||||
node = g_tree_node_restore_left_balance (node, old_balance);
|
||||
}
|
||||
}
|
||||
@ -483,7 +789,7 @@ g_tree_node_remove (GTreeNode *node,
|
||||
if (node->right)
|
||||
{
|
||||
old_balance = node->right->balance;
|
||||
node->right = g_tree_node_remove (node->right, compare, compare_data, key);
|
||||
node->right = g_tree_node_remove (tree, node->right, key, notify);
|
||||
node = g_tree_node_restore_right_balance (node, old_balance);
|
||||
}
|
||||
}
|
||||
@ -558,10 +864,10 @@ g_tree_node_restore_right_balance (GTreeNode *node,
|
||||
}
|
||||
|
||||
static GTreeNode *
|
||||
g_tree_node_lookup (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer compare_data,
|
||||
gconstpointer key)
|
||||
g_tree_node_lookup (GTreeNode *node,
|
||||
GCompareDataFunc compare,
|
||||
gpointer compare_data,
|
||||
gconstpointer key)
|
||||
{
|
||||
gint cmp;
|
||||
|
||||
|
18
gtree.h
18
gtree.h
@ -41,26 +41,38 @@ typedef gint (*GTraverseFunc) (gpointer key,
|
||||
*/
|
||||
GTree* g_tree_new (GCompareFunc key_compare_func);
|
||||
GTree* g_tree_new_with_data (GCompareDataFunc key_compare_func,
|
||||
gpointer user_data);
|
||||
gpointer key_compare_data);
|
||||
GTree* g_tree_new_full (GCompareDataFunc key_compare_func,
|
||||
gpointer key_compare_data,
|
||||
GDestroyNotify key_destroy_func,
|
||||
GDestroyNotify value_destroy_func);
|
||||
void g_tree_destroy (GTree *tree);
|
||||
void g_tree_insert (GTree *tree,
|
||||
gpointer key,
|
||||
gpointer value);
|
||||
void g_tree_replace (GTree *tree,
|
||||
gpointer key,
|
||||
gpointer value);
|
||||
void g_tree_remove (GTree *tree,
|
||||
gconstpointer key);
|
||||
void g_tree_steal (GTree *tree,
|
||||
gconstpointer key);
|
||||
gpointer g_tree_lookup (GTree *tree,
|
||||
gconstpointer key);
|
||||
gboolean g_tree_lookup_extended (GTree *tree,
|
||||
gconstpointer lookup_key,
|
||||
gpointer *orig_key,
|
||||
gpointer *value);
|
||||
void g_tree_foreach (GTree *tree,
|
||||
GTraverseFunc func,
|
||||
gpointer user_data);
|
||||
void g_tree_traverse (GTree *tree,
|
||||
GTraverseFunc traverse_func,
|
||||
GTraverseType traverse_type,
|
||||
gpointer data);
|
||||
gpointer user_data);
|
||||
gpointer g_tree_search (GTree *tree,
|
||||
GCompareFunc search_func,
|
||||
gconstpointer data);
|
||||
gconstpointer user_data);
|
||||
gint g_tree_height (GTree *tree);
|
||||
gint g_tree_nnodes (GTree *tree);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user