honour g_mem_gc_friendly settings when freeing slices, make sure
[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 #include "config.h"
32
33 #include "glib.h"
34 #include "galias.h"
35
36
37 #define HASH_TABLE_MIN_SIZE 11
38 #define HASH_TABLE_MAX_SIZE 13845163
39
40
41 typedef struct _GHashNode      GHashNode;
42
43 struct _GHashNode
44 {
45   gpointer   key;
46   gpointer   value;
47   GHashNode *next;
48 };
49
50 struct _GHashTable
51 {
52   gint             size;
53   gint             nnodes;
54   GHashNode      **nodes;
55   GHashFunc        hash_func;
56   GEqualFunc       key_equal_func;
57   volatile guint   ref_count;
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 /**
89  * g_hash_table_new:
90  * @hash_func: a function to create a hash value from a key.
91  *   Hash values are used to determine where keys are stored within the
92  *   #GHashTable data structure. The g_direct_hash(), g_int_hash() and 
93  *   g_str_hash() functions are provided for some common types of keys. 
94  *   If hash_func is %NULL, g_direct_hash() is used.
95  * @key_equal_func: a function to check two keys for equality.  This is
96  *   used when looking up keys in the #GHashTable.  The g_direct_equal(),
97  *   g_int_equal() and g_str_equal() functions are provided for the most
98  *   common types of keys. If @key_equal_func is %NULL, keys are compared
99  *   directly in a similar fashion to g_direct_equal(), but without the
100  *   overhead of a function call.
101  *
102  * Creates a new #GHashTable with a reference count of 1.
103  * 
104  * Return value: a new #GHashTable.
105  **/
106 GHashTable*
107 g_hash_table_new (GHashFunc    hash_func,
108                   GEqualFunc   key_equal_func)
109 {
110   return g_hash_table_new_full (hash_func, key_equal_func, NULL, NULL);
111 }
112
113
114 /**
115  * g_hash_table_new_full:
116  * @hash_func: a function to create a hash value from a key.
117  * @key_equal_func: a function to check two keys for equality.
118  * @key_destroy_func: a function to free the memory allocated for the key 
119  *   used when removing the entry from the #GHashTable or %NULL if you 
120  *   don't want to supply such a function.
121  * @value_destroy_func: a function to free the memory allocated for the 
122  *   value used when removing the entry from the #GHashTable or %NULL if 
123  *   you don't want to supply such a function.
124  * 
125  * Creates a new #GHashTable like g_hash_table_new() with a reference count
126  * of 1 and allows to specify functions to free the memory allocated for the
127  * key and value that get called when removing the entry from the #GHashTable.
128  * 
129  * Return value: a new #GHashTable.
130  **/
131 GHashTable*
132 g_hash_table_new_full (GHashFunc       hash_func,
133                        GEqualFunc      key_equal_func,
134                        GDestroyNotify  key_destroy_func,
135                        GDestroyNotify  value_destroy_func)
136 {
137   GHashTable *hash_table;
138   
139   hash_table = g_slice_new (GHashTable);
140   hash_table->size               = HASH_TABLE_MIN_SIZE;
141   hash_table->nnodes             = 0;
142   hash_table->hash_func          = hash_func ? hash_func : g_direct_hash;
143   hash_table->key_equal_func     = key_equal_func;
144   hash_table->ref_count          = 1;
145   hash_table->key_destroy_func   = key_destroy_func;
146   hash_table->value_destroy_func = value_destroy_func;
147   hash_table->nodes              = g_new0 (GHashNode*, hash_table->size);
148   
149   return hash_table;
150 }
151
152
153 /**
154  * g_hash_table_ref:
155  * @hash_table: a valid #GHashTable.
156  * 
157  * Atomically increments the reference count of @hash_table by one.
158  * This function is MT-safe and may be called from any thread.
159  * 
160  * Return value: the passed in #GHashTable.
161  * 
162  * Since: 2.10
163  **/
164 GHashTable*
165 g_hash_table_ref (GHashTable *hash_table)
166 {
167   g_return_val_if_fail (hash_table != NULL, NULL);
168   g_return_val_if_fail (hash_table->ref_count > 0, hash_table);
169
170   g_atomic_int_add (&hash_table->ref_count, 1);
171   return hash_table;
172 }
173
174 /**
175  * g_hash_table_unref:
176  * @hash_table: a valid #GHashTable.
177  * 
178  * Atomically decrements the reference count of @hash_table by one.
179  * If the reference count drops to 0, all keys and values will be
180  * destroyed, and all memory allocated by the hash table is released.
181  * This function is MT-safe and may be called from any thread.
182  * 
183  * Since: 2.10
184  **/
185 void
186 g_hash_table_unref (GHashTable *hash_table)
187 {
188   g_return_if_fail (hash_table != NULL);
189   g_return_if_fail (hash_table->ref_count > 0);
190
191   if (g_atomic_int_exchange_and_add (&hash_table->ref_count, -1) - 1 == 0)
192     {
193       gint i;
194
195       for (i = 0; i < hash_table->size; i++)
196         g_hash_nodes_destroy (hash_table->nodes[i], 
197                               hash_table->key_destroy_func,
198                               hash_table->value_destroy_func);
199       g_free (hash_table->nodes);
200       g_slice_free (GHashTable, hash_table);
201     }
202 }
203
204 /**
205  * g_hash_table_destroy:
206  * @hash_table: a #GHashTable.
207  * 
208  * Destroys all keys and values in the #GHashTable and decrements its
209  * reference count by 1. If keys and/or values are dynamically allocated,
210  * you should either free them first or create the #GHashTable with destroy
211  * notifiers using g_hash_table_new_full(). In the latter case the destroy
212  * functions you supplied will be called on all keys and values during the
213  * destruction phase.
214  **/
215 void
216 g_hash_table_destroy (GHashTable *hash_table)
217 {
218   gint i;
219   
220   g_return_if_fail (hash_table != NULL);
221   g_return_if_fail (hash_table->ref_count > 0);
222   
223   for (i = 0; i < hash_table->size; i++)
224     {
225       g_hash_nodes_destroy (hash_table->nodes[i], 
226                             hash_table->key_destroy_func,
227                             hash_table->value_destroy_func);
228       hash_table->nodes[i] = NULL;
229     }
230   hash_table->nnodes = 0;
231   hash_table->size = HASH_TABLE_MIN_SIZE;
232
233   g_hash_table_unref (hash_table);
234 }
235
236 static inline GHashNode**
237 g_hash_table_lookup_node (GHashTable    *hash_table,
238                           gconstpointer  key)
239 {
240   GHashNode **node;
241   
242   node = &hash_table->nodes
243     [(* hash_table->hash_func) (key) % hash_table->size];
244   
245   /* Hash table lookup needs to be fast.
246    *  We therefore remove the extra conditional of testing
247    *  whether to call the key_equal_func or not from
248    *  the inner loop.
249    */
250   if (hash_table->key_equal_func)
251     while (*node && !(*hash_table->key_equal_func) ((*node)->key, key))
252       node = &(*node)->next;
253   else
254     while (*node && (*node)->key != key)
255       node = &(*node)->next;
256   
257   return node;
258 }
259
260 /**
261  * g_hash_table_lookup:
262  * @hash_table: a #GHashTable.
263  * @key: the key to look up.
264  * 
265  * Looks up a key in a #GHashTable. Note that this function cannot
266  * distinguish between a key that is not present and one which is present
267  * and has the value %NULL. If you need this distinction, use
268  * g_hash_table_lookup_extended().
269  * 
270  * Return value: the associated value, or %NULL if the key is not found.
271  **/
272 gpointer
273 g_hash_table_lookup (GHashTable   *hash_table,
274                      gconstpointer key)
275 {
276   GHashNode *node;
277   
278   g_return_val_if_fail (hash_table != NULL, NULL);
279   
280   node = *g_hash_table_lookup_node (hash_table, key);
281   
282   return node ? node->value : NULL;
283 }
284
285 /**
286  * g_hash_table_lookup_extended:
287  * @hash_table: a #GHashTable.
288  * @lookup_key: the key to look up.
289  * @orig_key: returns the original key.
290  * @value: returns the value associated with the key.
291  * 
292  * Looks up a key in the #GHashTable, returning the original key and the
293  * associated value and a #gboolean which is %TRUE if the key was found. This 
294  * is useful if you need to free the memory allocated for the original key, 
295  * for example before calling g_hash_table_remove().
296  * 
297  * Return value: %TRUE if the key was found in the #GHashTable.
298  **/
299 gboolean
300 g_hash_table_lookup_extended (GHashTable    *hash_table,
301                               gconstpointer  lookup_key,
302                               gpointer      *orig_key,
303                               gpointer      *value)
304 {
305   GHashNode *node;
306   
307   g_return_val_if_fail (hash_table != NULL, FALSE);
308   
309   node = *g_hash_table_lookup_node (hash_table, lookup_key);
310   
311   if (node)
312     {
313       if (orig_key)
314         *orig_key = node->key;
315       if (value)
316         *value = node->value;
317       return TRUE;
318     }
319   else
320     return FALSE;
321 }
322
323 /**
324  * g_hash_table_insert:
325  * @hash_table: a #GHashTable.
326  * @key: a key to insert.
327  * @value: the value to associate with the key.
328  * 
329  * Inserts a new key and value into a #GHashTable.
330  * 
331  * If the key already exists in the #GHashTable its current value is replaced
332  * with the new value. If you supplied a @value_destroy_func when creating the 
333  * #GHashTable, the old value is freed using that function. If you supplied
334  * a @key_destroy_func when creating the #GHashTable, the passed key is freed 
335  * using that function.
336  **/
337 void
338 g_hash_table_insert (GHashTable *hash_table,
339                      gpointer    key,
340                      gpointer    value)
341 {
342   GHashNode **node;
343   
344   g_return_if_fail (hash_table != NULL);
345   g_return_if_fail (hash_table->ref_count > 0);
346   
347   node = g_hash_table_lookup_node (hash_table, key);
348   
349   if (*node)
350     {
351       /* do not reset node->key in this place, keeping
352        * the old key is the intended behaviour. 
353        * g_hash_table_replace() can be used instead.
354        */
355
356       /* free the passed key */
357       if (hash_table->key_destroy_func)
358         hash_table->key_destroy_func (key);
359       
360       if (hash_table->value_destroy_func)
361         hash_table->value_destroy_func ((*node)->value);
362
363       (*node)->value = value;
364     }
365   else
366     {
367       *node = g_hash_node_new (key, value);
368       hash_table->nnodes++;
369       G_HASH_TABLE_RESIZE (hash_table);
370     }
371 }
372
373 /**
374  * g_hash_table_replace:
375  * @hash_table: a #GHashTable.
376  * @key: a key to insert.
377  * @value: the value to associate with the key.
378  * 
379  * Inserts a new key and value into a #GHashTable similar to 
380  * g_hash_table_insert(). The difference is that if the key already exists 
381  * in the #GHashTable, it gets replaced by the new key. If you supplied a 
382  * @value_destroy_func when creating the #GHashTable, the old value is freed 
383  * using that function. If you supplied a @key_destroy_func when creating the 
384  * #GHashTable, the old key is freed using that function. 
385  **/
386 void
387 g_hash_table_replace (GHashTable *hash_table,
388                       gpointer    key,
389                       gpointer    value)
390 {
391   GHashNode **node;
392   
393   g_return_if_fail (hash_table != NULL);
394   g_return_if_fail (hash_table->ref_count > 0);
395   
396   node = g_hash_table_lookup_node (hash_table, key);
397   
398   if (*node)
399     {
400       if (hash_table->key_destroy_func)
401         hash_table->key_destroy_func ((*node)->key);
402       
403       if (hash_table->value_destroy_func)
404         hash_table->value_destroy_func ((*node)->value);
405
406       (*node)->key   = key;
407       (*node)->value = value;
408     }
409   else
410     {
411       *node = g_hash_node_new (key, value);
412       hash_table->nnodes++;
413       G_HASH_TABLE_RESIZE (hash_table);
414     }
415 }
416
417 /**
418  * g_hash_table_remove:
419  * @hash_table: a #GHashTable.
420  * @key: the key to remove.
421  * 
422  * Removes a key and its associated value from a #GHashTable.
423  *
424  * If the #GHashTable was created using g_hash_table_new_full(), the
425  * key and value are freed using the supplied destroy functions, otherwise
426  * you have to make sure that any dynamically allocated values are freed 
427  * yourself.
428  * 
429  * Return value: %TRUE if the key was found and removed from the #GHashTable.
430  **/
431 gboolean
432 g_hash_table_remove (GHashTable    *hash_table,
433                      gconstpointer  key)
434 {
435   GHashNode **node, *dest;
436   
437   g_return_val_if_fail (hash_table != NULL, FALSE);
438   
439   node = g_hash_table_lookup_node (hash_table, key);
440   if (*node)
441     {
442       dest = *node;
443       (*node) = dest->next;
444       g_hash_node_destroy (dest, 
445                            hash_table->key_destroy_func,
446                            hash_table->value_destroy_func);
447       hash_table->nnodes--;
448   
449       G_HASH_TABLE_RESIZE (hash_table);
450
451       return TRUE;
452     }
453
454   return FALSE;
455 }
456
457 /**
458  * g_hash_table_steal:
459  * @hash_table: a #GHashTable.
460  * @key: the key to remove.
461  * 
462  * Removes a key and its associated value from a #GHashTable without
463  * calling the key and value destroy functions.
464  *
465  * Return value: %TRUE if the key was found and removed from the #GHashTable.
466  **/
467 gboolean
468 g_hash_table_steal (GHashTable    *hash_table,
469                     gconstpointer  key)
470 {
471   GHashNode **node, *dest;
472   
473   g_return_val_if_fail (hash_table != NULL, FALSE);
474   
475   node = g_hash_table_lookup_node (hash_table, key);
476   if (*node)
477     {
478       dest = *node;
479       (*node) = dest->next;
480       g_hash_node_destroy (dest, NULL, NULL);
481       hash_table->nnodes--;
482   
483       G_HASH_TABLE_RESIZE (hash_table);
484
485       return TRUE;
486     }
487
488   return FALSE;
489 }
490
491 /**
492  * g_hash_table_foreach_remove:
493  * @hash_table: a #GHashTable.
494  * @func: the function to call for each key/value pair.
495  * @user_data: user data to pass to the function.
496  * 
497  * Calls the given function for each key/value pair in the #GHashTable.
498  * If the function returns %TRUE, then the key/value pair is removed from the
499  * #GHashTable. If you supplied key or value destroy functions when creating
500  * the #GHashTable, they are used to free the memory allocated for the removed
501  * keys and values.
502  * 
503  * Return value: the number of key/value pairs removed.
504  **/
505 guint
506 g_hash_table_foreach_remove (GHashTable *hash_table,
507                              GHRFunc     func,
508                              gpointer    user_data)
509 {
510   g_return_val_if_fail (hash_table != NULL, 0);
511   g_return_val_if_fail (func != NULL, 0);
512   
513   return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, TRUE);
514 }
515
516 /**
517  * g_hash_table_foreach_steal:
518  * @hash_table: a #GHashTable.
519  * @func: the function to call for each key/value pair.
520  * @user_data: user data to pass to the function.
521  * 
522  * Calls the given function for each key/value pair in the #GHashTable.
523  * If the function returns %TRUE, then the key/value pair is removed from the
524  * #GHashTable, but no key or value destroy functions are called.
525  * 
526  * Return value: the number of key/value pairs removed.
527  **/
528 guint
529 g_hash_table_foreach_steal (GHashTable *hash_table,
530                             GHRFunc     func,
531                             gpointer    user_data)
532 {
533   g_return_val_if_fail (hash_table != NULL, 0);
534   g_return_val_if_fail (func != NULL, 0);
535   
536   return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, FALSE);
537 }
538
539 static guint
540 g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
541                                       GHRFunc     func,
542                                       gpointer    user_data,
543                                       gboolean    notify)
544 {
545   GHashNode *node, *prev;
546   gint i;
547   guint deleted = 0;
548   
549   for (i = 0; i < hash_table->size; i++)
550     {
551     restart:
552       
553       prev = NULL;
554       
555       for (node = hash_table->nodes[i]; node; prev = node, node = node->next)
556         {
557           if ((* func) (node->key, node->value, user_data))
558             {
559               deleted += 1;
560               
561               hash_table->nnodes -= 1;
562               
563               if (prev)
564                 {
565                   prev->next = node->next;
566                   g_hash_node_destroy (node,
567                                        notify ? hash_table->key_destroy_func : NULL,
568                                        notify ? hash_table->value_destroy_func : NULL);
569                   node = prev;
570                 }
571               else
572                 {
573                   hash_table->nodes[i] = node->next;
574                   g_hash_node_destroy (node,
575                                        notify ? hash_table->key_destroy_func : NULL,
576                                        notify ? hash_table->value_destroy_func : NULL);
577                   goto restart;
578                 }
579             }
580         }
581     }
582   
583   G_HASH_TABLE_RESIZE (hash_table);
584   
585   return deleted;
586 }
587
588 /**
589  * g_hash_table_foreach:
590  * @hash_table: a #GHashTable.
591  * @func: the function to call for each key/value pair.
592  * @user_data: user data to pass to the function.
593  * 
594  * Calls the given function for each of the key/value pairs in the
595  * #GHashTable.  The function is passed the key and value of each
596  * pair, and the given @user_data parameter.  The hash table may not
597  * be modified while iterating over it (you can't add/remove
598  * items). To remove all items matching a predicate, use
599  * g_hash_table_foreach_remove().
600  **/
601 void
602 g_hash_table_foreach (GHashTable *hash_table,
603                       GHFunc      func,
604                       gpointer    user_data)
605 {
606   GHashNode *node;
607   gint i;
608   
609   g_return_if_fail (hash_table != NULL);
610   g_return_if_fail (func != NULL);
611   
612   for (i = 0; i < hash_table->size; i++)
613     for (node = hash_table->nodes[i]; node; node = node->next)
614       (* func) (node->key, node->value, user_data);
615 }
616
617 /**
618  * g_hash_table_find:
619  * @hash_table: a #GHashTable.
620  * @predicate:  function to test the key/value pairs for a certain property.
621  * @user_data:  user data to pass to the function.
622  * 
623  * Calls the given function for key/value pairs in the #GHashTable until 
624  * @predicate returns %TRUE.  The function is passed the key and value of 
625  * each pair, and the given @user_data parameter. The hash table may not
626  * be modified while iterating over it (you can't add/remove items). 
627  *
628  * Return value: The value of the first key/value pair is returned, for which 
629  * func evaluates to %TRUE. If no pair with the requested property is found, 
630  * %NULL is returned.
631  *
632  * Since: 2.4
633  **/
634 gpointer
635 g_hash_table_find (GHashTable      *hash_table,
636                    GHRFunc          predicate,
637                    gpointer         user_data)
638 {
639   GHashNode *node;
640   gint i;
641   
642   g_return_val_if_fail (hash_table != NULL, NULL);
643   g_return_val_if_fail (predicate != NULL, NULL);
644   
645   for (i = 0; i < hash_table->size; i++)
646     for (node = hash_table->nodes[i]; node; node = node->next)
647       if (predicate (node->key, node->value, user_data))
648         return node->value;       
649   return NULL;
650 }
651
652 /**
653  * g_hash_table_size:
654  * @hash_table: a #GHashTable.
655  * 
656  * Returns the number of elements contained in the #GHashTable.
657  * 
658  * Return value: the number of key/value pairs in the #GHashTable.
659  **/
660 guint
661 g_hash_table_size (GHashTable *hash_table)
662 {
663   g_return_val_if_fail (hash_table != NULL, 0);
664   
665   return hash_table->nnodes;
666 }
667
668 static void
669 g_hash_table_resize (GHashTable *hash_table)
670 {
671   GHashNode **new_nodes;
672   GHashNode *node;
673   GHashNode *next;
674   guint hash_val;
675   gint new_size;
676   gint i;
677
678   new_size = g_spaced_primes_closest (hash_table->nnodes);
679   new_size = CLAMP (new_size, HASH_TABLE_MIN_SIZE, HASH_TABLE_MAX_SIZE);
680  
681   new_nodes = g_new0 (GHashNode*, new_size);
682   
683   for (i = 0; i < hash_table->size; i++)
684     for (node = hash_table->nodes[i]; node; node = next)
685       {
686         next = node->next;
687
688         hash_val = (* hash_table->hash_func) (node->key) % new_size;
689
690         node->next = new_nodes[hash_val];
691         new_nodes[hash_val] = node;
692       }
693   
694   g_free (hash_table->nodes);
695   hash_table->nodes = new_nodes;
696   hash_table->size = new_size;
697 }
698
699 static GHashNode*
700 g_hash_node_new (gpointer key,
701                  gpointer value)
702 {
703   GHashNode *hash_node = g_slice_new (GHashNode);
704   
705   hash_node->key = key;
706   hash_node->value = value;
707   hash_node->next = NULL;
708   
709   return hash_node;
710 }
711
712 static void
713 g_hash_node_destroy (GHashNode      *hash_node,
714                      GDestroyNotify  key_destroy_func,
715                      GDestroyNotify  value_destroy_func)
716 {
717   if (key_destroy_func)
718     key_destroy_func (hash_node->key);
719   if (value_destroy_func)
720     value_destroy_func (hash_node->value);
721   g_slice_free (GHashNode, hash_node);
722 }
723
724 static void
725 g_hash_nodes_destroy (GHashNode *hash_node,
726                       GFreeFunc  key_destroy_func,
727                       GFreeFunc  value_destroy_func)
728 {
729   while (hash_node)
730     {
731       GHashNode *next = hash_node->next;
732       if (key_destroy_func)
733         key_destroy_func (hash_node->key);
734       if (value_destroy_func)
735         value_destroy_func (hash_node->value);
736       g_slice_free (GHashNode, hash_node);
737       hash_node = next;
738     }
739 }
740
741
742 #define __G_HASH_C__
743 #include "galiasdef.c"