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