Main Page | Class List | Directories | File List | Class Members | File Members

ghash.c File Reference

#include "glib.h"

Go to the source code of this file.

Classes

struct  _GHashNode
struct  _GHashTable

Defines

#define HASH_TABLE_MIN_SIZE   11
#define HASH_TABLE_MAX_SIZE   13845163

Typedefs

typedef _GHashNode GHashNode

Functions

static void g_hash_table_resize (GHashTable *hash_table)
static GHashNode ** g_hash_table_lookup_node (GHashTable *hash_table, gconstpointer key)
static GHashNodeg_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)
 G_LOCK_DEFINE_STATIC (g_hash_global)
GHashTableg_hash_table_new (GHashFunc hash_func, GCompareFunc key_compare_func)
void g_hash_table_destroy (GHashTable *hash_table)
gpointer g_hash_table_lookup (GHashTable *hash_table, gconstpointer key)
void g_hash_table_insert (GHashTable *hash_table, gpointer key, gpointer value)
void g_hash_table_remove (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_freeze (GHashTable *hash_table)
void g_hash_table_thaw (GHashTable *hash_table)
guint g_hash_table_foreach_remove (GHashTable *hash_table, GHRFunc func, gpointer user_data)
void g_hash_table_foreach (GHashTable *hash_table, GHFunc func, gpointer user_data)
guint g_hash_table_size (GHashTable *hash_table)

Variables

static GMemChunknode_mem_chunk = NULL
static GHashNodenode_free_list = NULL


Define Documentation

#define HASH_TABLE_MAX_SIZE   13845163
 

Definition at line 35 of file ghash.c.

Referenced by g_hash_table_resize().

#define HASH_TABLE_MIN_SIZE   11
 

Definition at line 34 of file ghash.c.

Referenced by g_hash_table_new(), and g_hash_table_resize().


Typedef Documentation

typedef struct _GHashNode GHashNode
 

Definition at line 38 of file ghash.c.


Function Documentation

static void g_hash_node_destroy GHashNode hash_node  )  [static]
 

Definition at line 381 of file ghash.c.

References G_LOCK, G_UNLOCK, and _GHashNode::next.

Referenced by g_hash_table_foreach_remove(), and g_hash_table_remove().

00382 {
00383   G_LOCK (g_hash_global);
00384   hash_node->next = node_free_list;
00385   node_free_list = hash_node;
00386   G_UNLOCK (g_hash_global);
00387 }

static GHashNode * g_hash_node_new gpointer  key,
gpointer  value
[static]
 

Definition at line 351 of file ghash.c.

References G_ALLOC_ONLY, g_chunk_new, G_LOCK, g_mem_chunk_new(), G_UNLOCK, _GHashNode::key, _GHashNode::next, node_mem_chunk, NULL, and _GHashNode::value.

Referenced by g_hash_table_insert().

00353 {
00354   GHashNode *hash_node;
00355   
00356   G_LOCK (g_hash_global);
00357   if (node_free_list)
00358     {
00359       hash_node = node_free_list;
00360       node_free_list = node_free_list->next;
00361     }
00362   else
00363     {
00364       if (!node_mem_chunk)
00365         node_mem_chunk = g_mem_chunk_new ("hash node mem chunk",
00366                                           sizeof (GHashNode),
00367                                           1024, G_ALLOC_ONLY);
00368       
00369       hash_node = g_chunk_new (GHashNode, node_mem_chunk);
00370     }
00371   G_UNLOCK (g_hash_global);
00372   
00373   hash_node->key = key;
00374   hash_node->value = value;
00375   hash_node->next = NULL;
00376   
00377   return hash_node;
00378 }

static void g_hash_nodes_destroy GHashNode hash_node  )  [static]
 

Definition at line 390 of file ghash.c.

References G_LOCK, G_UNLOCK, and _GHashNode::next.

Referenced by g_hash_table_destroy().

00391 {
00392   if (hash_node)
00393     {
00394       GHashNode *node = hash_node;
00395   
00396       while (node->next)
00397         node = node->next;
00398   
00399       G_LOCK (g_hash_global);
00400       node->next = node_free_list;
00401       node_free_list = hash_node;
00402       G_UNLOCK (g_hash_global);
00403     }
00404 }

void g_hash_table_destroy GHashTable hash_table  ) 
 

Definition at line 95 of file ghash.c.

References g_free(), g_hash_nodes_destroy(), g_return_if_fail, _GHashTable::nodes, and NULL.

Referenced by direct_hash_test(), g_cache_destroy(), g_relation_delete(), g_relation_destroy(), g_relation_free_array(), g_scanner_destroy(), g_string_chunk_free(), main(), and second_hash_test().

00096 {
00097   guint i;
00098   
00099   g_return_if_fail (hash_table != NULL);
00100   
00101   for (i = 0; i < hash_table->size; i++)
00102     g_hash_nodes_destroy (hash_table->nodes[i]);
00103   
00104   g_free (hash_table->nodes);
00105   g_free (hash_table);
00106 }

void g_hash_table_foreach GHashTable hash_table,
GHFunc  func,
gpointer  user_data
 

Definition at line 288 of file ghash.c.

References g_return_if_fail, _GHashNode::key, _GHashNode::next, _GHashTable::nodes, NULL, and _GHashNode::value.

Referenced by g_cache_key_foreach(), g_cache_value_foreach(), g_relation_delete(), g_relation_destroy(), g_relation_print(), g_relation_print_index(), g_relation_select(), g_scanner_destroy(), g_scanner_scope_foreach_symbol(), and main().

00291 {
00292   GHashNode *node;
00293   gint i;
00294   
00295   g_return_if_fail (hash_table != NULL);
00296   g_return_if_fail (func != NULL);
00297   
00298   for (i = 0; i < hash_table->size; i++)
00299     for (node = hash_table->nodes[i]; node; node = node->next)
00300       (* func) (node->key, node->value, user_data);
00301 }

guint g_hash_table_foreach_remove GHashTable hash_table,
GHRFunc  func,
gpointer  user_data
 

Definition at line 240 of file ghash.c.

References _GHashTable::frozen, g_hash_node_destroy(), g_hash_table_resize(), g_return_val_if_fail, _GHashNode::key, _GHashNode::next, _GHashTable::nnodes, _GHashTable::nodes, NULL, and _GHashNode::value.

Referenced by main().

00243 {
00244   GHashNode *node, *prev;
00245   guint i;
00246   guint deleted = 0;
00247   
00248   g_return_val_if_fail (hash_table != NULL, 0);
00249   g_return_val_if_fail (func != NULL, 0);
00250   
00251   for (i = 0; i < hash_table->size; i++)
00252     {
00253     restart:
00254       
00255       prev = NULL;
00256       
00257       for (node = hash_table->nodes[i]; node; prev = node, node = node->next)
00258         {
00259           if ((* func) (node->key, node->value, user_data))
00260             {
00261               deleted += 1;
00262               
00263               hash_table->nnodes -= 1;
00264               
00265               if (prev)
00266                 {
00267                   prev->next = node->next;
00268                   g_hash_node_destroy (node);
00269                   node = prev;
00270                 }
00271               else
00272                 {
00273                   hash_table->nodes[i] = node->next;
00274                   g_hash_node_destroy (node);
00275                   goto restart;
00276                 }
00277             }
00278         }
00279     }
00280   
00281   if (!hash_table->frozen)
00282     g_hash_table_resize (hash_table);
00283   
00284   return deleted;
00285 }

void g_hash_table_freeze GHashTable hash_table  ) 
 

Definition at line 222 of file ghash.c.

References _GHashTable::frozen, g_return_if_fail, and NULL.

Referenced by g_scanner_freeze_symbol_table().

00223 {
00224   g_return_if_fail (hash_table != NULL);
00225   
00226   hash_table->frozen++;
00227 }

void g_hash_table_insert GHashTable hash_table,
gpointer  key,
gpointer  value
 

Definition at line 146 of file ghash.c.

References _GHashTable::frozen, g_hash_node_new(), g_hash_table_lookup_node(), g_hash_table_resize(), g_return_if_fail, _GHashTable::nnodes, and NULL.

Referenced by direct_hash_test(), g_cache_insert(), g_dataset_id_set_data_full(), g_quark_new(), g_relation_insert(), g_scanner_scope_add_symbol(), g_string_chunk_insert_const(), main(), and second_hash_test().

00149 {
00150   GHashNode **node;
00151   
00152   g_return_if_fail (hash_table != NULL);
00153   
00154   node = g_hash_table_lookup_node (hash_table, key);
00155   
00156   if (*node)
00157     {
00158       /* do not reset node->key in this place, keeping
00159        * the old key might be intended.
00160        * a g_hash_table_remove/g_hash_table_insert pair
00161        * can be used otherwise.
00162        *
00163        * node->key = key; */
00164       (*node)->value = value;
00165     }
00166   else
00167     {
00168       *node = g_hash_node_new (key, value);
00169       hash_table->nnodes++;
00170       if (!hash_table->frozen)
00171         g_hash_table_resize (hash_table);
00172     }
00173 }

gpointer g_hash_table_lookup GHashTable hash_table,
gconstpointer  key
 

Definition at line 133 of file ghash.c.

References g_hash_table_lookup_node(), g_return_val_if_fail, NULL, and _GHashNode::value.

Referenced by direct_hash_test(), g_cache_insert(), g_cache_remove(), g_dataset_lookup(), g_quark_from_static_string(), g_quark_from_string(), g_quark_try_string(), g_relation_count(), g_relation_delete(), g_relation_delete_tuple(), g_relation_exists(), g_relation_insert(), g_relation_select(), g_scanner_lookup_internal(), g_string_chunk_insert_const(), and second_hash_test().

00135 {
00136   GHashNode *node;
00137   
00138   g_return_val_if_fail (hash_table != NULL, NULL);
00139   
00140   node = *g_hash_table_lookup_node (hash_table, key);
00141   
00142   return node ? node->value : NULL;
00143 }

gboolean g_hash_table_lookup_extended GHashTable hash_table,
gconstpointer  lookup_key,
gpointer orig_key,
gpointer value
 

Definition at line 198 of file ghash.c.

References FALSE, g_hash_table_lookup_node(), g_return_val_if_fail, _GHashNode::key, NULL, TRUE, and _GHashNode::value.

Referenced by second_hash_test().

00202 {
00203   GHashNode *node;
00204   
00205   g_return_val_if_fail (hash_table != NULL, FALSE);
00206   
00207   node = *g_hash_table_lookup_node (hash_table, lookup_key);
00208   
00209   if (node)
00210     {
00211       if (orig_key)
00212         *orig_key = node->key;
00213       if (value)
00214         *value = node->value;
00215       return TRUE;
00216     }
00217   else
00218     return FALSE;
00219 }

static GHashNode ** g_hash_table_lookup_node GHashTable hash_table,
gconstpointer  key
[inline, static]
 

Definition at line 109 of file ghash.c.

References _GHashTable::hash_func, _GHashNode::key, _GHashTable::key_compare_func, _GHashNode::next, _GHashTable::nodes, and _GHashTable::size.

Referenced by g_hash_table_insert(), g_hash_table_lookup(), g_hash_table_lookup_extended(), and g_hash_table_remove().

00111 {
00112   GHashNode **node;
00113   
00114   node = &hash_table->nodes
00115     [(* hash_table->hash_func) (key) % hash_table->size];
00116   
00117   /* Hash table lookup needs to be fast.
00118    *  We therefore remove the extra conditional of testing
00119    *  whether to call the key_compare_func or not from
00120    *  the inner loop.
00121    */
00122   if (hash_table->key_compare_func)
00123     while (*node && !(*hash_table->key_compare_func) ((*node)->key, key))
00124       node = &(*node)->next;
00125   else
00126     while (*node && (*node)->key != key)
00127       node = &(*node)->next;
00128   
00129   return node;
00130 }

GHashTable* g_hash_table_new GHashFunc  hash_func,
GCompareFunc  key_compare_func
 

Definition at line 74 of file ghash.c.

References FALSE, _GHashTable::frozen, g_direct_hash(), g_new, _GHashTable::hash_func, HASH_TABLE_MIN_SIZE, _GHashTable::key_compare_func, _GHashTable::nnodes, _GHashTable::nodes, NULL, and _GHashTable::size.

Referenced by direct_hash_test(), g_cache_new(), g_data_initialize(), g_quark_from_static_string(), g_quark_from_string(), g_relation_index(), g_relation_insert(), g_relation_new(), g_scanner_new(), g_string_chunk_insert_const(), main(), and second_hash_test().

00076 {
00077   GHashTable *hash_table;
00078   guint i;
00079   
00080   hash_table = g_new (GHashTable, 1);
00081   hash_table->size = HASH_TABLE_MIN_SIZE;
00082   hash_table->nnodes = 0;
00083   hash_table->frozen = FALSE;
00084   hash_table->hash_func = hash_func ? hash_func : g_direct_hash;
00085   hash_table->key_compare_func = key_compare_func;
00086   hash_table->nodes = g_new (GHashNode*, hash_table->size);
00087   
00088   for (i = 0; i < hash_table->size; i++)
00089     hash_table->nodes[i] = NULL;
00090   
00091   return hash_table;
00092 }

void g_hash_table_remove GHashTable hash_table,
gconstpointer  key
 

Definition at line 176 of file ghash.c.

References _GHashTable::frozen, g_hash_node_destroy(), g_hash_table_lookup_node(), g_hash_table_resize(), g_return_if_fail, _GHashNode::next, _GHashTable::nnodes, and NULL.

Referenced by g_cache_remove(), g_dataset_destroy_internal(), g_relation_delete(), g_relation_delete_tuple(), g_scanner_scope_remove_symbol(), and main().

00178 {
00179   GHashNode **node, *dest;
00180   
00181   g_return_if_fail (hash_table != NULL);
00182   
00183   node = g_hash_table_lookup_node (hash_table, key);
00184 
00185   if (*node)
00186     {
00187       dest = *node;
00188       (*node) = dest->next;
00189       g_hash_node_destroy (dest);
00190       hash_table->nnodes--;
00191   
00192       if (!hash_table->frozen)
00193         g_hash_table_resize (hash_table);
00194     }
00195 }

static void g_hash_table_resize GHashTable hash_table  )  [static]
 

Definition at line 313 of file ghash.c.

References CLAMP, g_free(), g_new0, g_spaced_primes_closest(), _GHashTable::hash_func, HASH_TABLE_MAX_SIZE, HASH_TABLE_MIN_SIZE, _GHashNode::key, _GHashNode::next, _GHashTable::nnodes, _GHashTable::nodes, and _GHashTable::size.

Referenced by g_hash_table_foreach_remove(), g_hash_table_insert(), g_hash_table_remove(), and g_hash_table_thaw().

00314 {
00315   GHashNode **new_nodes;
00316   GHashNode *node;
00317   GHashNode *next;
00318   gfloat nodes_per_list;
00319   guint hash_val;
00320   gint new_size;
00321   gint i;
00322   
00323   nodes_per_list = (gfloat) hash_table->nnodes / (gfloat) hash_table->size;
00324   
00325   if ((nodes_per_list > 0.3 || hash_table->size <= HASH_TABLE_MIN_SIZE) &&
00326       (nodes_per_list < 3.0 || hash_table->size >= HASH_TABLE_MAX_SIZE))
00327     return;
00328   
00329   new_size = CLAMP(g_spaced_primes_closest (hash_table->nnodes),
00330                    HASH_TABLE_MIN_SIZE,
00331                    HASH_TABLE_MAX_SIZE);
00332   new_nodes = g_new0 (GHashNode*, new_size);
00333   
00334   for (i = 0; i < hash_table->size; i++)
00335     for (node = hash_table->nodes[i]; node; node = next)
00336       {
00337         next = node->next;
00338 
00339         hash_val = (* hash_table->hash_func) (node->key) % new_size;
00340 
00341         node->next = new_nodes[hash_val];
00342         new_nodes[hash_val] = node;
00343       }
00344   
00345   g_free (hash_table->nodes);
00346   hash_table->nodes = new_nodes;
00347   hash_table->size = new_size;
00348 }

guint g_hash_table_size GHashTable hash_table  ) 
 

Definition at line 305 of file ghash.c.

References g_return_val_if_fail, _GHashTable::nnodes, and NULL.

Referenced by direct_hash_test(), g_relation_count(), main(), and second_hash_test().

00306 {
00307   g_return_val_if_fail (hash_table != NULL, 0);
00308   
00309   return hash_table->nnodes;
00310 }

void g_hash_table_thaw GHashTable hash_table  ) 
 

Definition at line 230 of file ghash.c.

References _GHashTable::frozen, g_hash_table_resize(), g_return_if_fail, and NULL.

Referenced by g_scanner_thaw_symbol_table().

00231 {
00232   g_return_if_fail (hash_table != NULL);
00233   
00234   if (hash_table->frozen)
00235     if (!(--hash_table->frozen))
00236       g_hash_table_resize (hash_table);
00237 }

G_LOCK_DEFINE_STATIC g_hash_global   ) 
 


Variable Documentation

GHashNode* node_free_list = NULL [static]
 

Definition at line 70 of file ghash.c.

GMemChunk* node_mem_chunk = NULL [static]
 

Definition at line 69 of file ghash.c.


© sourcejam.com 2005-2008