Use <envar>, not <envvar>.
[platform/upstream/glib.git] / glib / ghash.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GLib Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 /* 
28  * MT safe
29  */
30
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 #include "glib.h"
36
37
38 #define HASH_TABLE_MIN_SIZE 11
39 #define HASH_TABLE_MAX_SIZE 13845163
40
41
42 typedef struct _GHashNode      GHashNode;
43
44 struct _GHashNode
45 {
46   gpointer   key;
47   gpointer   value;
48   GHashNode *next;
49 };
50
51 struct _GHashTable
52 {
53   gint             size;
54   gint             nnodes;
55   GHashNode      **nodes;
56   GHashFunc        hash_func;
57   GEqualFunc       key_equal_func;
58   GDestroyNotify   key_destroy_func;
59   GDestroyNotify   value_destroy_func;
60 };
61
62 #define G_HASH_TABLE_RESIZE(hash_table)                         \
63    G_STMT_START {                                               \
64      if ((hash_table->size >= 3 * hash_table->nnodes &&         \
65           hash_table->size > HASH_TABLE_MIN_SIZE) ||            \
66          (3 * hash_table->size <= hash_table->nnodes &&         \
67           hash_table->size < HASH_TABLE_MAX_SIZE))              \
68            g_hash_table_resize (hash_table);                    \
69    } G_STMT_END
70
71 static void             g_hash_table_resize       (GHashTable     *hash_table);
72 static GHashNode**      g_hash_table_lookup_node  (GHashTable     *hash_table,
73                                                    gconstpointer   key);
74 static GHashNode*       g_hash_node_new           (gpointer        key,
75                                                    gpointer        value);
76 static void             g_hash_node_destroy       (GHashNode      *hash_node,
77                                                    GDestroyNotify  key_destroy_func,
78                                                    GDestroyNotify  value_destroy_func);
79 static void             g_hash_nodes_destroy      (GHashNode      *hash_node,
80                                                   GDestroyNotify   key_destroy_func,
81                                                   GDestroyNotify   value_destroy_func);
82 static guint g_hash_table_foreach_remove_or_steal (GHashTable     *hash_table,
83                                                    GHRFunc         func,
84                                                    gpointer        user_data,
85                                                    gboolean        notify);
86
87
88 G_LOCK_DEFINE_STATIC (g_hash_global);
89
90 static GMemChunk *node_mem_chunk = NULL;
91 static GHashNode *node_free_list = NULL;
92
93 /**
94  * g_hash_table_new:
95  * @hash_func: a function to create a hash value from a key.
96  *   Hash values are used to determine where keys are stored within the
97  *   #GHashTable data structure. The g_direct_hash(), g_int_hash() and 
98  *   g_str_hash() functions are provided for some common types of keys. 
99  *   If hash_func is %NULL, g_direct_hash() is used.
100  * @key_equal_func: a function to check two keys for equality.  This is
101  *   used when looking up keys in the #GHashTable.  The g_direct_equal(),
102  *   g_int_equal() and g_str_equal() functions are provided for the most
103  *   common types of keys. If @key_equal_func is %NULL, keys are compared
104  *   directly in a similar fashion to g_direct_equal(), but without the
105  *   overhead of a function call.
106  *
107  * Creates a new #GHashTable.
108  * 
109  * Return value: a new #GHashTable.
110  **/
111 GHashTable*
112 g_hash_table_new (GHashFunc    hash_func,
113                   GEqualFunc   key_equal_func)
114 {
115   return g_hash_table_new_full (hash_func, key_equal_func, NULL, NULL);
116 }
117
118
119 /**
120  * g_hash_table_new_full:
121  * @hash_func: a function to create a hash value from a key.
122  * @key_equal_func: a function to check two keys for equality.
123  * @key_destroy_func: a function to free the memory allocated for the key 
124  *   used when removing the entry from the #GHashTable or %NULL if you 
125  *   don't want to supply such a function.
126  * @value_destroy_func: a function to free the memory allocated for the 
127  *   value used when removing the entry from the #GHashTable or %NULL if 
128  *   you don't want to supply such a function.
129  * 
130  * Creates a new #GHashTable like g_hash_table_new() and allows to specify
131  * functions to free the memory allocated for the key and value that get 
132  * called when removing the entry from the #GHashTable.
133  * 
134  * Return value: a new #GHashTable.
135  **/
136 GHashTable*
137 g_hash_table_new_full (GHashFunc       hash_func,
138                        GEqualFunc      key_equal_func,
139                        GDestroyNotify  key_destroy_func,
140                        GDestroyNotify  value_destroy_func)
141 {
142   GHashTable *hash_table;
143   guint i;
144   
145   hash_table = g_new (GHashTable, 1);
146   hash_table->size               = HASH_TABLE_MIN_SIZE;
147   hash_table->nnodes             = 0;
148   hash_table->hash_func          = hash_func ? hash_func : g_direct_hash;
149   hash_table->key_equal_func     = key_equal_func;
150   hash_table->key_destroy_func   = key_destroy_func;
151   hash_table->value_destroy_func = value_destroy_func;
152   hash_table->nodes              = g_new (GHashNode*, hash_table->size);
153   
154   for (i = 0; i < hash_table->size; i++)
155     hash_table->nodes[i] = NULL;
156   
157   return hash_table;
158 }
159
160 /**
161  * g_hash_table_destroy:
162  * @hash_table: a #GHashTable.
163  * 
164  * Destroys the #GHashTable. If keys and/or values are dynamically 
165  * allocated, you should either free them first or create the #GHashTable
166  * using g_hash_table_new_full(). In the latter case the destroy functions 
167  * you supplied will be called on all keys and values before destroying 
168  * the #GHashTable.
169  **/
170 void
171 g_hash_table_destroy (GHashTable *hash_table)
172 {
173   guint i;
174   
175   g_return_if_fail (hash_table != NULL);
176   
177   for (i = 0; i < hash_table->size; i++)
178     g_hash_nodes_destroy (hash_table->nodes[i], 
179                           hash_table->key_destroy_func,
180                           hash_table->value_destroy_func);
181   
182   g_free (hash_table->nodes);
183   g_free (hash_table);
184 }
185
186 static inline GHashNode**
187 g_hash_table_lookup_node (GHashTable    *hash_table,
188                           gconstpointer  key)
189 {
190   GHashNode **node;
191   
192   node = &hash_table->nodes
193     [(* hash_table->hash_func) (key) % hash_table->size];
194   
195   /* Hash table lookup needs to be fast.
196    *  We therefore remove the extra conditional of testing
197    *  whether to call the key_equal_func or not from
198    *  the inner loop.
199    */
200   if (hash_table->key_equal_func)
201     while (*node && !(*hash_table->key_equal_func) ((*node)->key, key))
202       node = &(*node)->next;
203   else
204     while (*node && (*node)->key != key)
205       node = &(*node)->next;
206   
207   return node;
208 }
209
210 /**
211  * g_hash_table_lookup:
212  * @hash_table: a #GHashTable.
213  * @key: the key to look up.
214  * 
215  * Looks up a key in a #GHashTable.
216  * 
217  * Return value: the associated value, or %NULL if the key is not found.
218  **/
219 gpointer
220 g_hash_table_lookup (GHashTable   *hash_table,
221                      gconstpointer key)
222 {
223   GHashNode *node;
224   
225   g_return_val_if_fail (hash_table != NULL, NULL);
226   
227   node = *g_hash_table_lookup_node (hash_table, key);
228   
229   return node ? node->value : NULL;
230 }
231
232 /**
233  * g_hash_table_lookup_extended:
234  * @hash_table: a #GHashTable.
235  * @lookup_key: the key to look up.
236  * @orig_key: returns the original key.
237  * @value: returns the value associated with the key.
238  * 
239  * Looks up a key in the #GHashTable, returning the original key and the
240  * associated value and a #gboolean which is %TRUE if the key was found. This 
241  * is useful if you need to free the memory allocated for the original key, 
242  * for example before calling g_hash_table_remove().
243  * 
244  * Return value: %TRUE if the key was found in the #GHashTable.
245  **/
246 gboolean
247 g_hash_table_lookup_extended (GHashTable    *hash_table,
248                               gconstpointer  lookup_key,
249                               gpointer      *orig_key,
250                               gpointer      *value)
251 {
252   GHashNode *node;
253   
254   g_return_val_if_fail (hash_table != NULL, FALSE);
255   
256   node = *g_hash_table_lookup_node (hash_table, lookup_key);
257   
258   if (node)
259     {
260       if (orig_key)
261         *orig_key = node->key;
262       if (value)
263         *value = node->value;
264       return TRUE;
265     }
266   else
267     return FALSE;
268 }
269
270 /**
271  * g_hash_table_insert:
272  * @hash_table: a #GHashTable.
273  * @key: a key to insert.
274  * @value: the value to associate with the key.
275  * 
276  * Inserts a new key and value into a #GHashTable.
277  * 
278  * If the key already exists in the #GHashTable its current value is replaced
279  * with the new value. If you supplied a @value_destroy_func when creating the 
280  * #GHashTable, the old value is freed using that function. If you supplied
281  * a @key_destroy_func when creating the #GHashTable, the passed key is freed 
282  * using that function.
283  **/
284 void
285 g_hash_table_insert (GHashTable *hash_table,
286                      gpointer    key,
287                      gpointer    value)
288 {
289   GHashNode **node;
290   
291   g_return_if_fail (hash_table != NULL);
292   
293   node = g_hash_table_lookup_node (hash_table, key);
294   
295   if (*node)
296     {
297       /* do not reset node->key in this place, keeping
298        * the old key is the intended behaviour. 
299        * g_hash_table_replace() can be used instead.
300        */
301
302       /* free the passed key */
303       if (hash_table->key_destroy_func)
304         hash_table->key_destroy_func (key);
305       
306       if (hash_table->value_destroy_func)
307         hash_table->value_destroy_func ((*node)->value);
308
309       (*node)->value = value;
310     }
311   else
312     {
313       *node = g_hash_node_new (key, value);
314       hash_table->nnodes++;
315       G_HASH_TABLE_RESIZE (hash_table);
316     }
317 }
318
319 /**
320  * g_hash_table_replace:
321  * @hash_table: a #GHashTable.
322  * @key: a key to insert.
323  * @value: the value to associate with the key.
324  * 
325  * Inserts a new key and value into a #GHashTable similar to 
326  * g_hash_table_insert(). The difference is that if the key already exists 
327  * in the #GHashTable, it gets replaced by the new key. If you supplied a 
328  * @value_destroy_func when creating the #GHashTable, the old value is freed 
329  * using that function. If you supplied a @key_destroy_func when creating the 
330  * #GHashTable, the old key is freed using that function. 
331  **/
332 void
333 g_hash_table_replace (GHashTable *hash_table,
334                       gpointer    key,
335                       gpointer    value)
336 {
337   GHashNode **node;
338   
339   g_return_if_fail (hash_table != NULL);
340   
341   node = g_hash_table_lookup_node (hash_table, key);
342   
343   if (*node)
344     {
345       if (hash_table->key_destroy_func)
346         hash_table->key_destroy_func ((*node)->key);
347       
348       if (hash_table->value_destroy_func)
349         hash_table->value_destroy_func ((*node)->value);
350
351       (*node)->key   = key;
352       (*node)->value = value;
353     }
354   else
355     {
356       *node = g_hash_node_new (key, value);
357       hash_table->nnodes++;
358       G_HASH_TABLE_RESIZE (hash_table);
359     }
360 }
361
362 /**
363  * g_hash_table_remove:
364  * @hash_table: a #GHashTable.
365  * @key: the key to remove.
366  * 
367  * Removes a key and its associated value from a #GHashTable.
368  *
369  * If the #GHashTable was created using g_hash_table_new_full(), the
370  * key and value are freed using the supplied destroy functions, otherwise
371  * you have to make sure that any dynamically allocated values are freed 
372  * yourself.
373  * 
374  * Return value: %TRUE if the key was found and removed from the #GHashTable.
375  **/
376 gboolean
377 g_hash_table_remove (GHashTable    *hash_table,
378                      gconstpointer  key)
379 {
380   GHashNode **node, *dest;
381   
382   g_return_val_if_fail (hash_table != NULL, FALSE);
383   
384   node = g_hash_table_lookup_node (hash_table, key);
385   if (*node)
386     {
387       dest = *node;
388       (*node) = dest->next;
389       g_hash_node_destroy (dest, 
390                            hash_table->key_destroy_func,
391                            hash_table->value_destroy_func);
392       hash_table->nnodes--;
393   
394       G_HASH_TABLE_RESIZE (hash_table);
395
396       return TRUE;
397     }
398
399   return FALSE;
400 }
401
402 /**
403  * g_hash_table_steal:
404  * @hash_table: a #GHashTable.
405  * @key: the key to remove.
406  * 
407  * Removes a key and its associated value from a #GHashTable without
408  * calling the key and value destroy functions.
409  *
410  * Return value: %TRUE if the key was found and removed from the #GHashTable.
411  **/
412 gboolean
413 g_hash_table_steal (GHashTable    *hash_table,
414                     gconstpointer  key)
415 {
416   GHashNode **node, *dest;
417   
418   g_return_val_if_fail (hash_table != NULL, FALSE);
419   
420   node = g_hash_table_lookup_node (hash_table, key);
421   if (*node)
422     {
423       dest = *node;
424       (*node) = dest->next;
425       g_hash_node_destroy (dest, NULL, NULL);
426       hash_table->nnodes--;
427   
428       G_HASH_TABLE_RESIZE (hash_table);
429
430       return TRUE;
431     }
432
433   return FALSE;
434 }
435
436 /**
437  * g_hash_table_foreach_remove:
438  * @hash_table: a #GHashTable.
439  * @func: the function to call for each key/value pair.
440  * @user_data: user data to pass to the function.
441  * 
442  * Calls the given function for each key/value pair in the #GHashTable.
443  * If the function returns %TRUE, then the key/value pair is removed from the
444  * #GHashTable. If you supplied key or value destroy functions when creating
445  * the #GHashTable, they are used to free the memory allocated for the removed
446  * keys and values.
447  * 
448  * Return value: the number of key/value pairs removed.
449  **/
450 guint
451 g_hash_table_foreach_remove (GHashTable *hash_table,
452                              GHRFunc     func,
453                              gpointer    user_data)
454 {
455   g_return_val_if_fail (hash_table != NULL, 0);
456   g_return_val_if_fail (func != NULL, 0);
457   
458   return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, TRUE);
459 }
460
461 /**
462  * g_hash_table_foreach_steal:
463  * @hash_table: a #GHashTable.
464  * @func: the function to call for each key/value pair.
465  * @user_data: user data to pass to the function.
466  * 
467  * Calls the given function for each key/value pair in the #GHashTable.
468  * If the function returns %TRUE, then the key/value pair is removed from the
469  * #GHashTable, but no key or value destroy functions are called.
470  * 
471  * Return value: the number of key/value pairs removed.
472  **/
473 guint
474 g_hash_table_foreach_steal (GHashTable *hash_table,
475                             GHRFunc     func,
476                             gpointer    user_data)
477 {
478   g_return_val_if_fail (hash_table != NULL, 0);
479   g_return_val_if_fail (func != NULL, 0);
480   
481   return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, FALSE);
482 }
483
484 static guint
485 g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
486                                       GHRFunc     func,
487                                       gpointer    user_data,
488                                       gboolean    notify)
489 {
490   GHashNode *node, *prev;
491   guint i;
492   guint deleted = 0;
493   
494   for (i = 0; i < hash_table->size; i++)
495     {
496     restart:
497       
498       prev = NULL;
499       
500       for (node = hash_table->nodes[i]; node; prev = node, node = node->next)
501         {
502           if ((* func) (node->key, node->value, user_data))
503             {
504               deleted += 1;
505               
506               hash_table->nnodes -= 1;
507               
508               if (prev)
509                 {
510                   prev->next = node->next;
511                   g_hash_node_destroy (node,
512                                        notify ? hash_table->key_destroy_func : NULL,
513                                        notify ? hash_table->value_destroy_func : NULL);
514                   node = prev;
515                 }
516               else
517                 {
518                   hash_table->nodes[i] = node->next;
519                   g_hash_node_destroy (node,
520                                        notify ? hash_table->key_destroy_func : NULL,
521                                        notify ? hash_table->value_destroy_func : NULL);
522                   goto restart;
523                 }
524             }
525         }
526     }
527   
528   G_HASH_TABLE_RESIZE (hash_table);
529   
530   return deleted;
531 }
532
533 /**
534  * g_hash_table_foreach:
535  * @hash_table: a #GHashTable.
536  * @func: the function to call for each key/value pair.
537  * @user_data: user data to pass to the function.
538  * 
539  * Calls the given function for each of the key/value pairs in the
540  * #GHashTable.  The function is passed the key and value of each
541  * pair, and the given @user_data parameter.  The hash table may not
542  * be modified while iterating over it (you can't add/remove
543  * items). To remove all items matching a predicate, use
544  * g_hash_table_remove().
545  **/
546 void
547 g_hash_table_foreach (GHashTable *hash_table,
548                       GHFunc      func,
549                       gpointer    user_data)
550 {
551   GHashNode *node;
552   gint i;
553   
554   g_return_if_fail (hash_table != NULL);
555   g_return_if_fail (func != NULL);
556   
557   for (i = 0; i < hash_table->size; i++)
558     for (node = hash_table->nodes[i]; node; node = node->next)
559       (* func) (node->key, node->value, user_data);
560 }
561
562 /**
563  * g_hash_table_size:
564  * @hash_table: a #GHashTable.
565  * 
566  * Returns the number of elements contained in the #GHashTable.
567  * 
568  * Return value: the number of key/value pairs in the #GHashTable.
569  **/
570 guint
571 g_hash_table_size (GHashTable *hash_table)
572 {
573   g_return_val_if_fail (hash_table != NULL, 0);
574   
575   return hash_table->nnodes;
576 }
577
578 static void
579 g_hash_table_resize (GHashTable *hash_table)
580 {
581   GHashNode **new_nodes;
582   GHashNode *node;
583   GHashNode *next;
584   guint hash_val;
585   gint new_size;
586   gint i;
587
588   new_size = CLAMP(g_spaced_primes_closest (hash_table->nnodes),
589                    HASH_TABLE_MIN_SIZE,
590                    HASH_TABLE_MAX_SIZE);
591   new_nodes = g_new0 (GHashNode*, new_size);
592   
593   for (i = 0; i < hash_table->size; i++)
594     for (node = hash_table->nodes[i]; node; node = next)
595       {
596         next = node->next;
597
598         hash_val = (* hash_table->hash_func) (node->key) % new_size;
599
600         node->next = new_nodes[hash_val];
601         new_nodes[hash_val] = node;
602       }
603   
604   g_free (hash_table->nodes);
605   hash_table->nodes = new_nodes;
606   hash_table->size = new_size;
607 }
608
609 static GHashNode*
610 g_hash_node_new (gpointer key,
611                  gpointer value)
612 {
613   GHashNode *hash_node;
614   
615   G_LOCK (g_hash_global);
616   if (node_free_list)
617     {
618       hash_node = node_free_list;
619       node_free_list = node_free_list->next;
620     }
621   else
622     {
623       if (!node_mem_chunk)
624         node_mem_chunk = g_mem_chunk_new ("hash node mem chunk",
625                                           sizeof (GHashNode),
626                                           1024, G_ALLOC_ONLY);
627       
628       hash_node = g_chunk_new (GHashNode, node_mem_chunk);
629     }
630   G_UNLOCK (g_hash_global);
631   
632   hash_node->key = key;
633   hash_node->value = value;
634   hash_node->next = NULL;
635   
636   return hash_node;
637 }
638
639 static void
640 g_hash_node_destroy (GHashNode      *hash_node,
641                      GDestroyNotify  key_destroy_func,
642                      GDestroyNotify  value_destroy_func)
643 {
644   if (key_destroy_func)
645     key_destroy_func (hash_node->key);
646   if (value_destroy_func)
647     value_destroy_func (hash_node->value);
648   
649 #ifdef ENABLE_GC_FRIENDLY
650   hash_node->key = NULL;
651   hash_node->value = NULL;
652 #endif /* ENABLE_GC_FRIENDLY */
653
654   G_LOCK (g_hash_global);
655   hash_node->next = node_free_list;
656   node_free_list = hash_node;
657   G_UNLOCK (g_hash_global);
658 }
659
660 static void
661 g_hash_nodes_destroy (GHashNode *hash_node,
662                       GFreeFunc  key_destroy_func,
663                       GFreeFunc  value_destroy_func)
664 {
665   if (hash_node)
666     {
667       GHashNode *node = hash_node;
668   
669       while (node->next)
670         {
671           if (key_destroy_func)
672             key_destroy_func (node->key);
673           if (value_destroy_func)
674             value_destroy_func (node->value);
675
676 #ifdef ENABLE_GC_FRIENDLY
677           node->key = NULL;
678           node->value = NULL;
679 #endif /* ENABLE_GC_FRIENDLY */
680
681           node = node->next;
682         }
683
684   if (key_destroy_func)
685     key_destroy_func (node->key);
686   if (value_destroy_func)
687     value_destroy_func (node->value);
688
689 #ifdef ENABLE_GC_FRIENDLY
690       node->key = NULL;
691       node->value = NULL;
692 #endif /* ENABLE_GC_FRIENDLY */
693  
694       G_LOCK (g_hash_global);
695       node->next = node_free_list;
696       node_free_list = hash_node;
697       G_UNLOCK (g_hash_global);
698     }
699 }