mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-02 15:46:17 +01:00
no code changes; reorder functions to remove the need for forward
2007-12-03 Ryan Lortie <desrt@desrt.ca> * glib/ghash.c: no code changes; reorder functions to remove the need for forward declarations. svn path=/trunk/; revision=6036
This commit is contained in:
parent
d72c02686b
commit
ac44f9cb5a
@ -1,3 +1,8 @@
|
||||
2007-12-03 Ryan Lortie <desrt@desrt.ca>
|
||||
|
||||
* glib/ghash.c: no code changes; reorder functions to remove the need
|
||||
for forward declarations.
|
||||
|
||||
2007-12-03 Ryan Lortie <desrt@desrt.ca>
|
||||
|
||||
* glib/ghash.c (g_hash_table_lookup_node,
|
||||
|
328
glib/ghash.c
328
glib/ghash.c
@ -60,19 +60,121 @@ struct _GHashTable
|
||||
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,
|
||||
guint *hash_return);
|
||||
static GHashNode* g_hash_node_new (gpointer key,
|
||||
gpointer value,
|
||||
guint key_hash);
|
||||
static guint g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
|
||||
GHRFunc func,
|
||||
gpointer user_data,
|
||||
gboolean notify);
|
||||
static void g_hash_table_remove_all_nodes (GHashTable *hash_table,
|
||||
gboolean notify);
|
||||
static inline GHashNode **
|
||||
g_hash_table_lookup_node (GHashTable *hash_table,
|
||||
gconstpointer key,
|
||||
guint *hash_return)
|
||||
{
|
||||
GHashNode **node_ptr, *node;
|
||||
guint hash_value;
|
||||
|
||||
hash_value = (* hash_table->hash_func) (key);
|
||||
node_ptr = &hash_table->nodes[hash_value % hash_table->size];
|
||||
|
||||
if (hash_return)
|
||||
*hash_return = hash_value;
|
||||
|
||||
/* Hash table lookup needs to be fast.
|
||||
* We therefore remove the extra conditional of testing
|
||||
* whether to call the key_equal_func or not from
|
||||
* the inner loop.
|
||||
*
|
||||
* Additional optimisation: first check if our full hash
|
||||
* values are equal so we can avoid calling the full-blown
|
||||
* key equality function in most cases.
|
||||
*/
|
||||
if (hash_table->key_equal_func)
|
||||
{
|
||||
while ((node = *node_ptr))
|
||||
{
|
||||
if (node->key_hash == hash_value &&
|
||||
hash_table->key_equal_func (node->key, key))
|
||||
break;
|
||||
|
||||
node_ptr = &(*node_ptr)->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((node = *node_ptr))
|
||||
{
|
||||
if (node->key == key)
|
||||
break;
|
||||
|
||||
node_ptr = &(*node_ptr)->next;
|
||||
}
|
||||
}
|
||||
|
||||
return node_ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
g_hash_table_remove_node (GHashTable *hash_table,
|
||||
GHashNode ***node_ptr_ptr,
|
||||
gboolean notify)
|
||||
{
|
||||
GHashNode **node_ptr, *node;
|
||||
|
||||
node_ptr = *node_ptr_ptr;
|
||||
node = *node_ptr;
|
||||
|
||||
*node_ptr = node->next;
|
||||
|
||||
if (notify && hash_table->key_destroy_func)
|
||||
hash_table->key_destroy_func (node->key);
|
||||
|
||||
if (notify && hash_table->value_destroy_func)
|
||||
hash_table->value_destroy_func (node->value);
|
||||
|
||||
g_slice_free (GHashNode, node);
|
||||
|
||||
hash_table->nnodes--;
|
||||
}
|
||||
|
||||
static void
|
||||
g_hash_table_remove_all_nodes (GHashTable *hash_table,
|
||||
gboolean notify)
|
||||
{
|
||||
GHashNode **node_ptr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < hash_table->size; i++)
|
||||
for (node_ptr = &hash_table->nodes[i]; *node_ptr != NULL;)
|
||||
g_hash_table_remove_node (hash_table, &node_ptr, notify);
|
||||
|
||||
hash_table->nnodes = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
g_hash_table_resize (GHashTable *hash_table)
|
||||
{
|
||||
GHashNode **new_nodes;
|
||||
GHashNode *node;
|
||||
GHashNode *next;
|
||||
guint hash_val;
|
||||
gint new_size;
|
||||
gint i;
|
||||
|
||||
new_size = g_spaced_primes_closest (hash_table->nnodes);
|
||||
new_size = CLAMP (new_size, HASH_TABLE_MIN_SIZE, HASH_TABLE_MAX_SIZE);
|
||||
|
||||
new_nodes = g_new0 (GHashNode*, new_size);
|
||||
|
||||
for (i = 0; i < hash_table->size; i++)
|
||||
for (node = hash_table->nodes[i]; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
|
||||
hash_val = node->key_hash % new_size;
|
||||
|
||||
node->next = new_nodes[hash_val];
|
||||
new_nodes[hash_val] = node;
|
||||
}
|
||||
|
||||
g_free (hash_table->nodes);
|
||||
hash_table->nodes = new_nodes;
|
||||
hash_table->size = new_size;
|
||||
}
|
||||
|
||||
static inline void
|
||||
g_hash_table_maybe_resize (GHashTable *hash_table)
|
||||
@ -217,54 +319,6 @@ g_hash_table_destroy (GHashTable *hash_table)
|
||||
g_hash_table_unref (hash_table);
|
||||
}
|
||||
|
||||
static inline GHashNode **
|
||||
g_hash_table_lookup_node (GHashTable *hash_table,
|
||||
gconstpointer key,
|
||||
guint *hash_return)
|
||||
{
|
||||
GHashNode **node_ptr, *node;
|
||||
guint hash_value;
|
||||
|
||||
hash_value = (* hash_table->hash_func) (key);
|
||||
node_ptr = &hash_table->nodes[hash_value % hash_table->size];
|
||||
|
||||
if (hash_return)
|
||||
*hash_return = hash_value;
|
||||
|
||||
/* Hash table lookup needs to be fast.
|
||||
* We therefore remove the extra conditional of testing
|
||||
* whether to call the key_equal_func or not from
|
||||
* the inner loop.
|
||||
*
|
||||
* Additional optimisation: first check if our full hash
|
||||
* values are equal so we can avoid calling the full-blown
|
||||
* key equality function in most cases.
|
||||
*/
|
||||
if (hash_table->key_equal_func)
|
||||
{
|
||||
while ((node = *node_ptr))
|
||||
{
|
||||
if (node->key_hash == hash_value &&
|
||||
hash_table->key_equal_func (node->key, key))
|
||||
break;
|
||||
|
||||
node_ptr = &(*node_ptr)->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((node = *node_ptr))
|
||||
{
|
||||
if (node->key == key)
|
||||
break;
|
||||
|
||||
node_ptr = &(*node_ptr)->next;
|
||||
}
|
||||
}
|
||||
|
||||
return node_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_hash_table_lookup:
|
||||
* @hash_table: a #GHashTable.
|
||||
@ -419,43 +473,6 @@ g_hash_table_replace (GHashTable *hash_table,
|
||||
return g_hash_table_insert_internal (hash_table, key, value, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
g_hash_table_remove_node (GHashTable *hash_table,
|
||||
GHashNode ***node_ptr_ptr,
|
||||
gboolean notify)
|
||||
{
|
||||
GHashNode **node_ptr, *node;
|
||||
|
||||
node_ptr = *node_ptr_ptr;
|
||||
node = *node_ptr;
|
||||
|
||||
*node_ptr = node->next;
|
||||
|
||||
if (notify && hash_table->key_destroy_func)
|
||||
hash_table->key_destroy_func (node->key);
|
||||
|
||||
if (notify && hash_table->value_destroy_func)
|
||||
hash_table->value_destroy_func (node->value);
|
||||
|
||||
g_slice_free (GHashNode, node);
|
||||
|
||||
hash_table->nnodes--;
|
||||
}
|
||||
|
||||
static void
|
||||
g_hash_table_remove_all_nodes (GHashTable *hash_table,
|
||||
gboolean notify)
|
||||
{
|
||||
GHashNode **node_ptr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < hash_table->size; i++)
|
||||
for (node_ptr = &hash_table->nodes[i]; *node_ptr != NULL;)
|
||||
g_hash_table_remove_node (hash_table, &node_ptr, notify);
|
||||
|
||||
hash_table->nnodes = 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_hash_table_remove_internal (GHashTable *hash_table,
|
||||
gconstpointer key,
|
||||
@ -496,6 +513,23 @@ g_hash_table_remove (GHashTable *hash_table,
|
||||
return g_hash_table_remove_internal (hash_table, key, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
return g_hash_table_remove_internal (hash_table, key, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_hash_table_remove_all:
|
||||
* @hash_table: a #GHashTable
|
||||
@ -518,23 +552,6 @@ g_hash_table_remove_all (GHashTable *hash_table)
|
||||
g_hash_table_maybe_resize (hash_table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
return g_hash_table_remove_internal (hash_table, key, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_hash_table_steal_all:
|
||||
* @hash_table: a #GHashTable.
|
||||
@ -553,6 +570,31 @@ g_hash_table_steal_all (GHashTable *hash_table)
|
||||
g_hash_table_maybe_resize (hash_table);
|
||||
}
|
||||
|
||||
static guint
|
||||
g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
|
||||
GHRFunc func,
|
||||
gpointer user_data,
|
||||
gboolean notify)
|
||||
{
|
||||
GHashNode *node, **node_ptr;
|
||||
guint deleted = 0;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < hash_table->size; i++)
|
||||
for (node_ptr = &hash_table->nodes[i]; (node = *node_ptr) != NULL;)
|
||||
if ((* func) (node->key, node->value, user_data))
|
||||
{
|
||||
g_hash_table_remove_node (hash_table, &node_ptr, notify);
|
||||
deleted++;
|
||||
}
|
||||
else
|
||||
node_ptr = &node->next;
|
||||
|
||||
g_hash_table_maybe_resize (hash_table);
|
||||
|
||||
return deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_hash_table_foreach_remove:
|
||||
* @hash_table: a #GHashTable.
|
||||
@ -601,31 +643,6 @@ g_hash_table_foreach_steal (GHashTable *hash_table,
|
||||
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, **node_ptr;
|
||||
guint deleted = 0;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < hash_table->size; i++)
|
||||
for (node_ptr = &hash_table->nodes[i]; (node = *node_ptr) != NULL;)
|
||||
if ((* func) (node->key, node->value, user_data))
|
||||
{
|
||||
g_hash_table_remove_node (hash_table, &node_ptr, notify);
|
||||
deleted++;
|
||||
}
|
||||
else
|
||||
node_ptr = &node->next;
|
||||
|
||||
g_hash_table_maybe_resize (hash_table);
|
||||
|
||||
return deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_hash_table_foreach:
|
||||
* @hash_table: a #GHashTable.
|
||||
@ -780,36 +797,5 @@ g_hash_table_get_values (GHashTable *hash_table)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
g_hash_table_resize (GHashTable *hash_table)
|
||||
{
|
||||
GHashNode **new_nodes;
|
||||
GHashNode *node;
|
||||
GHashNode *next;
|
||||
guint hash_val;
|
||||
gint new_size;
|
||||
gint i;
|
||||
|
||||
new_size = g_spaced_primes_closest (hash_table->nnodes);
|
||||
new_size = CLAMP (new_size, HASH_TABLE_MIN_SIZE, HASH_TABLE_MAX_SIZE);
|
||||
|
||||
new_nodes = g_new0 (GHashNode*, new_size);
|
||||
|
||||
for (i = 0; i < hash_table->size; i++)
|
||||
for (node = hash_table->nodes[i]; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
|
||||
hash_val = node->key_hash % new_size;
|
||||
|
||||
node->next = new_nodes[hash_val];
|
||||
new_nodes[hash_val] = node;
|
||||
}
|
||||
|
||||
g_free (hash_table->nodes);
|
||||
hash_table->nodes = new_nodes;
|
||||
hash_table->size = new_size;
|
||||
}
|
||||
|
||||
#define __G_HASH_C__
|
||||
#include "galiasdef.c"
|
||||
|
Loading…
Reference in New Issue
Block a user