ghash.[ch] added new functions g_hash_table_new_full,

2001-03-30  Sven Neumann  <sven@gimp.org>

        * ghash.[ch]
        * docs/reference/glib/tmpl/hash_tables.sgml: added new functions
        g_hash_table_new_full, g_hash_table_replace, g_hash_table_steal and
        g_hash_table_foreach_steal. Moved most docs out of the template
        file into the C file. Please proofread the new documentation.
This commit is contained in:
Sven Neumann 2001-03-30 18:14:41 +00:00 committed by Sven Neumann
parent 9228b3327f
commit a2b269bae3
13 changed files with 1000 additions and 347 deletions

View File

@ -1,3 +1,11 @@
2001-03-30 Sven Neumann <sven@gimp.org>
* ghash.[ch]
* docs/reference/glib/tmpl/hash_tables.sgml: added new functions
g_hash_table_new_full, g_hash_table_replace, g_hash_table_steal and
g_hash_table_foreach_steal. Moved most docs out of the template
file into the C file. Please proofread the new documentation.
2001-03-29 Tor Lillqvist <tml@iki.fi>
* glib.def: Updates.

View File

@ -1,3 +1,11 @@
2001-03-30 Sven Neumann <sven@gimp.org>
* ghash.[ch]
* docs/reference/glib/tmpl/hash_tables.sgml: added new functions
g_hash_table_new_full, g_hash_table_replace, g_hash_table_steal and
g_hash_table_foreach_steal. Moved most docs out of the template
file into the C file. Please proofread the new documentation.
2001-03-29 Tor Lillqvist <tml@iki.fi>
* glib.def: Updates.

View File

@ -1,3 +1,11 @@
2001-03-30 Sven Neumann <sven@gimp.org>
* ghash.[ch]
* docs/reference/glib/tmpl/hash_tables.sgml: added new functions
g_hash_table_new_full, g_hash_table_replace, g_hash_table_steal and
g_hash_table_foreach_steal. Moved most docs out of the template
file into the C file. Please proofread the new documentation.
2001-03-29 Tor Lillqvist <tml@iki.fi>
* glib.def: Updates.

View File

@ -1,3 +1,11 @@
2001-03-30 Sven Neumann <sven@gimp.org>
* ghash.[ch]
* docs/reference/glib/tmpl/hash_tables.sgml: added new functions
g_hash_table_new_full, g_hash_table_replace, g_hash_table_steal and
g_hash_table_foreach_steal. Moved most docs out of the template
file into the C file. Please proofread the new documentation.
2001-03-29 Tor Lillqvist <tml@iki.fi>
* glib.def: Updates.

View File

@ -1,3 +1,11 @@
2001-03-30 Sven Neumann <sven@gimp.org>
* ghash.[ch]
* docs/reference/glib/tmpl/hash_tables.sgml: added new functions
g_hash_table_new_full, g_hash_table_replace, g_hash_table_steal and
g_hash_table_foreach_steal. Moved most docs out of the template
file into the C file. Please proofread the new documentation.
2001-03-29 Tor Lillqvist <tml@iki.fi>
* glib.def: Updates.

View File

@ -1,3 +1,11 @@
2001-03-30 Sven Neumann <sven@gimp.org>
* ghash.[ch]
* docs/reference/glib/tmpl/hash_tables.sgml: added new functions
g_hash_table_new_full, g_hash_table_replace, g_hash_table_steal and
g_hash_table_foreach_steal. Moved most docs out of the template
file into the C file. Please proofread the new documentation.
2001-03-29 Tor Lillqvist <tml@iki.fi>
* glib.def: Updates.

View File

@ -1,3 +1,11 @@
2001-03-30 Sven Neumann <sven@gimp.org>
* ghash.[ch]
* docs/reference/glib/tmpl/hash_tables.sgml: added new functions
g_hash_table_new_full, g_hash_table_replace, g_hash_table_steal and
g_hash_table_foreach_steal. Moved most docs out of the template
file into the C file. Please proofread the new documentation.
2001-03-29 Tor Lillqvist <tml@iki.fi>
* glib.def: Updates.

View File

@ -1,3 +1,11 @@
2001-03-30 Sven Neumann <sven@gimp.org>
* ghash.[ch]
* docs/reference/glib/tmpl/hash_tables.sgml: added new functions
g_hash_table_new_full, g_hash_table_replace, g_hash_table_steal and
g_hash_table_foreach_steal. Moved most docs out of the template
file into the C file. Please proofread the new documentation.
2001-03-29 Tor Lillqvist <tml@iki.fi>
* glib.def: Updates.

View File

@ -61,23 +61,12 @@ It should only be accessed via the following functions.
<!-- ##### FUNCTION g_hash_table_new ##### -->
<para>
Creates a new #GHashTable.
</para>
@hash_func: a function to create a hash value from a key.
Hash values are used to determine where keys are stored within the
#GHashTable data structure.
The g_direct_hash(), g_int_hash() and g_str_hash() functions are provided for
some common types of keys. If hash_func is NULL, g_direct_hash() is used.
@key_equal_func: a function to check two keys for equality. This is
used when looking up keys in the #GHashTable. The g_direct_equal(),
g_int_equal() and g_str_equal() functions are provided for the most
common types of keys. If @key_equal_func is NULL, keys are compared
directly in a similar fashion to g_direct_equal(), but without the
overhead of a function call.
@Returns: a new #GHashTable.
<!-- # Unused Parameters # -->
@key_compare_func:
@hash_func:
@key_equal_func:
@Returns:
<!-- ##### USER_FUNCTION GHashFunc ##### -->
@ -118,69 +107,53 @@ FALSE otherwise.
<!-- ##### FUNCTION g_hash_table_insert ##### -->
<para>
Inserts a new key and value into a #GHashTable.
If the key already exists in the #GHashTable its current value is replaced
with the new value.
</para>
<note>
<para>
If the keys or values use dynamically allocated memory, then you should
first check if the key already exists in the GHashTable. If it does,
you should free the existing key and/or value before inserting the
new key and value.
</para>
</note>
@hash_table: a #GHashTable.
@key: a key to insert.
@value: the value to associate with the key.
</para>
@hash_table:
@key:
@value:
<!-- ##### FUNCTION g_hash_table_size ##### -->
<para>
Returns the number of key/value pairs in a #GHashTable.
</para>
@hash_table: a #GHashTable.
@Returns: the number of key/value pairs in the #GHashTable.
@hash_table:
@Returns:
<!-- ##### FUNCTION g_hash_table_lookup ##### -->
<para>
Looks up a key in the #GHashTable, returning the associated value or NULL
if the key is not found.
</para>
@hash_table: a #GHashTable.
@key: the key to look up.
@Returns: the associated value, or NULL if the key is not found.
@hash_table:
@key:
@Returns:
<!-- ##### FUNCTION g_hash_table_lookup_extended ##### -->
<para>
Looks up a key in the #GHashTable, 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_hash_table_remove().
</para>
@hash_table: a #GHashTable.
@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 #GHashTable.
@hash_table:
@lookup_key:
@orig_key:
@value:
@Returns:
<!-- ##### FUNCTION g_hash_table_foreach ##### -->
<para>
Calls the given function for each of the key/value pairs in the #GHashTable.
The function is passed the key and value of each pair, and the given
@user_data parameter.
</para>
@hash_table: a #GHashTable.
@func: the function to call for each key/value pair.
@user_data: use data to pass to the function.
@hash_table:
@func:
@user_data:
<!-- ##### USER_FUNCTION GHFunc ##### -->
@ -197,31 +170,23 @@ which is passed to g_hash_table_foreach().
<!-- ##### FUNCTION g_hash_table_remove ##### -->
<para>
Removes a key and its associated value from a #GHashTable.
</para>
<note>
<para>
As with g_hash_table_insert(), you should make sure that any dynamically
allocated values are freed yourself.
</para>
</note>
@hash_table: a #GHashTable.
@key: the key to remove.
</para>
@hash_table:
@key:
@Returns:
<!-- ##### FUNCTION g_hash_table_foreach_remove ##### -->
<para>
Calls the given function for each key/value pair in the #GHashTable.
If the function returns TRUE, then the key/value pair is removed from the
#GHashTable.
</para>
@hash_table: a #GHashTable.
@func: the function to call for each key/value pair.
@user_data: user data to pass to the function.
@Returns: the number of key/value paris removed.
@hash_table:
@func:
@user_data:
@Returns:
<!-- ##### USER_FUNCTION GHRFunc ##### -->
@ -241,8 +206,7 @@ It should return TRUE if the key/value pair should be removed from the
<!-- ##### FUNCTION g_hash_table_freeze ##### -->
<para>
This function is deprecated and will be removed in the next major
release of GLib. It does nothing.
</para>
@hash_table:
@ -250,8 +214,7 @@ release of GLib. It does nothing.
<!-- ##### FUNCTION g_hash_table_thaw ##### -->
<para>
This function is deprecated and will be removed in the next major
release of GLib. It does nothing.
</para>
@hash_table:
@ -259,16 +222,10 @@ release of GLib. It does nothing.
<!-- ##### FUNCTION g_hash_table_destroy ##### -->
<para>
Destroys the #GHashTable.
</para>
<note>
<para>
If keys and/or values are dynamically allocated, you should free them
first.
</para>
</note>
@hash_table: a #GHashTable.
</para>
@hash_table:
<!-- ##### FUNCTION g_direct_equal ##### -->

496
ghash.c
View File

@ -43,28 +43,38 @@ typedef struct _GHashNode GHashNode;
struct _GHashNode
{
gpointer key;
gpointer value;
gpointer key;
gpointer value;
GHashNode *next;
};
struct _GHashTable
{
gint size;
gint nnodes;
GHashNode **nodes;
GHashFunc hash_func;
GEqualFunc key_equal_func;
gint size;
gint nnodes;
GHashNode **nodes;
GHashFunc hash_func;
GEqualFunc key_equal_func;
GDestroyNotify key_destroy_func;
GDestroyNotify value_destroy_func;
};
static void g_hash_table_resize (GHashTable *hash_table);
static GHashNode** g_hash_table_lookup_node (GHashTable *hash_table,
gconstpointer key);
static GHashNode* g_hash_node_new (gpointer key,
gpointer value);
static void g_hash_node_destroy (GHashNode *hash_node);
static void g_hash_nodes_destroy (GHashNode *hash_node);
static void g_hash_table_resize (GHashTable *hash_table);
static GHashNode** g_hash_table_lookup_node (GHashTable *hash_table,
gconstpointer key);
static GHashNode* g_hash_node_new (gpointer key,
gpointer value);
static void g_hash_node_destroy (GHashNode *hash_node,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func);
static void g_hash_nodes_destroy (GHashNode *hash_node,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func);
static guint g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
GHRFunc func,
gpointer user_data,
gboolean notify);
G_LOCK_DEFINE_STATIC (g_hash_global);
@ -72,20 +82,66 @@ G_LOCK_DEFINE_STATIC (g_hash_global);
static GMemChunk *node_mem_chunk = NULL;
static GHashNode *node_free_list = NULL;
/**
* g_hash_table_new:
* @hash_func: a function to create a hash value from a key.
* Hash values are used to determine where keys are stored within the
* #GHashTable data structure. The g_direct_hash(), g_int_hash() and
* g_str_hash() functions are provided for some common types of keys.
* If hash_func is NULL, g_direct_hash() is used.
* @key_equal_func: a function to check two keys for equality. This is
* used when looking up keys in the #GHashTable. The g_direct_equal(),
* g_int_equal() and g_str_equal() functions are provided for the most
* common types of keys. If @key_equal_func is NULL, keys are compared
* directly in a similar fashion to g_direct_equal(), but without the
* overhead of a function call.
*
* Creates a new #GHashTable.
*
* Return value: a new #GHashTable.
**/
GHashTable*
g_hash_table_new (GHashFunc hash_func,
GEqualFunc key_equal_func)
{
return g_hash_table_new_full (hash_func, key_equal_func, NULL, NULL);
}
/**
* g_hash_table_new_full:
* @hash_func: a function to create a hash value from a key.
* @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.
* @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.
*
* Creates a new #GHashTable like g_hash_table_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 #GHashTable.
*
* Return value: a new #GHashTable.
**/
GHashTable*
g_hash_table_new_full (GHashFunc hash_func,
GEqualFunc key_equal_func,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func)
{
GHashTable *hash_table;
guint i;
hash_table = g_new (GHashTable, 1);
hash_table->size = HASH_TABLE_MIN_SIZE;
hash_table->nnodes = 0;
hash_table->hash_func = hash_func ? hash_func : g_direct_hash;
hash_table->key_equal_func = key_equal_func;
hash_table->nodes = g_new (GHashNode*, hash_table->size);
hash_table->size = HASH_TABLE_MIN_SIZE;
hash_table->nnodes = 0;
hash_table->hash_func = hash_func ? hash_func : g_direct_hash;
hash_table->key_equal_func = key_equal_func;
hash_table->key_destroy_func = key_destroy_func;
hash_table->value_destroy_func = value_destroy_func;
hash_table->nodes = g_new (GHashNode*, hash_table->size);
for (i = 0; i < hash_table->size; i++)
hash_table->nodes[i] = NULL;
@ -93,6 +149,16 @@ g_hash_table_new (GHashFunc hash_func,
return hash_table;
}
/**
* g_hash_table_destroy:
* @hash_table: a #GHashTable.
*
* Destroys the #GHashTable. If keys and/or values are dynamically
* allocated, you should either free them first or create the #GHashTable
* using g_hash_table_new_full(). In the latter case the destroy functions
* you supplied will be called on all keys and values before destroying
* the #GHashTable.
**/
void
g_hash_table_destroy (GHashTable *hash_table)
{
@ -101,7 +167,9 @@ g_hash_table_destroy (GHashTable *hash_table)
g_return_if_fail (hash_table != NULL);
for (i = 0; i < hash_table->size; i++)
g_hash_nodes_destroy (hash_table->nodes[i]);
g_hash_nodes_destroy (hash_table->nodes[i],
hash_table->key_destroy_func,
hash_table->value_destroy_func);
g_free (hash_table->nodes);
g_free (hash_table);
@ -131,6 +199,15 @@ g_hash_table_lookup_node (GHashTable *hash_table,
return node;
}
/**
* g_hash_table_lookup:
* @hash_table: a #GHashTable.
* @key: the key to look up.
*
* Looks up a key in a #GHashTable.
*
* Return value: the associated value, or NULL if the key is not found.
**/
gpointer
g_hash_table_lookup (GHashTable *hash_table,
gconstpointer key)
@ -144,64 +221,25 @@ g_hash_table_lookup (GHashTable *hash_table,
return node ? node->value : NULL;
}
void
g_hash_table_insert (GHashTable *hash_table,
gpointer key,
gpointer value)
{
GHashNode **node;
g_return_if_fail (hash_table != NULL);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
/* do not reset node->key in this place, keeping
* the old key might be intended.
* a g_hash_table_remove/g_hash_table_insert pair
* can be used otherwise.
*
* node->key = key; */
(*node)->value = value;
}
else
{
*node = g_hash_node_new (key, value);
hash_table->nnodes++;
g_hash_table_resize (hash_table);
}
}
/**
* g_hash_table_lookup_extended:
* @hash_table: a #GHashTable.
* @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 #GHashTable, 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_hash_table_remove().
*
* Return value: #TRUE if the key was found in the #GHashTable.
**/
gboolean
g_hash_table_remove (GHashTable *hash_table,
gconstpointer key)
{
GHashNode **node, *dest;
g_return_val_if_fail (hash_table != NULL, FALSE);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
dest = *node;
(*node) = dest->next;
g_hash_node_destroy (dest);
hash_table->nnodes--;
g_hash_table_resize (hash_table);
return TRUE;
}
return FALSE;
}
gboolean
g_hash_table_lookup_extended (GHashTable *hash_table,
gconstpointer lookup_key,
gpointer *orig_key,
gpointer *value)
g_hash_table_lookup_extended (GHashTable *hash_table,
gconstpointer lookup_key,
gpointer *orig_key,
gpointer *value)
{
GHashNode *node;
@ -221,37 +259,230 @@ g_hash_table_lookup_extended (GHashTable *hash_table,
return FALSE;
}
/**
* g_hash_table_insert:
* @hash_table: a #GHashTable.
* @key: a key to insert.
* @value: the value to associate with the key.
*
* Inserts a new key and value into a #GHashTable.
*
* If the key already exists in the #GHashTable its current value is replaced
* with the new value. If you supplied a value_destroy_func when creating the
* #GHashTable, the old value is freed using that function. If you supplied
* a key_destroy_func when creating the #GHashTable, the passed key is freed
* using that function.
**/
void
g_hash_table_freeze (GHashTable *hash_table)
g_hash_table_insert (GHashTable *hash_table,
gpointer key,
gpointer value)
{
#ifdef G_ENABLE_DEBUG
static gboolean first_call = TRUE;
if (first_call)
GHashNode **node;
g_return_if_fail (hash_table != NULL);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
g_warning("g_hash_table_freeze and g_hash_table_thaw are deprecated.");
first_call = FALSE;
/* do not reset node->key in this place, keeping
* the old key is the intended behaviour.
* g_hash_table_replace() can be used instead.
*/
/* free the passed key */
if (hash_table->key_destroy_func)
hash_table->key_destroy_func (key);
if (hash_table->value_destroy_func)
hash_table->value_destroy_func ((*node)->value);
(*node)->value = value;
}
else
{
*node = g_hash_node_new (key, value);
hash_table->nnodes++;
g_hash_table_resize (hash_table);
}
#endif /* G_ENABLE_DEBUG */
}
/**
* g_hash_table_replace:
* @hash_table: a #GHashTable.
* @key: a key to insert.
* @value: the value to associate with the key.
*
* Inserts a new key and value into a #GHashTable similar to
* g_hash_table_insert(). The difference is that if the key already exists
* in the #GHashTable, it gets replaced by the new key. If you supplied a
* value_destroy_func when creating the #GHashTable, the old value is freed
* using that function. If you supplied a key_destroy_func when creating the
* #GHashTable, the old key is freed using that function.
**/
void
g_hash_table_thaw (GHashTable *hash_table)
g_hash_table_replace (GHashTable *hash_table,
gpointer key,
gpointer value)
{
GHashNode **node;
g_return_if_fail (hash_table != NULL);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
if (hash_table->key_destroy_func)
hash_table->key_destroy_func ((*node)->key);
if (hash_table->value_destroy_func)
hash_table->value_destroy_func ((*node)->value);
(*node)->key = key;
(*node)->value = value;
}
else
{
*node = g_hash_node_new (key, value);
hash_table->nnodes++;
g_hash_table_resize (hash_table);
}
}
/**
* g_hash_table_remove:
* @hash_table: a #GHashTable.
* @key: the key to remove.
*
* Removes a key and its associated value from a #GHashTable.
*
* If the #GHashTable was created using g_hash_table_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.
*
* Return value: #TRUE if the key was found and removed from the #GHashTable.
**/
gboolean
g_hash_table_remove (GHashTable *hash_table,
gconstpointer key)
{
GHashNode **node, *dest;
g_return_val_if_fail (hash_table != NULL, FALSE);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
dest = *node;
(*node) = dest->next;
g_hash_node_destroy (dest,
hash_table->key_destroy_func,
hash_table->value_destroy_func);
hash_table->nnodes--;
g_hash_table_resize (hash_table);
return TRUE;
}
return FALSE;
}
/**
* g_hash_table_steal:
* @hash_table: a #GHashTable.
* @key: the key to remove.
*
* Removes a key and its associated value from a #GHashTable without
* calling the key and value destroy functions.
*
* Return value: #TRUE if the key was found and removed from the #GHashTable.
**/
gboolean
g_hash_table_steal (GHashTable *hash_table,
gconstpointer key)
{
GHashNode **node, *dest;
g_return_val_if_fail (hash_table != NULL, FALSE);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
dest = *node;
(*node) = dest->next;
g_hash_node_destroy (dest, NULL, NULL);
hash_table->nnodes--;
g_hash_table_resize (hash_table);
return TRUE;
}
return FALSE;
}
/**
* g_hash_table_foreach_remove:
* @hash_table: a #GHashTable.
* @func: the function to call for each key/value pair.
* @user_data: user data to pass to the function.
*
* Calls the given function for each key/value pair in the #GHashTable.
* If the function returns TRUE, then the key/value pair is removed from the
* #GHashTable. If you supplied key or value destroy functions when creating
* the #GHashTable, they are used to free the memory allocated for the removed
* keys and values.
*
* Return value: the number of key/value pairs removed.
**/
guint
g_hash_table_foreach_remove (GHashTable *hash_table,
GHRFunc func,
gpointer user_data)
{
g_return_val_if_fail (hash_table != NULL, 0);
g_return_val_if_fail (func != NULL, 0);
return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, TRUE);
}
/**
* g_hash_table_foreach_steal:
* @hash_table: a #GHashTable.
* @func: the function to call for each key/value pair.
* @user_data: user data to pass to the function.
*
* Calls the given function for each key/value pair in the #GHashTable.
* If the function returns TRUE, then the key/value pair is removed from the
* #GHashTable, but no key or value destroy functions are called.
*
* Return value: the number of key/value pairs removed.
**/
guint
g_hash_table_foreach_steal (GHashTable *hash_table,
GHRFunc func,
gpointer user_data)
{
g_return_val_if_fail (hash_table != NULL, 0);
g_return_val_if_fail (func != NULL, 0);
return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, FALSE);
}
static guint
g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
GHRFunc func,
gpointer user_data,
gboolean notify)
{
GHashNode *node, *prev;
guint i;
guint deleted = 0;
g_return_val_if_fail (hash_table != NULL, 0);
g_return_val_if_fail (func != NULL, 0);
for (i = 0; i < hash_table->size; i++)
{
restart:
@ -269,13 +500,17 @@ g_hash_table_foreach_remove (GHashTable *hash_table,
if (prev)
{
prev->next = node->next;
g_hash_node_destroy (node);
g_hash_node_destroy (node,
notify ? hash_table->value_destroy_func : NULL,
notify ? hash_table->key_destroy_func : NULL);
node = prev;
}
else
{
hash_table->nodes[i] = node->next;
g_hash_node_destroy (node);
g_hash_node_destroy (node,
notify ? hash_table->value_destroy_func : NULL,
notify ? hash_table->key_destroy_func : NULL);
goto restart;
}
}
@ -287,6 +522,16 @@ g_hash_table_foreach_remove (GHashTable *hash_table,
return deleted;
}
/**
* g_hash_table_foreach:
* @hash_table: a #GHashTable.
* @func: the function to call for each key/value pair.
* @user_data: user data to pass to the function.
*
* Calls the given function for each of the key/value pairs in the #GHashTable.
* The function is passed the key and value of each pair, and the given
* @user_data parameter.
**/
void
g_hash_table_foreach (GHashTable *hash_table,
GHFunc func,
@ -303,7 +548,14 @@ g_hash_table_foreach (GHashTable *hash_table,
(* func) (node->key, node->value, user_data);
}
/* Returns the number of elements contained in the hash table. */
/**
* g_hash_table_size:
* @hash_table: a #GHashTable.
*
* Returns the number of elements contained in the #GHashTable.
*
* Return value: the number of key/value pairs in the #GHashTable.
**/
guint
g_hash_table_size (GHashTable *hash_table)
{
@ -312,6 +564,39 @@ g_hash_table_size (GHashTable *hash_table)
return hash_table->nnodes;
}
/**
* g_hash_table_freeze:
* @hash_table: a #GHashTable.
*
* This function is deprecated and will be removed in the next major
* release of GLib. It does nothing.
**/
void
g_hash_table_freeze (GHashTable *hash_table)
{
#ifdef G_ENABLE_DEBUG
static gboolean first_call = TRUE;
if (first_call)
{
g_warning("g_hash_table_freeze and g_hash_table_thaw are deprecated.");
first_call = FALSE;
}
#endif /* G_ENABLE_DEBUG */
}
/**
* g_hash_table_thaw:
* @hash_table: a #GHashTable.
*
* This function is deprecated and will be removed in the next major
* release of GLib. It does nothing.
**/
void
g_hash_table_thaw (GHashTable *hash_table)
{
}
static void
g_hash_table_resize (GHashTable *hash_table)
{
@ -381,9 +666,15 @@ g_hash_node_new (gpointer key,
}
static void
g_hash_node_destroy (GHashNode *hash_node)
g_hash_node_destroy (GHashNode *hash_node,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func)
{
if (key_destroy_func)
key_destroy_func (hash_node->key);
if (value_destroy_func)
value_destroy_func (hash_node->value);
#ifdef ENABLE_GC_FRIENDLY
hash_node->key = NULL;
hash_node->value = NULL;
@ -396,7 +687,9 @@ g_hash_node_destroy (GHashNode *hash_node)
}
static void
g_hash_nodes_destroy (GHashNode *hash_node)
g_hash_nodes_destroy (GHashNode *hash_node,
GFreeFunc key_destroy_func,
GFreeFunc value_destroy_func)
{
if (hash_node)
{
@ -404,13 +697,24 @@ g_hash_nodes_destroy (GHashNode *hash_node)
while (node->next)
{
if (key_destroy_func)
key_destroy_func (node->key);
if (value_destroy_func)
value_destroy_func (node->value);
#ifdef ENABLE_GC_FRIENDLY
node->key = NULL;
node->value = NULL;
#endif /* ENABLE_GC_FRIENDLY */
node = node->next;
}
if (key_destroy_func)
key_destroy_func (node->key);
if (value_destroy_func)
value_destroy_func (node->value);
#ifdef ENABLE_GC_FRIENDLY
node->key = NULL;
node->value = NULL;

84
ghash.h
View File

@ -31,50 +31,62 @@
G_BEGIN_DECLS
typedef struct _GHashTable GHashTable;
typedef struct _GHashTable GHashTable;
typedef gboolean (*GHRFunc) (gpointer key,
gpointer value,
gpointer user_data);
typedef gboolean (*GHRFunc) (gpointer key,
gpointer value,
gpointer user_data);
/* Hash tables
*/
GHashTable* g_hash_table_new (GHashFunc hash_func,
GEqualFunc key_equal_func);
void g_hash_table_destroy (GHashTable *hash_table);
void g_hash_table_insert (GHashTable *hash_table,
gpointer key,
gpointer value);
gboolean g_hash_table_remove (GHashTable *hash_table,
gconstpointer key);
gpointer g_hash_table_lookup (GHashTable *hash_table,
gconstpointer key);
gboolean g_hash_table_lookup_extended(GHashTable *hash_table,
gconstpointer lookup_key,
gpointer *orig_key,
gpointer *value);
void g_hash_table_foreach (GHashTable *hash_table,
GHFunc func,
gpointer user_data);
guint g_hash_table_foreach_remove (GHashTable *hash_table,
GHRFunc func,
gpointer user_data);
guint g_hash_table_size (GHashTable *hash_table);
GHashTable* g_hash_table_new (GHashFunc hash_func,
GEqualFunc key_equal_func);
GHashTable* g_hash_table_new_full (GHashFunc hash_func,
GEqualFunc key_equal_func,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func);
void g_hash_table_destroy (GHashTable *hash_table);
void g_hash_table_insert (GHashTable *hash_table,
gpointer key,
gpointer value);
void g_hash_table_replace (GHashTable *hash_table,
gpointer key,
gpointer value);
gboolean g_hash_table_remove (GHashTable *hash_table,
gconstpointer key);
gboolean g_hash_table_steal (GHashTable *hash_table,
gconstpointer key);
gpointer g_hash_table_lookup (GHashTable *hash_table,
gconstpointer key);
gboolean g_hash_table_lookup_extended (GHashTable *hash_table,
gconstpointer lookup_key,
gpointer *orig_key,
gpointer *value);
void g_hash_table_foreach (GHashTable *hash_table,
GHFunc func,
gpointer user_data);
guint g_hash_table_foreach_remove (GHashTable *hash_table,
GHRFunc func,
gpointer user_data);
guint g_hash_table_foreach_steal (GHashTable *hash_table,
GHRFunc func,
gpointer user_data);
guint g_hash_table_size (GHashTable *hash_table);
/* The following two functions are deprecated and will be removed in
* the next major release. They do no good. */
void g_hash_table_freeze (GHashTable *hash_table);
void g_hash_table_thaw (GHashTable *hash_table);
void g_hash_table_freeze (GHashTable *hash_table);
void g_hash_table_thaw (GHashTable *hash_table);
/* Hash Functions
*/
gboolean g_str_equal (gconstpointer v,
gconstpointer v2);
guint g_str_hash (gconstpointer v);
gboolean g_str_equal (gconstpointer v,
gconstpointer v2);
guint g_str_hash (gconstpointer v);
gboolean g_int_equal (gconstpointer v,
gconstpointer v2) G_GNUC_CONST;
guint g_int_hash (gconstpointer v) G_GNUC_CONST;
gboolean g_int_equal (gconstpointer v,
gconstpointer v2) G_GNUC_CONST;
guint g_int_hash (gconstpointer v) G_GNUC_CONST;
/* This "hash" function will just return the key's adress as an
* unsigned integer. Useful for hashing on plain adresses or
@ -82,9 +94,9 @@ guint g_int_hash (gconstpointer v) G_GNUC_CONST;
* passing NULL into g_hash_table_new() as GHashFunc has the
* same effect as passing g_direct_hash().
*/
guint g_direct_hash (gconstpointer v) G_GNUC_CONST;
gboolean g_direct_equal (gconstpointer v,
gconstpointer v2) G_GNUC_CONST;
guint g_direct_hash (gconstpointer v) G_GNUC_CONST;
gboolean g_direct_equal (gconstpointer v,
gconstpointer v2) G_GNUC_CONST;
G_END_DECLS

View File

@ -43,28 +43,38 @@ typedef struct _GHashNode GHashNode;
struct _GHashNode
{
gpointer key;
gpointer value;
gpointer key;
gpointer value;
GHashNode *next;
};
struct _GHashTable
{
gint size;
gint nnodes;
GHashNode **nodes;
GHashFunc hash_func;
GEqualFunc key_equal_func;
gint size;
gint nnodes;
GHashNode **nodes;
GHashFunc hash_func;
GEqualFunc key_equal_func;
GDestroyNotify key_destroy_func;
GDestroyNotify value_destroy_func;
};
static void g_hash_table_resize (GHashTable *hash_table);
static GHashNode** g_hash_table_lookup_node (GHashTable *hash_table,
gconstpointer key);
static GHashNode* g_hash_node_new (gpointer key,
gpointer value);
static void g_hash_node_destroy (GHashNode *hash_node);
static void g_hash_nodes_destroy (GHashNode *hash_node);
static void g_hash_table_resize (GHashTable *hash_table);
static GHashNode** g_hash_table_lookup_node (GHashTable *hash_table,
gconstpointer key);
static GHashNode* g_hash_node_new (gpointer key,
gpointer value);
static void g_hash_node_destroy (GHashNode *hash_node,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func);
static void g_hash_nodes_destroy (GHashNode *hash_node,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func);
static guint g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
GHRFunc func,
gpointer user_data,
gboolean notify);
G_LOCK_DEFINE_STATIC (g_hash_global);
@ -72,20 +82,66 @@ G_LOCK_DEFINE_STATIC (g_hash_global);
static GMemChunk *node_mem_chunk = NULL;
static GHashNode *node_free_list = NULL;
/**
* g_hash_table_new:
* @hash_func: a function to create a hash value from a key.
* Hash values are used to determine where keys are stored within the
* #GHashTable data structure. The g_direct_hash(), g_int_hash() and
* g_str_hash() functions are provided for some common types of keys.
* If hash_func is NULL, g_direct_hash() is used.
* @key_equal_func: a function to check two keys for equality. This is
* used when looking up keys in the #GHashTable. The g_direct_equal(),
* g_int_equal() and g_str_equal() functions are provided for the most
* common types of keys. If @key_equal_func is NULL, keys are compared
* directly in a similar fashion to g_direct_equal(), but without the
* overhead of a function call.
*
* Creates a new #GHashTable.
*
* Return value: a new #GHashTable.
**/
GHashTable*
g_hash_table_new (GHashFunc hash_func,
GEqualFunc key_equal_func)
{
return g_hash_table_new_full (hash_func, key_equal_func, NULL, NULL);
}
/**
* g_hash_table_new_full:
* @hash_func: a function to create a hash value from a key.
* @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.
* @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.
*
* Creates a new #GHashTable like g_hash_table_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 #GHashTable.
*
* Return value: a new #GHashTable.
**/
GHashTable*
g_hash_table_new_full (GHashFunc hash_func,
GEqualFunc key_equal_func,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func)
{
GHashTable *hash_table;
guint i;
hash_table = g_new (GHashTable, 1);
hash_table->size = HASH_TABLE_MIN_SIZE;
hash_table->nnodes = 0;
hash_table->hash_func = hash_func ? hash_func : g_direct_hash;
hash_table->key_equal_func = key_equal_func;
hash_table->nodes = g_new (GHashNode*, hash_table->size);
hash_table->size = HASH_TABLE_MIN_SIZE;
hash_table->nnodes = 0;
hash_table->hash_func = hash_func ? hash_func : g_direct_hash;
hash_table->key_equal_func = key_equal_func;
hash_table->key_destroy_func = key_destroy_func;
hash_table->value_destroy_func = value_destroy_func;
hash_table->nodes = g_new (GHashNode*, hash_table->size);
for (i = 0; i < hash_table->size; i++)
hash_table->nodes[i] = NULL;
@ -93,6 +149,16 @@ g_hash_table_new (GHashFunc hash_func,
return hash_table;
}
/**
* g_hash_table_destroy:
* @hash_table: a #GHashTable.
*
* Destroys the #GHashTable. If keys and/or values are dynamically
* allocated, you should either free them first or create the #GHashTable
* using g_hash_table_new_full(). In the latter case the destroy functions
* you supplied will be called on all keys and values before destroying
* the #GHashTable.
**/
void
g_hash_table_destroy (GHashTable *hash_table)
{
@ -101,7 +167,9 @@ g_hash_table_destroy (GHashTable *hash_table)
g_return_if_fail (hash_table != NULL);
for (i = 0; i < hash_table->size; i++)
g_hash_nodes_destroy (hash_table->nodes[i]);
g_hash_nodes_destroy (hash_table->nodes[i],
hash_table->key_destroy_func,
hash_table->value_destroy_func);
g_free (hash_table->nodes);
g_free (hash_table);
@ -131,6 +199,15 @@ g_hash_table_lookup_node (GHashTable *hash_table,
return node;
}
/**
* g_hash_table_lookup:
* @hash_table: a #GHashTable.
* @key: the key to look up.
*
* Looks up a key in a #GHashTable.
*
* Return value: the associated value, or NULL if the key is not found.
**/
gpointer
g_hash_table_lookup (GHashTable *hash_table,
gconstpointer key)
@ -144,64 +221,25 @@ g_hash_table_lookup (GHashTable *hash_table,
return node ? node->value : NULL;
}
void
g_hash_table_insert (GHashTable *hash_table,
gpointer key,
gpointer value)
{
GHashNode **node;
g_return_if_fail (hash_table != NULL);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
/* do not reset node->key in this place, keeping
* the old key might be intended.
* a g_hash_table_remove/g_hash_table_insert pair
* can be used otherwise.
*
* node->key = key; */
(*node)->value = value;
}
else
{
*node = g_hash_node_new (key, value);
hash_table->nnodes++;
g_hash_table_resize (hash_table);
}
}
/**
* g_hash_table_lookup_extended:
* @hash_table: a #GHashTable.
* @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 #GHashTable, 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_hash_table_remove().
*
* Return value: #TRUE if the key was found in the #GHashTable.
**/
gboolean
g_hash_table_remove (GHashTable *hash_table,
gconstpointer key)
{
GHashNode **node, *dest;
g_return_val_if_fail (hash_table != NULL, FALSE);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
dest = *node;
(*node) = dest->next;
g_hash_node_destroy (dest);
hash_table->nnodes--;
g_hash_table_resize (hash_table);
return TRUE;
}
return FALSE;
}
gboolean
g_hash_table_lookup_extended (GHashTable *hash_table,
gconstpointer lookup_key,
gpointer *orig_key,
gpointer *value)
g_hash_table_lookup_extended (GHashTable *hash_table,
gconstpointer lookup_key,
gpointer *orig_key,
gpointer *value)
{
GHashNode *node;
@ -221,37 +259,230 @@ g_hash_table_lookup_extended (GHashTable *hash_table,
return FALSE;
}
/**
* g_hash_table_insert:
* @hash_table: a #GHashTable.
* @key: a key to insert.
* @value: the value to associate with the key.
*
* Inserts a new key and value into a #GHashTable.
*
* If the key already exists in the #GHashTable its current value is replaced
* with the new value. If you supplied a value_destroy_func when creating the
* #GHashTable, the old value is freed using that function. If you supplied
* a key_destroy_func when creating the #GHashTable, the passed key is freed
* using that function.
**/
void
g_hash_table_freeze (GHashTable *hash_table)
g_hash_table_insert (GHashTable *hash_table,
gpointer key,
gpointer value)
{
#ifdef G_ENABLE_DEBUG
static gboolean first_call = TRUE;
if (first_call)
GHashNode **node;
g_return_if_fail (hash_table != NULL);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
g_warning("g_hash_table_freeze and g_hash_table_thaw are deprecated.");
first_call = FALSE;
/* do not reset node->key in this place, keeping
* the old key is the intended behaviour.
* g_hash_table_replace() can be used instead.
*/
/* free the passed key */
if (hash_table->key_destroy_func)
hash_table->key_destroy_func (key);
if (hash_table->value_destroy_func)
hash_table->value_destroy_func ((*node)->value);
(*node)->value = value;
}
else
{
*node = g_hash_node_new (key, value);
hash_table->nnodes++;
g_hash_table_resize (hash_table);
}
#endif /* G_ENABLE_DEBUG */
}
/**
* g_hash_table_replace:
* @hash_table: a #GHashTable.
* @key: a key to insert.
* @value: the value to associate with the key.
*
* Inserts a new key and value into a #GHashTable similar to
* g_hash_table_insert(). The difference is that if the key already exists
* in the #GHashTable, it gets replaced by the new key. If you supplied a
* value_destroy_func when creating the #GHashTable, the old value is freed
* using that function. If you supplied a key_destroy_func when creating the
* #GHashTable, the old key is freed using that function.
**/
void
g_hash_table_thaw (GHashTable *hash_table)
g_hash_table_replace (GHashTable *hash_table,
gpointer key,
gpointer value)
{
GHashNode **node;
g_return_if_fail (hash_table != NULL);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
if (hash_table->key_destroy_func)
hash_table->key_destroy_func ((*node)->key);
if (hash_table->value_destroy_func)
hash_table->value_destroy_func ((*node)->value);
(*node)->key = key;
(*node)->value = value;
}
else
{
*node = g_hash_node_new (key, value);
hash_table->nnodes++;
g_hash_table_resize (hash_table);
}
}
/**
* g_hash_table_remove:
* @hash_table: a #GHashTable.
* @key: the key to remove.
*
* Removes a key and its associated value from a #GHashTable.
*
* If the #GHashTable was created using g_hash_table_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.
*
* Return value: #TRUE if the key was found and removed from the #GHashTable.
**/
gboolean
g_hash_table_remove (GHashTable *hash_table,
gconstpointer key)
{
GHashNode **node, *dest;
g_return_val_if_fail (hash_table != NULL, FALSE);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
dest = *node;
(*node) = dest->next;
g_hash_node_destroy (dest,
hash_table->key_destroy_func,
hash_table->value_destroy_func);
hash_table->nnodes--;
g_hash_table_resize (hash_table);
return TRUE;
}
return FALSE;
}
/**
* g_hash_table_steal:
* @hash_table: a #GHashTable.
* @key: the key to remove.
*
* Removes a key and its associated value from a #GHashTable without
* calling the key and value destroy functions.
*
* Return value: #TRUE if the key was found and removed from the #GHashTable.
**/
gboolean
g_hash_table_steal (GHashTable *hash_table,
gconstpointer key)
{
GHashNode **node, *dest;
g_return_val_if_fail (hash_table != NULL, FALSE);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
dest = *node;
(*node) = dest->next;
g_hash_node_destroy (dest, NULL, NULL);
hash_table->nnodes--;
g_hash_table_resize (hash_table);
return TRUE;
}
return FALSE;
}
/**
* g_hash_table_foreach_remove:
* @hash_table: a #GHashTable.
* @func: the function to call for each key/value pair.
* @user_data: user data to pass to the function.
*
* Calls the given function for each key/value pair in the #GHashTable.
* If the function returns TRUE, then the key/value pair is removed from the
* #GHashTable. If you supplied key or value destroy functions when creating
* the #GHashTable, they are used to free the memory allocated for the removed
* keys and values.
*
* Return value: the number of key/value pairs removed.
**/
guint
g_hash_table_foreach_remove (GHashTable *hash_table,
GHRFunc func,
gpointer user_data)
{
g_return_val_if_fail (hash_table != NULL, 0);
g_return_val_if_fail (func != NULL, 0);
return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, TRUE);
}
/**
* g_hash_table_foreach_steal:
* @hash_table: a #GHashTable.
* @func: the function to call for each key/value pair.
* @user_data: user data to pass to the function.
*
* Calls the given function for each key/value pair in the #GHashTable.
* If the function returns TRUE, then the key/value pair is removed from the
* #GHashTable, but no key or value destroy functions are called.
*
* Return value: the number of key/value pairs removed.
**/
guint
g_hash_table_foreach_steal (GHashTable *hash_table,
GHRFunc func,
gpointer user_data)
{
g_return_val_if_fail (hash_table != NULL, 0);
g_return_val_if_fail (func != NULL, 0);
return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, FALSE);
}
static guint
g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
GHRFunc func,
gpointer user_data,
gboolean notify)
{
GHashNode *node, *prev;
guint i;
guint deleted = 0;
g_return_val_if_fail (hash_table != NULL, 0);
g_return_val_if_fail (func != NULL, 0);
for (i = 0; i < hash_table->size; i++)
{
restart:
@ -269,13 +500,17 @@ g_hash_table_foreach_remove (GHashTable *hash_table,
if (prev)
{
prev->next = node->next;
g_hash_node_destroy (node);
g_hash_node_destroy (node,
notify ? hash_table->value_destroy_func : NULL,
notify ? hash_table->key_destroy_func : NULL);
node = prev;
}
else
{
hash_table->nodes[i] = node->next;
g_hash_node_destroy (node);
g_hash_node_destroy (node,
notify ? hash_table->value_destroy_func : NULL,
notify ? hash_table->key_destroy_func : NULL);
goto restart;
}
}
@ -287,6 +522,16 @@ g_hash_table_foreach_remove (GHashTable *hash_table,
return deleted;
}
/**
* g_hash_table_foreach:
* @hash_table: a #GHashTable.
* @func: the function to call for each key/value pair.
* @user_data: user data to pass to the function.
*
* Calls the given function for each of the key/value pairs in the #GHashTable.
* The function is passed the key and value of each pair, and the given
* @user_data parameter.
**/
void
g_hash_table_foreach (GHashTable *hash_table,
GHFunc func,
@ -303,7 +548,14 @@ g_hash_table_foreach (GHashTable *hash_table,
(* func) (node->key, node->value, user_data);
}
/* Returns the number of elements contained in the hash table. */
/**
* g_hash_table_size:
* @hash_table: a #GHashTable.
*
* Returns the number of elements contained in the #GHashTable.
*
* Return value: the number of key/value pairs in the #GHashTable.
**/
guint
g_hash_table_size (GHashTable *hash_table)
{
@ -312,6 +564,39 @@ g_hash_table_size (GHashTable *hash_table)
return hash_table->nnodes;
}
/**
* g_hash_table_freeze:
* @hash_table: a #GHashTable.
*
* This function is deprecated and will be removed in the next major
* release of GLib. It does nothing.
**/
void
g_hash_table_freeze (GHashTable *hash_table)
{
#ifdef G_ENABLE_DEBUG
static gboolean first_call = TRUE;
if (first_call)
{
g_warning("g_hash_table_freeze and g_hash_table_thaw are deprecated.");
first_call = FALSE;
}
#endif /* G_ENABLE_DEBUG */
}
/**
* g_hash_table_thaw:
* @hash_table: a #GHashTable.
*
* This function is deprecated and will be removed in the next major
* release of GLib. It does nothing.
**/
void
g_hash_table_thaw (GHashTable *hash_table)
{
}
static void
g_hash_table_resize (GHashTable *hash_table)
{
@ -381,9 +666,15 @@ g_hash_node_new (gpointer key,
}
static void
g_hash_node_destroy (GHashNode *hash_node)
g_hash_node_destroy (GHashNode *hash_node,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func)
{
if (key_destroy_func)
key_destroy_func (hash_node->key);
if (value_destroy_func)
value_destroy_func (hash_node->value);
#ifdef ENABLE_GC_FRIENDLY
hash_node->key = NULL;
hash_node->value = NULL;
@ -396,7 +687,9 @@ g_hash_node_destroy (GHashNode *hash_node)
}
static void
g_hash_nodes_destroy (GHashNode *hash_node)
g_hash_nodes_destroy (GHashNode *hash_node,
GFreeFunc key_destroy_func,
GFreeFunc value_destroy_func)
{
if (hash_node)
{
@ -404,13 +697,24 @@ g_hash_nodes_destroy (GHashNode *hash_node)
while (node->next)
{
if (key_destroy_func)
key_destroy_func (node->key);
if (value_destroy_func)
value_destroy_func (node->value);
#ifdef ENABLE_GC_FRIENDLY
node->key = NULL;
node->value = NULL;
#endif /* ENABLE_GC_FRIENDLY */
node = node->next;
}
if (key_destroy_func)
key_destroy_func (node->key);
if (value_destroy_func)
value_destroy_func (node->value);
#ifdef ENABLE_GC_FRIENDLY
node->key = NULL;
node->value = NULL;

View File

@ -31,50 +31,62 @@
G_BEGIN_DECLS
typedef struct _GHashTable GHashTable;
typedef struct _GHashTable GHashTable;
typedef gboolean (*GHRFunc) (gpointer key,
gpointer value,
gpointer user_data);
typedef gboolean (*GHRFunc) (gpointer key,
gpointer value,
gpointer user_data);
/* Hash tables
*/
GHashTable* g_hash_table_new (GHashFunc hash_func,
GEqualFunc key_equal_func);
void g_hash_table_destroy (GHashTable *hash_table);
void g_hash_table_insert (GHashTable *hash_table,
gpointer key,
gpointer value);
gboolean g_hash_table_remove (GHashTable *hash_table,
gconstpointer key);
gpointer g_hash_table_lookup (GHashTable *hash_table,
gconstpointer key);
gboolean g_hash_table_lookup_extended(GHashTable *hash_table,
gconstpointer lookup_key,
gpointer *orig_key,
gpointer *value);
void g_hash_table_foreach (GHashTable *hash_table,
GHFunc func,
gpointer user_data);
guint g_hash_table_foreach_remove (GHashTable *hash_table,
GHRFunc func,
gpointer user_data);
guint g_hash_table_size (GHashTable *hash_table);
GHashTable* g_hash_table_new (GHashFunc hash_func,
GEqualFunc key_equal_func);
GHashTable* g_hash_table_new_full (GHashFunc hash_func,
GEqualFunc key_equal_func,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func);
void g_hash_table_destroy (GHashTable *hash_table);
void g_hash_table_insert (GHashTable *hash_table,
gpointer key,
gpointer value);
void g_hash_table_replace (GHashTable *hash_table,
gpointer key,
gpointer value);
gboolean g_hash_table_remove (GHashTable *hash_table,
gconstpointer key);
gboolean g_hash_table_steal (GHashTable *hash_table,
gconstpointer key);
gpointer g_hash_table_lookup (GHashTable *hash_table,
gconstpointer key);
gboolean g_hash_table_lookup_extended (GHashTable *hash_table,
gconstpointer lookup_key,
gpointer *orig_key,
gpointer *value);
void g_hash_table_foreach (GHashTable *hash_table,
GHFunc func,
gpointer user_data);
guint g_hash_table_foreach_remove (GHashTable *hash_table,
GHRFunc func,
gpointer user_data);
guint g_hash_table_foreach_steal (GHashTable *hash_table,
GHRFunc func,
gpointer user_data);
guint g_hash_table_size (GHashTable *hash_table);
/* The following two functions are deprecated and will be removed in
* the next major release. They do no good. */
void g_hash_table_freeze (GHashTable *hash_table);
void g_hash_table_thaw (GHashTable *hash_table);
void g_hash_table_freeze (GHashTable *hash_table);
void g_hash_table_thaw (GHashTable *hash_table);
/* Hash Functions
*/
gboolean g_str_equal (gconstpointer v,
gconstpointer v2);
guint g_str_hash (gconstpointer v);
gboolean g_str_equal (gconstpointer v,
gconstpointer v2);
guint g_str_hash (gconstpointer v);
gboolean g_int_equal (gconstpointer v,
gconstpointer v2) G_GNUC_CONST;
guint g_int_hash (gconstpointer v) G_GNUC_CONST;
gboolean g_int_equal (gconstpointer v,
gconstpointer v2) G_GNUC_CONST;
guint g_int_hash (gconstpointer v) G_GNUC_CONST;
/* This "hash" function will just return the key's adress as an
* unsigned integer. Useful for hashing on plain adresses or
@ -82,9 +94,9 @@ guint g_int_hash (gconstpointer v) G_GNUC_CONST;
* passing NULL into g_hash_table_new() as GHashFunc has the
* same effect as passing g_direct_hash().
*/
guint g_direct_hash (gconstpointer v) G_GNUC_CONST;
gboolean g_direct_equal (gconstpointer v,
gconstpointer v2) G_GNUC_CONST;
guint g_direct_hash (gconstpointer v) G_GNUC_CONST;
gboolean g_direct_equal (gconstpointer v,
gconstpointer v2) G_GNUC_CONST;
G_END_DECLS