cmake/cross-compile.sh: use mktemp(1) to avoid a symlink attack in /tmp
[platform/upstream/dbus.git] / dbus / dbus-hash.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-hash.c Generic hash table utility (internal to D-Bus implementation)
3  * 
4  * Copyright (C) 2002  Red Hat, Inc.
5  * Copyright (c) 1991-1993 The Regents of the University of California.
6  * Copyright (c) 1994 Sun Microsystems, Inc.
7  * 
8  * Hash table implementation based on generic/tclHash.c from the Tcl
9  * source code. The original Tcl license applies to portions of the
10  * code from tclHash.c; the Tcl license follows this standad D-Bus 
11  * license information.
12  *
13  * Licensed under the Academic Free License version 2.1
14  * 
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  * 
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
28  *
29  */
30 /* 
31  * The following copyright applies to code from the Tcl distribution.
32  *
33  * Copyright (c) 1991-1993 The Regents of the University of California.
34  * Copyright (c) 1994 Sun Microsystems, Inc.
35  *
36  * This software is copyrighted by the Regents of the University of
37  * California, Sun Microsystems, Inc., Scriptics Corporation, and
38  * other parties.  The following terms apply to all files associated
39  * with the software unless explicitly disclaimed in individual files.
40  * 
41  * The authors hereby grant permission to use, copy, modify,
42  * distribute, and license this software and its documentation for any
43  * purpose, provided that existing copyright notices are retained in
44  * all copies and that this notice is included verbatim in any
45  * distributions. No written agreement, license, or royalty fee is
46  * required for any of the authorized uses.  Modifications to this
47  * software may be copyrighted by their authors and need not follow
48  * the licensing terms described here, provided that the new terms are
49  * clearly indicated on the first page of each file where they apply.
50  * 
51  * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
52  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
53  * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
54  * OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
55  * OF THE POSSIBILITY OF SUCH DAMAGE.
56  * 
57  * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
58  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
59  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
60  * NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
61  * AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
62  * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
63  * 
64  * GOVERNMENT USE: If you are acquiring this software on behalf of the
65  * U.S. government, the Government shall have only "Restricted Rights"
66  * in the software and related documentation as defined in the Federal
67  * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
68  * are acquiring the software on behalf of the Department of Defense,
69  * the software shall be classified as "Commercial Computer Software"
70  * and the Government shall have only "Restricted Rights" as defined
71  * in Clause 252.227-7013 (c) (1) of DFARs.  Notwithstanding the
72  * foregoing, the authors grant the U.S. Government and others acting
73  * in its behalf permission to use and distribute the software in
74  * accordance with the terms specified in this license.
75  */
76
77 #include <config.h>
78 #include "dbus-hash.h"
79 #include "dbus-internals.h"
80 #include "dbus-mempool.h"
81
82 /**
83  * @defgroup DBusHashTable Hash table
84  * @ingroup  DBusInternals
85  * @brief DBusHashTable data structure
86  *
87  * Types and functions related to DBusHashTable.
88  */
89
90 /**
91  * @defgroup DBusHashTableInternals Hash table implementation details
92  * @ingroup  DBusInternals
93  * @brief DBusHashTable implementation details
94  *
95  * The guts of DBusHashTable.
96  *
97  * @{
98  */
99
100 /**
101  * When there are this many entries per bucket, on average, rebuild
102  * the hash table to make it larger.
103  */
104 #define REBUILD_MULTIPLIER  3
105
106 /**
107  * Takes a preliminary integer hash value and produces an index into a
108  * hash tables bucket list.  The idea is to make it so that
109  * preliminary values that are arbitrarily similar will end up in
110  * different buckets.  The hash function was taken from a
111  * random-number generator. (This is used to hash integers.)
112  *
113  * The down_shift drops off the high bits of the hash index, and
114  * decreases as we increase the number of hash buckets (to keep more
115  * range in the hash index). The mask also strips high bits and strips
116  * fewer high bits as the number of hash buckets increases.
117  * I don't understand two things: why is the initial downshift 28
118  * to keep 4 bits when the initial mask is 011 to keep 2 bits,
119  * and why do we have both a mask and a downshift?
120  * 
121  */
122 #define RANDOM_INDEX(table, i) \
123     (((((intptr_t) (i))*1103515245) >> (table)->down_shift) & (table)->mask)
124
125 /**
126  * Initial number of buckets in hash table (hash table statically
127  * allocates its buckets for this size and below).
128  * The initial mask has to be synced to this.
129  */
130 #define DBUS_SMALL_HASH_TABLE 4
131
132 /**
133  * Typedef for DBusHashEntry
134  */
135 typedef struct DBusHashEntry DBusHashEntry;
136
137 /**
138  * @brief Internal representation of a hash entry.
139  * 
140  * A single entry (key-value pair) in the hash table.
141  * Internal to hash table implementation.
142  */
143 struct DBusHashEntry
144 {
145   DBusHashEntry *next;    /**< Pointer to next entry in this
146                            * hash bucket, or #NULL for end of
147                            * chain.
148                            */
149   void *key;              /**< Hash key */
150   void *value;            /**< Hash value */
151 };
152
153 /**
154  * Function used to find and optionally create a hash entry.
155  */
156 typedef DBusHashEntry* (* DBusFindEntryFunction) (DBusHashTable        *table,
157                                                   void                 *key,
158                                                   dbus_bool_t           create_if_not_found,
159                                                   DBusHashEntry      ***bucket,
160                                                   DBusPreallocatedHash *preallocated);
161
162 /**
163  * @brief Internals of DBusHashTable.
164  * 
165  * Hash table internals. Hash tables are opaque objects, they must be
166  * used via accessor functions.
167  */
168 struct DBusHashTable {
169   int refcount;                       /**< Reference count */
170   
171   DBusHashEntry **buckets;            /**< Pointer to bucket array.  Each
172                                        * element points to first entry in
173                                        * bucket's hash chain, or #NULL.
174                                        */
175   DBusHashEntry *static_buckets[DBUS_SMALL_HASH_TABLE];
176                                        /**< Bucket array used for small tables
177                                         * (to avoid mallocs and frees).
178                                         */
179   int n_buckets;                       /**< Total number of buckets allocated
180                                         * at **buckets.
181                                         */
182   int n_entries;                       /**< Total number of entries present
183                                         * in table.
184                                         */
185   int hi_rebuild_size;                 /**< Enlarge table when n_entries gets
186                                         * to be this large.
187                                         */
188   int lo_rebuild_size;                 /**< Shrink table when n_entries gets
189                                         * below this.
190                                         */
191   int down_shift;                      /**< Shift count used in hashing
192                                         * function.  Designed to use high-
193                                         * order bits of randomized keys.
194                                         */
195   int mask;                            /**< Mask value used in hashing
196                                         * function.
197                                         */
198   DBusHashType key_type;               /**< Type of keys used in this table */
199
200
201   DBusFindEntryFunction find_function; /**< Function for finding entries */
202
203   DBusFreeFunction free_key_function;   /**< Function to free keys */
204   DBusFreeFunction free_value_function; /**< Function to free values */
205
206   DBusMemPool *entry_pool;              /**< Memory pool for hash entries */
207 };
208
209 /** 
210  * @brief Internals of DBusHashIter.
211  */
212 typedef struct
213 {
214   DBusHashTable *table;     /**< Pointer to table containing entry. */
215   DBusHashEntry **bucket;   /**< Pointer to bucket that points to
216                              * first entry in this entry's chain:
217                              * used for deleting the entry.
218                              */
219   DBusHashEntry *entry;      /**< Current hash entry */
220   DBusHashEntry *next_entry; /**< Next entry to be iterated onto in current bucket */
221   int next_bucket;           /**< index of next bucket */
222   int n_entries_on_init;     /**< used to detect table resize since initialization */
223 } DBusRealHashIter;
224
225 static DBusHashEntry* find_direct_function      (DBusHashTable          *table,
226                                                  void                   *key,
227                                                  dbus_bool_t             create_if_not_found,
228                                                  DBusHashEntry        ***bucket,
229                                                  DBusPreallocatedHash   *preallocated);
230 static DBusHashEntry* find_string_function      (DBusHashTable          *table,
231                                                  void                   *key,
232                                                  dbus_bool_t             create_if_not_found,
233                                                  DBusHashEntry        ***bucket,
234                                                  DBusPreallocatedHash   *preallocated);
235 #ifdef DBUS_BUILD_TESTS
236 static DBusHashEntry* find_two_strings_function (DBusHashTable          *table,
237                                                  void                   *key,
238                                                  dbus_bool_t             create_if_not_found,
239                                                  DBusHashEntry        ***bucket,
240                                                  DBusPreallocatedHash   *preallocated);
241 #endif
242 static unsigned int   string_hash               (const char             *str);
243 #ifdef DBUS_BUILD_TESTS
244 static unsigned int   two_strings_hash          (const char             *str);
245 #endif
246 static void           rebuild_table             (DBusHashTable          *table);
247 static DBusHashEntry* alloc_entry               (DBusHashTable          *table);
248 static void           remove_entry              (DBusHashTable          *table,
249                                                  DBusHashEntry         **bucket,
250                                                  DBusHashEntry          *entry);
251 static void           free_entry                (DBusHashTable          *table,
252                                                  DBusHashEntry          *entry);
253 static void           free_entry_data           (DBusHashTable          *table,
254                                                  DBusHashEntry          *entry);
255
256
257 /** @} */
258
259 /**
260  * @addtogroup DBusHashTable
261  * @{
262  */
263
264 /**
265  * @typedef DBusHashIter
266  *
267  * Public opaque hash table iterator object.
268  */
269
270 /**
271  * @typedef DBusHashTable
272  *
273  * Public opaque hash table object.
274  */
275
276 /**
277  * @typedef DBusHashType
278  *
279  * Indicates the type of a key in the hash table.
280  */
281
282 /**
283  * Constructs a new hash table. Should be freed with
284  * _dbus_hash_table_unref(). If memory cannot be
285  * allocated for the hash table, returns #NULL.
286  *
287  * @param type the type of hash key to use.
288  * @param key_free_function function to free hash keys.
289  * @param value_free_function function to free hash values.
290  * @returns a new DBusHashTable or #NULL if no memory.
291  */
292 DBusHashTable*
293 _dbus_hash_table_new (DBusHashType     type,
294                       DBusFreeFunction key_free_function,
295                       DBusFreeFunction value_free_function)
296 {
297   DBusHashTable *table;
298   DBusMemPool *entry_pool;
299   
300   table = dbus_new0 (DBusHashTable, 1);
301   if (table == NULL)
302     return NULL;
303
304   entry_pool = _dbus_mem_pool_new (sizeof (DBusHashEntry), TRUE);
305   if (entry_pool == NULL)
306     {
307       dbus_free (table);
308       return NULL;
309     }
310   
311   table->refcount = 1;
312   table->entry_pool = entry_pool;
313   
314   _dbus_assert (DBUS_SMALL_HASH_TABLE == _DBUS_N_ELEMENTS (table->static_buckets));
315   
316   table->buckets = table->static_buckets;  
317   table->n_buckets = DBUS_SMALL_HASH_TABLE;
318   table->n_entries = 0;
319   table->hi_rebuild_size = DBUS_SMALL_HASH_TABLE * REBUILD_MULTIPLIER;
320   table->lo_rebuild_size = 0;
321   table->down_shift = 28;
322   table->mask = 3;
323   table->key_type = type;
324
325   _dbus_assert (table->mask < table->n_buckets);
326   
327   switch (table->key_type)
328     {
329     case DBUS_HASH_INT:
330     case DBUS_HASH_POINTER:
331     case DBUS_HASH_UINTPTR:
332       table->find_function = find_direct_function;
333       break;
334     case DBUS_HASH_STRING:
335       table->find_function = find_string_function;
336       break;
337     case DBUS_HASH_TWO_STRINGS:
338 #ifdef DBUS_BUILD_TESTS
339       table->find_function = find_two_strings_function;
340 #endif
341       break;
342     default:
343       _dbus_assert_not_reached ("Unknown hash table type");
344       break;
345     }
346
347   table->free_key_function = key_free_function;
348   table->free_value_function = value_free_function;
349
350   return table;
351 }
352
353
354 /**
355  * Increments the reference count for a hash table.
356  *
357  * @param table the hash table to add a reference to.
358  * @returns the hash table.
359  */
360 DBusHashTable *
361 _dbus_hash_table_ref (DBusHashTable *table)
362 {
363   table->refcount += 1;
364   
365   return table;
366 }
367
368 /**
369  * Decrements the reference count for a hash table,
370  * freeing the hash table if the count reaches zero.
371  *
372  * @param table the hash table to remove a reference from.
373  */
374 void
375 _dbus_hash_table_unref (DBusHashTable *table)
376 {
377   table->refcount -= 1;
378
379   if (table->refcount == 0)
380     {
381 #if 0
382       DBusHashEntry *entry;
383       DBusHashEntry *next;
384       int i;
385
386       /* Free the entries in the table. */
387       for (i = 0; i < table->n_buckets; i++)
388         {
389           entry = table->buckets[i];
390           while (entry != NULL)
391             {
392               next = entry->next;
393
394               free_entry (table, entry);
395               
396               entry = next;
397             }
398         }
399 #else
400       DBusHashEntry *entry;
401       int i;
402
403       /* Free the entries in the table. */
404       for (i = 0; i < table->n_buckets; i++)
405         {
406           entry = table->buckets[i];
407           while (entry != NULL)
408             {
409               free_entry_data (table, entry);
410               
411               entry = entry->next;
412             }
413         }
414       /* We can do this very quickly with memory pools ;-) */
415       _dbus_mem_pool_free (table->entry_pool);
416 #endif
417       
418       /* Free the bucket array, if it was dynamically allocated. */
419       if (table->buckets != table->static_buckets)
420         dbus_free (table->buckets);
421
422       dbus_free (table);
423     }
424 }
425
426 /**
427  * Removed all entries from a hash table.
428  *
429  * @param table the hash table to remove all entries from.
430  */
431 void
432 _dbus_hash_table_remove_all (DBusHashTable *table)
433 {
434   DBusHashIter iter;
435   _dbus_hash_iter_init (table, &iter);
436   while (_dbus_hash_iter_next (&iter))
437     {
438       _dbus_hash_iter_remove_entry(&iter);
439     }
440 }
441
442 static DBusHashEntry*
443 alloc_entry (DBusHashTable *table)
444 {
445   DBusHashEntry *entry;
446
447   entry = _dbus_mem_pool_alloc (table->entry_pool);
448   
449   return entry;
450 }
451
452 static void
453 free_entry_data (DBusHashTable  *table,
454                  DBusHashEntry  *entry)
455 {
456   if (table->free_key_function)
457     (* table->free_key_function) (entry->key);
458   if (table->free_value_function)
459     (* table->free_value_function) (entry->value);
460 }
461
462 static void
463 free_entry (DBusHashTable  *table,
464             DBusHashEntry  *entry)
465 {
466   free_entry_data (table, entry);
467   _dbus_mem_pool_dealloc (table->entry_pool, entry);
468 }
469
470 static void
471 remove_entry (DBusHashTable  *table,
472               DBusHashEntry **bucket,
473               DBusHashEntry  *entry)
474 {
475   _dbus_assert (table != NULL);
476   _dbus_assert (bucket != NULL);
477   _dbus_assert (*bucket != NULL);  
478   _dbus_assert (entry != NULL);
479   
480   if (*bucket == entry)
481     *bucket = entry->next;
482   else
483     {
484       DBusHashEntry *prev;
485       prev = *bucket;
486
487       while (prev->next != entry)
488         prev = prev->next;      
489       
490       _dbus_assert (prev != NULL);
491
492       prev->next = entry->next;
493     }
494   
495   table->n_entries -= 1;
496   free_entry (table, entry);
497 }
498
499 /**
500  * Initializes a hash table iterator. To iterate over all entries in a
501  * hash table, use the following code (the printf assumes a hash
502  * from strings to strings obviously):
503  *
504  * @code
505  * DBusHashIter iter;
506  *
507  * _dbus_hash_iter_init (table, &iter);
508  * while (_dbus_hash_iter_next (&iter))
509  *   {
510  *      printf ("The first key is %s and value is %s\n",
511  *              _dbus_hash_iter_get_string_key (&iter),
512  *              _dbus_hash_iter_get_value (&iter));
513  *   }
514  * 
515  * 
516  * @endcode
517  *
518  * The iterator is initialized pointing "one before" the first hash
519  * entry. The first call to _dbus_hash_iter_next() moves it onto
520  * the first valid entry or returns #FALSE if the hash table is
521  * empty. Subsequent calls move to the next valid entry or return
522  * #FALSE if there are no more entries.
523  *
524  * Note that it is guaranteed to be safe to remove a hash entry during
525  * iteration, but it is not safe to add a hash entry.
526  * 
527  * @param table the hash table to iterate over.
528  * @param iter the iterator to initialize.
529  */
530 void
531 _dbus_hash_iter_init (DBusHashTable *table,
532                       DBusHashIter  *iter)
533 {
534   DBusRealHashIter *real;
535   
536   _dbus_assert (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
537   
538   real = (DBusRealHashIter*) iter;
539
540   real->table = table;
541   real->bucket = NULL;
542   real->entry = NULL;
543   real->next_entry = NULL;
544   real->next_bucket = 0;
545   real->n_entries_on_init = table->n_entries;
546 }
547
548 /**
549  * Move the hash iterator forward one step, to the next hash entry.
550  * The documentation for _dbus_hash_iter_init() explains in more
551  * detail.
552  *
553  * @param iter the iterator to move forward.
554  * @returns #FALSE if there are no more entries to move to.
555  */
556 dbus_bool_t
557 _dbus_hash_iter_next (DBusHashIter  *iter)
558 {
559   DBusRealHashIter *real;
560   
561   _dbus_assert (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
562   
563   real = (DBusRealHashIter*) iter;
564
565   /* if this assertion failed someone probably added hash entries
566    * during iteration, which is bad.
567    */
568   _dbus_assert (real->n_entries_on_init >= real->table->n_entries);
569   
570   /* Remember that real->entry may have been deleted */
571   
572   while (real->next_entry == NULL)
573     {
574       if (real->next_bucket >= real->table->n_buckets)
575         {
576           /* invalidate iter and return false */
577           real->entry = NULL;
578           real->table = NULL;
579           real->bucket = NULL;
580           return FALSE;
581         }
582
583       real->bucket = &(real->table->buckets[real->next_bucket]);
584       real->next_entry = *(real->bucket);
585       real->next_bucket += 1;
586     }
587
588   _dbus_assert (real->next_entry != NULL);
589   _dbus_assert (real->bucket != NULL);
590   
591   real->entry = real->next_entry;
592   real->next_entry = real->entry->next;
593   
594   return TRUE;
595 }
596
597 /**
598  * Removes the current entry from the hash table.
599  * If a key_free_function or value_free_function
600  * was provided to _dbus_hash_table_new(),
601  * frees the key and/or value for this entry.
602  *
603  * @param iter the hash table iterator.
604  */
605 void
606 _dbus_hash_iter_remove_entry (DBusHashIter *iter)
607 {
608   DBusRealHashIter *real;
609
610   real = (DBusRealHashIter*) iter;
611
612   _dbus_assert (real->table != NULL);
613   _dbus_assert (real->entry != NULL);
614   _dbus_assert (real->bucket != NULL);
615   
616   remove_entry (real->table, real->bucket, real->entry);
617
618   real->entry = NULL; /* make it crash if you try to use this entry */
619 }
620
621 /**
622  * Gets the value of the current entry.
623  *
624  * @param iter the hash table iterator.
625  */
626 void*
627 _dbus_hash_iter_get_value (DBusHashIter *iter)
628 {
629   DBusRealHashIter *real;
630
631   real = (DBusRealHashIter*) iter;
632
633   _dbus_assert (real->table != NULL);
634   _dbus_assert (real->entry != NULL);
635
636   return real->entry->value;
637 }
638
639 /**
640  * Sets the value of the current entry.
641  * If the hash table has a value_free_function
642  * it will be used to free the previous value.
643  * The hash table will own the passed-in value
644  * (it will not be copied).
645  *
646  * @param iter the hash table iterator.
647  * @param value the new value.
648  */
649 void
650 _dbus_hash_iter_set_value (DBusHashIter *iter,
651                            void         *value)
652 {
653   DBusRealHashIter *real;
654
655   real = (DBusRealHashIter*) iter;
656
657   _dbus_assert (real->table != NULL);
658   _dbus_assert (real->entry != NULL);
659
660   if (real->table->free_value_function && value != real->entry->value)    
661     (* real->table->free_value_function) (real->entry->value);
662   
663   real->entry->value = value;
664 }
665
666 /**
667  * Gets the key for the current entry.
668  * Only works for hash tables of type #DBUS_HASH_INT.
669  *
670  * @param iter the hash table iterator.
671  */
672 int
673 _dbus_hash_iter_get_int_key (DBusHashIter *iter)
674 {
675   DBusRealHashIter *real;
676
677   real = (DBusRealHashIter*) iter;
678
679   _dbus_assert (real->table != NULL);
680   _dbus_assert (real->entry != NULL);
681
682   return _DBUS_POINTER_TO_INT (real->entry->key);
683 }
684
685 /**
686  * Gets the key for the current entry.
687  * Only works for hash tables of type #DBUS_HASH_UINTPTR.
688  *
689  * @param iter the hash table iterator.
690  */
691 uintptr_t
692 _dbus_hash_iter_get_uintptr_key (DBusHashIter *iter)
693 {
694   DBusRealHashIter *real;
695
696   real = (DBusRealHashIter*) iter;
697
698   _dbus_assert (real->table != NULL);
699   _dbus_assert (real->entry != NULL);
700
701   return (uintptr_t) real->entry->key;
702 }
703
704 /**
705  * Gets the key for the current entry.
706  * Only works for hash tables of type #DBUS_HASH_STRING
707  * @param iter the hash table iterator.
708  */
709 const char*
710 _dbus_hash_iter_get_string_key (DBusHashIter *iter)
711 {
712   DBusRealHashIter *real;
713
714   real = (DBusRealHashIter*) iter;
715
716   _dbus_assert (real->table != NULL);
717   _dbus_assert (real->entry != NULL);
718
719   return real->entry->key;
720 }
721
722 #ifdef DBUS_BUILD_TESTS
723 /**
724  * Gets the key for the current entry.
725  * Only works for hash tables of type #DBUS_HASH_TWO_STRINGS
726  * @param iter the hash table iterator.
727  */
728 const char*
729 _dbus_hash_iter_get_two_strings_key (DBusHashIter *iter)
730 {
731   DBusRealHashIter *real;
732
733   real = (DBusRealHashIter*) iter;
734
735   _dbus_assert (real->table != NULL);
736   _dbus_assert (real->entry != NULL);
737
738   return real->entry->key;
739 }
740 #endif /* DBUS_BUILD_TESTS */
741
742 /**
743  * A low-level but efficient interface for manipulating the hash
744  * table.  It's efficient because you can get, set, and optionally
745  * create the hash entry while only running the hash function one
746  * time.
747  *
748  * Note that while calling _dbus_hash_iter_next() on the iterator
749  * filled in by this function may work, it's completely
750  * undefined which entries are after this iter and which
751  * are before it. So it would be silly to iterate using this
752  * iterator.
753  *
754  * If the hash entry is created, its value will be initialized
755  * to all bits zero.
756  *
757  * #FALSE may be returned due to memory allocation failure, or
758  * because create_if_not_found was #FALSE and the entry
759  * did not exist.
760  *
761  * If create_if_not_found is #TRUE and the entry is created, the hash
762  * table takes ownership of the key that's passed in.
763  *
764  * For a hash table of type #DBUS_HASH_INT, cast the int
765  * key to the key parameter using #_DBUS_INT_TO_POINTER().
766  * 
767  * @param table the hash table.
768  * @param key the hash key.
769  * @param create_if_not_found if #TRUE, create the entry if it didn't exist.
770  * @param iter the iterator to initialize.
771  * @returns #TRUE if the hash entry now exists (and the iterator is thus valid).
772  */
773 dbus_bool_t
774 _dbus_hash_iter_lookup (DBusHashTable *table,
775                         void          *key,
776                         dbus_bool_t    create_if_not_found,
777                         DBusHashIter  *iter)
778 {
779   DBusRealHashIter *real;
780   DBusHashEntry *entry;
781   DBusHashEntry **bucket;
782   
783   _dbus_assert (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
784   
785   real = (DBusRealHashIter*) iter;
786
787   entry = (* table->find_function) (table, key, create_if_not_found, &bucket, NULL);
788
789   if (entry == NULL)
790     return FALSE;
791   
792   real->table = table;
793   real->bucket = bucket;
794   real->entry = entry;
795   real->next_entry = entry->next;
796   real->next_bucket = (bucket - table->buckets) + 1;
797   real->n_entries_on_init = table->n_entries; 
798
799   _dbus_assert (&(table->buckets[real->next_bucket-1]) == real->bucket);
800   
801   return TRUE;
802 }
803
804 static void
805 add_allocated_entry (DBusHashTable   *table,
806                      DBusHashEntry   *entry,
807                      unsigned int     idx,
808                      void            *key,
809                      DBusHashEntry ***bucket)
810 {
811   DBusHashEntry **b;  
812   
813   entry->key = key;
814   
815   b = &(table->buckets[idx]);
816   entry->next = *b;
817   *b = entry;
818
819   if (bucket)
820     *bucket = b;
821   
822   table->n_entries += 1;
823
824   /* note we ONLY rebuild when ADDING - because you can iterate over a
825    * table and remove entries safely.
826    */
827   if (table->n_entries >= table->hi_rebuild_size ||
828       table->n_entries < table->lo_rebuild_size)
829     rebuild_table (table);
830 }
831
832 static DBusHashEntry*
833 add_entry (DBusHashTable        *table, 
834            unsigned int          idx,
835            void                 *key,
836            DBusHashEntry      ***bucket,
837            DBusPreallocatedHash *preallocated)
838 {
839   DBusHashEntry  *entry;
840
841   if (preallocated == NULL)
842     {
843       entry = alloc_entry (table);
844       if (entry == NULL)
845         {
846           if (bucket)
847             *bucket = NULL;
848           return NULL;
849         }
850     }
851   else
852     {
853       entry = (DBusHashEntry*) preallocated;
854     }
855
856   add_allocated_entry (table, entry, idx, key, bucket);
857
858   return entry;
859 }
860
861 /* This is g_str_hash from GLib which was
862  * extensively discussed/tested/profiled
863  */
864 static unsigned int
865 string_hash (const char *str)
866 {
867   const char *p = str;
868   unsigned int h = *p;
869
870   if (h)
871     for (p += 1; *p != '\0'; p++)
872       h = (h << 5) - h + *p;
873
874   return h;
875 }
876
877 #ifdef DBUS_BUILD_TESTS
878 /* This hashes a memory block with two nul-terminated strings
879  * in it, used in dbus-object-registry.c at the moment.
880  */
881 static unsigned int
882 two_strings_hash (const char *str)
883 {
884   const char *p = str;
885   unsigned int h = *p;
886
887   if (h)
888     for (p += 1; *p != '\0'; p++)
889       h = (h << 5) - h + *p;
890
891   for (p += 1; *p != '\0'; p++)
892     h = (h << 5) - h + *p;
893   
894   return h;
895 }
896 #endif /* DBUS_BUILD_TESTS */
897
898 /** Key comparison function */
899 typedef int (* KeyCompareFunc) (const void *key_a, const void *key_b);
900
901 static DBusHashEntry*
902 find_generic_function (DBusHashTable        *table,
903                        void                 *key,
904                        unsigned int          idx,
905                        KeyCompareFunc        compare_func,
906                        dbus_bool_t           create_if_not_found,
907                        DBusHashEntry      ***bucket,
908                        DBusPreallocatedHash *preallocated)
909 {
910   DBusHashEntry *entry;
911
912   if (bucket)
913     *bucket = NULL;
914
915   /* Search all of the entries in this bucket. */
916   entry = table->buckets[idx];
917   while (entry != NULL)
918     {
919       if ((compare_func == NULL && key == entry->key) ||
920           (compare_func != NULL && (* compare_func) (key, entry->key) == 0))
921         {
922           if (bucket)
923             *bucket = &(table->buckets[idx]);
924
925           if (preallocated)
926             _dbus_hash_table_free_preallocated_entry (table, preallocated);
927           
928           return entry;
929         }
930       
931       entry = entry->next;
932     }
933
934   if (create_if_not_found)
935     entry = add_entry (table, idx, key, bucket, preallocated);
936   else if (preallocated)
937     _dbus_hash_table_free_preallocated_entry (table, preallocated);
938   
939   return entry;
940 }
941
942 static DBusHashEntry*
943 find_string_function (DBusHashTable        *table,
944                       void                 *key,
945                       dbus_bool_t           create_if_not_found,
946                       DBusHashEntry      ***bucket,
947                       DBusPreallocatedHash *preallocated)
948 {
949   unsigned int idx;
950   
951   idx = string_hash (key) & table->mask;
952
953   return find_generic_function (table, key, idx,
954                                 (KeyCompareFunc) strcmp, create_if_not_found, bucket,
955                                 preallocated);
956 }
957
958 #ifdef DBUS_BUILD_TESTS
959 static int
960 two_strings_cmp (const char *a,
961                  const char *b)
962 {
963   size_t len_a;
964   size_t len_b;
965   int res;
966   
967   res = strcmp (a, b);
968   if (res != 0)
969     return res;
970
971   len_a = strlen (a);
972   len_b = strlen (b);
973
974   return strcmp (a + len_a + 1, b + len_b + 1);
975 }
976 #endif
977
978 #ifdef DBUS_BUILD_TESTS
979 static DBusHashEntry*
980 find_two_strings_function (DBusHashTable        *table,
981                            void                 *key,
982                            dbus_bool_t           create_if_not_found,
983                            DBusHashEntry      ***bucket,
984                            DBusPreallocatedHash *preallocated)
985 {
986   unsigned int idx;
987   
988   idx = two_strings_hash (key) & table->mask;
989
990   return find_generic_function (table, key, idx,
991                                 (KeyCompareFunc) two_strings_cmp, create_if_not_found, bucket,
992                                 preallocated);
993 }
994 #endif /* DBUS_BUILD_TESTS */
995
996 static DBusHashEntry*
997 find_direct_function (DBusHashTable        *table,
998                       void                 *key,
999                       dbus_bool_t           create_if_not_found,
1000                       DBusHashEntry      ***bucket,
1001                       DBusPreallocatedHash *preallocated)
1002 {
1003   unsigned int idx;
1004   
1005   idx = RANDOM_INDEX (table, key) & table->mask;
1006
1007
1008   return find_generic_function (table, key, idx,
1009                                 NULL, create_if_not_found, bucket,
1010                                 preallocated);
1011 }
1012
1013 static void
1014 rebuild_table (DBusHashTable *table)
1015 {
1016   int old_size;
1017   int new_buckets;
1018   DBusHashEntry **old_buckets;
1019   DBusHashEntry **old_chain;
1020   DBusHashEntry *entry;
1021   dbus_bool_t growing;
1022   
1023   /*
1024    * Allocate and initialize the new bucket array, and set up
1025    * hashing constants for new array size.
1026    */
1027
1028   growing = table->n_entries >= table->hi_rebuild_size;
1029   
1030   old_size = table->n_buckets;
1031   old_buckets = table->buckets;
1032
1033   if (growing)
1034     {
1035       /* overflow paranoia */
1036       if (table->n_buckets < _DBUS_INT_MAX / 4 &&
1037           table->down_shift >= 0)
1038         new_buckets = table->n_buckets * 4;
1039       else
1040         return; /* can't grow anymore */
1041     }
1042   else
1043     {
1044       new_buckets = table->n_buckets / 4;
1045       if (new_buckets < DBUS_SMALL_HASH_TABLE)
1046         return; /* don't bother shrinking this far */
1047     }
1048
1049   table->buckets = dbus_new0 (DBusHashEntry*, new_buckets);
1050   if (table->buckets == NULL)
1051     {
1052       /* out of memory, yay - just don't reallocate, the table will
1053        * still work, albeit more slowly.
1054        */
1055       table->buckets = old_buckets;
1056       return;
1057     }
1058
1059   table->n_buckets = new_buckets;
1060   
1061   if (growing)
1062     {
1063       table->lo_rebuild_size = table->hi_rebuild_size;
1064       table->hi_rebuild_size *= 4;
1065       
1066       table->down_shift -= 2;               /* keep 2 more high bits */
1067       table->mask = (table->mask << 2) + 3; /* keep 2 more high bits */
1068     }
1069   else
1070     {
1071       table->hi_rebuild_size = table->lo_rebuild_size;
1072       table->lo_rebuild_size /= 4;
1073
1074       table->down_shift += 2;         /* keep 2 fewer high bits */
1075       table->mask = table->mask >> 2; /* keep 2 fewer high bits */
1076     }
1077
1078 #if 0
1079   printf ("%s table to lo = %d hi = %d downshift = %d mask = 0x%x\n",
1080           growing ? "GROW" : "SHRINK",
1081           table->lo_rebuild_size,
1082           table->hi_rebuild_size,
1083           table->down_shift,
1084           table->mask);
1085 #endif
1086   
1087   _dbus_assert (table->lo_rebuild_size >= 0);
1088   _dbus_assert (table->hi_rebuild_size > table->lo_rebuild_size);
1089   _dbus_assert (table->mask != 0);
1090   /* the mask is essentially the max index */
1091   _dbus_assert (table->mask < table->n_buckets);
1092   
1093   /*
1094    * Rehash all of the existing entries into the new bucket array.
1095    */
1096
1097   for (old_chain = old_buckets; old_size > 0; old_size--, old_chain++)
1098     {
1099       for (entry = *old_chain; entry != NULL; entry = *old_chain)
1100         {
1101           unsigned int idx;
1102           DBusHashEntry **bucket;
1103           
1104           *old_chain = entry->next;
1105           switch (table->key_type)
1106             {
1107             case DBUS_HASH_STRING:
1108               idx = string_hash (entry->key) & table->mask;
1109               break;
1110             case DBUS_HASH_TWO_STRINGS:
1111 #ifdef DBUS_BUILD_TESTS
1112               idx = two_strings_hash (entry->key) & table->mask;
1113 #else
1114               idx = 0;
1115               _dbus_assert_not_reached ("two-strings is not enabled");
1116 #endif
1117               break;
1118             case DBUS_HASH_INT:
1119             case DBUS_HASH_UINTPTR:
1120             case DBUS_HASH_POINTER:
1121               idx = RANDOM_INDEX (table, entry->key);
1122               break;
1123             default:
1124               idx = 0;
1125               _dbus_assert_not_reached ("Unknown hash table type");
1126               break;
1127             }
1128           
1129           bucket = &(table->buckets[idx]);
1130           entry->next = *bucket;
1131           *bucket = entry;
1132         }
1133     }
1134   
1135   /* Free the old bucket array, if it was dynamically allocated. */
1136
1137   if (old_buckets != table->static_buckets)
1138     dbus_free (old_buckets);
1139 }
1140
1141 /**
1142  * Looks up the value for a given string in a hash table
1143  * of type #DBUS_HASH_STRING. Returns %NULL if the value
1144  * is not present. (A not-present entry is indistinguishable
1145  * from an entry with a value of %NULL.)
1146  * @param table the hash table.
1147  * @param key the string to look up.
1148  * @returns the value of the hash entry.
1149  */
1150 void*
1151 _dbus_hash_table_lookup_string (DBusHashTable *table,
1152                                 const char    *key)
1153 {
1154   DBusHashEntry *entry;
1155
1156   _dbus_assert (table->key_type == DBUS_HASH_STRING);
1157   
1158   entry = (* table->find_function) (table, (char*) key, FALSE, NULL, NULL);
1159
1160   if (entry)
1161     return entry->value;
1162   else
1163     return NULL;
1164 }
1165
1166 #ifdef DBUS_BUILD_TESTS
1167 /**
1168  * Looks up the value for a given string in a hash table
1169  * of type #DBUS_HASH_TWO_STRINGS. Returns %NULL if the value
1170  * is not present. (A not-present entry is indistinguishable
1171  * from an entry with a value of %NULL.)
1172  * @param table the hash table.
1173  * @param key the string to look up.
1174  * @returns the value of the hash entry.
1175  */
1176 void*
1177 _dbus_hash_table_lookup_two_strings (DBusHashTable *table,
1178                                      const char    *key)
1179 {
1180   DBusHashEntry *entry;
1181
1182   _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
1183   
1184   entry = (* table->find_function) (table, (char*) key, FALSE, NULL, NULL);
1185
1186   if (entry)
1187     return entry->value;
1188   else
1189     return NULL;
1190 }
1191 #endif /* DBUS_BUILD_TESTS */
1192
1193 /**
1194  * Looks up the value for a given integer in a hash table
1195  * of type #DBUS_HASH_INT. Returns %NULL if the value
1196  * is not present. (A not-present entry is indistinguishable
1197  * from an entry with a value of %NULL.)
1198  * @param table the hash table.
1199  * @param key the integer to look up.
1200  * @returns the value of the hash entry.
1201  */
1202 void*
1203 _dbus_hash_table_lookup_int (DBusHashTable *table,
1204                              int            key)
1205 {
1206   DBusHashEntry *entry;
1207
1208   _dbus_assert (table->key_type == DBUS_HASH_INT);
1209   
1210   entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, NULL, NULL);
1211
1212   if (entry)
1213     return entry->value;
1214   else
1215     return NULL;
1216 }
1217
1218 #ifdef DBUS_BUILD_TESTS
1219 /* disabled since it's only used for testing */
1220 /**
1221  * Looks up the value for a given integer in a hash table
1222  * of type #DBUS_HASH_POINTER. Returns %NULL if the value
1223  * is not present. (A not-present entry is indistinguishable
1224  * from an entry with a value of %NULL.)
1225  * @param table the hash table.
1226  * @param key the integer to look up.
1227  * @returns the value of the hash entry.
1228  */
1229 void*
1230 _dbus_hash_table_lookup_pointer (DBusHashTable *table,
1231                                  void          *key)
1232 {
1233   DBusHashEntry *entry;
1234
1235   _dbus_assert (table->key_type == DBUS_HASH_POINTER);
1236   
1237   entry = (* table->find_function) (table, key, FALSE, NULL, NULL);
1238
1239   if (entry)
1240     return entry->value;
1241   else
1242     return NULL;
1243 }
1244 #endif /* DBUS_BUILD_TESTS */
1245
1246 /**
1247  * Looks up the value for a given integer in a hash table
1248  * of type #DBUS_HASH_UINTPTR. Returns %NULL if the value
1249  * is not present. (A not-present entry is indistinguishable
1250  * from an entry with a value of %NULL.)
1251  * @param table the hash table.
1252  * @param key the integer to look up.
1253  * @returns the value of the hash entry.
1254  */
1255 void*
1256 _dbus_hash_table_lookup_uintptr (DBusHashTable *table,
1257                                  uintptr_t      key)
1258 {
1259   DBusHashEntry *entry;
1260
1261   _dbus_assert (table->key_type == DBUS_HASH_UINTPTR);
1262   
1263   entry = (* table->find_function) (table, (void*) key, FALSE, NULL, NULL);
1264
1265   if (entry)
1266     return entry->value;
1267   else
1268     return NULL;
1269 }
1270
1271 /**
1272  * Removes the hash entry for the given key. If no hash entry
1273  * for the key exists, does nothing.
1274  *
1275  * @param table the hash table.
1276  * @param key the hash key.
1277  * @returns #TRUE if the entry existed
1278  */
1279 dbus_bool_t
1280 _dbus_hash_table_remove_string (DBusHashTable *table,
1281                                 const char    *key)
1282 {
1283   DBusHashEntry *entry;
1284   DBusHashEntry **bucket;
1285   
1286   _dbus_assert (table->key_type == DBUS_HASH_STRING);
1287   
1288   entry = (* table->find_function) (table, (char*) key, FALSE, &bucket, NULL);
1289
1290   if (entry)
1291     {
1292       remove_entry (table, bucket, entry);
1293       return TRUE;
1294     }
1295   else
1296     return FALSE;
1297 }
1298
1299 #ifdef DBUS_BUILD_TESTS
1300 /**
1301  * Removes the hash entry for the given key. If no hash entry
1302  * for the key exists, does nothing.
1303  *
1304  * @param table the hash table.
1305  * @param key the hash key.
1306  * @returns #TRUE if the entry existed
1307  */
1308 dbus_bool_t
1309 _dbus_hash_table_remove_two_strings (DBusHashTable *table,
1310                                      const char    *key)
1311 {
1312   DBusHashEntry *entry;
1313   DBusHashEntry **bucket;
1314   
1315   _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
1316   
1317   entry = (* table->find_function) (table, (char*) key, FALSE, &bucket, NULL);
1318
1319   if (entry)
1320     {
1321       remove_entry (table, bucket, entry);
1322       return TRUE;
1323     }
1324   else
1325     return FALSE;
1326 }
1327 #endif /* DBUS_BUILD_TESTS */
1328
1329 /**
1330  * Removes the hash entry for the given key. If no hash entry
1331  * for the key exists, does nothing.
1332  *
1333  * @param table the hash table.
1334  * @param key the hash key.
1335  * @returns #TRUE if the entry existed
1336  */
1337 dbus_bool_t
1338 _dbus_hash_table_remove_int (DBusHashTable *table,
1339                              int            key)
1340 {
1341   DBusHashEntry *entry;
1342   DBusHashEntry **bucket;
1343   
1344   _dbus_assert (table->key_type == DBUS_HASH_INT);
1345   
1346   entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, &bucket, NULL);
1347   
1348   if (entry)
1349     {
1350       remove_entry (table, bucket, entry);
1351       return TRUE;
1352     }
1353   else
1354     return FALSE;
1355 }
1356
1357 #ifdef DBUS_BUILD_TESTS
1358 /* disabled since it's only used for testing */
1359 /**
1360  * Removes the hash entry for the given key. If no hash entry
1361  * for the key exists, does nothing.
1362  *
1363  * @param table the hash table.
1364  * @param key the hash key.
1365  * @returns #TRUE if the entry existed
1366  */
1367 dbus_bool_t
1368 _dbus_hash_table_remove_pointer (DBusHashTable *table,
1369                                  void          *key)
1370 {
1371   DBusHashEntry *entry;
1372   DBusHashEntry **bucket;
1373   
1374   _dbus_assert (table->key_type == DBUS_HASH_POINTER);
1375   
1376   entry = (* table->find_function) (table, key, FALSE, &bucket, NULL);
1377   
1378   if (entry)
1379     {
1380       remove_entry (table, bucket, entry);
1381       return TRUE;
1382     }
1383   else
1384     return FALSE;
1385 }
1386 #endif /* DBUS_BUILD_TESTS */
1387
1388 /**
1389  * Removes the hash entry for the given key. If no hash entry
1390  * for the key exists, does nothing.
1391  *
1392  * @param table the hash table.
1393  * @param key the hash key.
1394  * @returns #TRUE if the entry existed
1395  */
1396 dbus_bool_t
1397 _dbus_hash_table_remove_uintptr (DBusHashTable *table,
1398                                  uintptr_t      key)
1399 {
1400   DBusHashEntry *entry;
1401   DBusHashEntry **bucket;
1402   
1403   _dbus_assert (table->key_type == DBUS_HASH_UINTPTR);
1404   
1405   entry = (* table->find_function) (table, (void*) key, FALSE, &bucket, NULL);
1406   
1407   if (entry)
1408     {
1409       remove_entry (table, bucket, entry);
1410       return TRUE;
1411     }
1412   else
1413     return FALSE;
1414 }
1415
1416 /**
1417  * Creates a hash entry with the given key and value.
1418  * The key and value are not copied; they are stored
1419  * in the hash table by reference. If an entry with the
1420  * given key already exists, the previous key and value
1421  * are overwritten (and freed if the hash table has
1422  * a key_free_function and/or value_free_function).
1423  *
1424  * Returns #FALSE if memory for the new hash entry
1425  * can't be allocated.
1426  * 
1427  * @param table the hash table.
1428  * @param key the hash entry key.
1429  * @param value the hash entry value.
1430  */
1431 dbus_bool_t
1432 _dbus_hash_table_insert_string (DBusHashTable *table,
1433                                 char          *key,
1434                                 void          *value)
1435 {
1436   DBusPreallocatedHash *preallocated;
1437
1438   _dbus_assert (table->key_type == DBUS_HASH_STRING);
1439
1440   preallocated = _dbus_hash_table_preallocate_entry (table);
1441   if (preallocated == NULL)
1442     return FALSE;
1443
1444   _dbus_hash_table_insert_string_preallocated (table, preallocated,
1445                                                key, value);
1446   
1447   return TRUE;
1448 }
1449
1450 #ifdef DBUS_BUILD_TESTS
1451 /**
1452  * Creates a hash entry with the given key and value.
1453  * The key and value are not copied; they are stored
1454  * in the hash table by reference. If an entry with the
1455  * given key already exists, the previous key and value
1456  * are overwritten (and freed if the hash table has
1457  * a key_free_function and/or value_free_function).
1458  *
1459  * Returns #FALSE if memory for the new hash entry
1460  * can't be allocated.
1461  * 
1462  * @param table the hash table.
1463  * @param key the hash entry key.
1464  * @param value the hash entry value.
1465  */
1466 dbus_bool_t
1467 _dbus_hash_table_insert_two_strings (DBusHashTable *table,
1468                                      char          *key,
1469                                      void          *value)
1470 {
1471   DBusHashEntry *entry;
1472   
1473   _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
1474   
1475   entry = (* table->find_function) (table, key, TRUE, NULL, NULL);
1476
1477   if (entry == NULL)
1478     return FALSE; /* no memory */
1479
1480   if (table->free_key_function && entry->key != key)
1481     (* table->free_key_function) (entry->key);
1482   
1483   if (table->free_value_function && entry->value != value)
1484     (* table->free_value_function) (entry->value);
1485   
1486   entry->key = key;
1487   entry->value = value;
1488
1489   return TRUE;
1490 }
1491 #endif /* DBUS_BUILD_TESTS */
1492
1493 /**
1494  * Creates a hash entry with the given key and value.
1495  * The key and value are not copied; they are stored
1496  * in the hash table by reference. If an entry with the
1497  * given key already exists, the previous key and value
1498  * are overwritten (and freed if the hash table has
1499  * a key_free_function and/or value_free_function).
1500  *
1501  * Returns #FALSE if memory for the new hash entry
1502  * can't be allocated.
1503  * 
1504  * @param table the hash table.
1505  * @param key the hash entry key.
1506  * @param value the hash entry value.
1507  */
1508 dbus_bool_t
1509 _dbus_hash_table_insert_int (DBusHashTable *table,
1510                              int            key,
1511                              void          *value)
1512 {
1513   DBusHashEntry *entry;
1514
1515   _dbus_assert (table->key_type == DBUS_HASH_INT);
1516   
1517   entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), TRUE, NULL, NULL);
1518
1519   if (entry == NULL)
1520     return FALSE; /* no memory */
1521
1522   if (table->free_key_function && entry->key != _DBUS_INT_TO_POINTER (key))
1523     (* table->free_key_function) (entry->key);
1524   
1525   if (table->free_value_function && entry->value != value)
1526     (* table->free_value_function) (entry->value);
1527   
1528   entry->key = _DBUS_INT_TO_POINTER (key);
1529   entry->value = value;
1530
1531   return TRUE;
1532 }
1533
1534 #ifdef DBUS_BUILD_TESTS
1535 /* disabled since it's only used for testing */
1536 /**
1537  * Creates a hash entry with the given key and value.
1538  * The key and value are not copied; they are stored
1539  * in the hash table by reference. If an entry with the
1540  * given key already exists, the previous key and value
1541  * are overwritten (and freed if the hash table has
1542  * a key_free_function and/or value_free_function).
1543  *
1544  * Returns #FALSE if memory for the new hash entry
1545  * can't be allocated.
1546  * 
1547  * @param table the hash table.
1548  * @param key the hash entry key.
1549  * @param value the hash entry value.
1550  */
1551 dbus_bool_t
1552 _dbus_hash_table_insert_pointer (DBusHashTable *table,
1553                                  void          *key,
1554                                  void          *value)
1555 {
1556   DBusHashEntry *entry;
1557
1558   _dbus_assert (table->key_type == DBUS_HASH_POINTER);
1559   
1560   entry = (* table->find_function) (table, key, TRUE, NULL, NULL);
1561
1562   if (entry == NULL)
1563     return FALSE; /* no memory */
1564
1565   if (table->free_key_function && entry->key != key)
1566     (* table->free_key_function) (entry->key);
1567   
1568   if (table->free_value_function && entry->value != value)
1569     (* table->free_value_function) (entry->value);
1570   
1571   entry->key = key;
1572   entry->value = value;
1573
1574   return TRUE;
1575 }
1576 #endif /* DBUS_BUILD_TESTS */
1577
1578 /**
1579  * Creates a hash entry with the given key and value.
1580  * The key and value are not copied; they are stored
1581  * in the hash table by reference. If an entry with the
1582  * given key already exists, the previous key and value
1583  * are overwritten (and freed if the hash table has
1584  * a key_free_function and/or value_free_function).
1585  *
1586  * Returns #FALSE if memory for the new hash entry
1587  * can't be allocated.
1588  * 
1589  * @param table the hash table.
1590  * @param key the hash entry key.
1591  * @param value the hash entry value.
1592  */
1593 dbus_bool_t
1594 _dbus_hash_table_insert_uintptr (DBusHashTable *table,
1595                                  uintptr_t      key,
1596                                  void          *value)
1597 {
1598   DBusHashEntry *entry;
1599
1600   _dbus_assert (table->key_type == DBUS_HASH_UINTPTR);
1601   
1602   entry = (* table->find_function) (table, (void*) key, TRUE, NULL, NULL);
1603
1604   if (entry == NULL)
1605     return FALSE; /* no memory */
1606
1607   if (table->free_key_function && entry->key != (void*) key)
1608     (* table->free_key_function) (entry->key);
1609   
1610   if (table->free_value_function && entry->value != value)
1611     (* table->free_value_function) (entry->value);
1612   
1613   entry->key = (void*) key;
1614   entry->value = value;
1615
1616   return TRUE;
1617 }
1618
1619 /**
1620  * Preallocate an opaque data blob that allows us to insert into the
1621  * hash table at a later time without allocating any memory.
1622  *
1623  * @param table the hash table
1624  * @returns the preallocated data, or #NULL if no memory
1625  */
1626 DBusPreallocatedHash*
1627 _dbus_hash_table_preallocate_entry (DBusHashTable *table)
1628 {
1629   DBusHashEntry *entry;
1630   
1631   entry = alloc_entry (table);
1632
1633   return (DBusPreallocatedHash*) entry;
1634 }
1635
1636 /**
1637  * Frees an opaque DBusPreallocatedHash that was *not* used
1638  * in order to insert into the hash table.
1639  *
1640  * @param table the hash table
1641  * @param preallocated the preallocated data
1642  */
1643 void
1644 _dbus_hash_table_free_preallocated_entry (DBusHashTable        *table,
1645                                           DBusPreallocatedHash *preallocated)
1646 {
1647   DBusHashEntry *entry;
1648
1649   _dbus_assert (preallocated != NULL);
1650   
1651   entry = (DBusHashEntry*) preallocated;
1652   
1653   /* Don't use free_entry(), since this entry has no key/data */
1654   _dbus_mem_pool_dealloc (table->entry_pool, entry);
1655 }
1656
1657 /**
1658  * Inserts a string-keyed entry into the hash table, using a
1659  * preallocated data block from
1660  * _dbus_hash_table_preallocate_entry(). This function cannot fail due
1661  * to lack of memory. The DBusPreallocatedHash object is consumed and
1662  * should not be reused or freed. Otherwise this function works
1663  * just like _dbus_hash_table_insert_string().
1664  *
1665  * @param table the hash table
1666  * @param preallocated the preallocated data
1667  * @param key the hash key
1668  * @param value the value 
1669  */
1670 void
1671 _dbus_hash_table_insert_string_preallocated (DBusHashTable        *table,
1672                                              DBusPreallocatedHash *preallocated,
1673                                              char                 *key,
1674                                              void                 *value)
1675 {
1676   DBusHashEntry *entry;
1677
1678   _dbus_assert (table->key_type == DBUS_HASH_STRING);
1679   _dbus_assert (preallocated != NULL);
1680   
1681   entry = (* table->find_function) (table, key, TRUE, NULL, preallocated);
1682
1683   _dbus_assert (entry != NULL);
1684   
1685   if (table->free_key_function && entry->key != key)
1686     (* table->free_key_function) (entry->key);
1687
1688   if (table->free_value_function && entry->value != value)
1689     (* table->free_value_function) (entry->value);
1690       
1691   entry->key = key;
1692   entry->value = value;
1693 }
1694
1695 /**
1696  * Gets the number of hash entries in a hash table.
1697  *
1698  * @param table the hash table.
1699  * @returns the number of entries in the table.
1700  */
1701 int
1702 _dbus_hash_table_get_n_entries (DBusHashTable *table)
1703 {
1704   return table->n_entries;
1705 }
1706
1707 /** @} */
1708
1709 #ifdef DBUS_BUILD_TESTS
1710 #include "dbus-test.h"
1711 #include <stdio.h>
1712
1713 /* If you're wondering why the hash table test takes
1714  * forever to run, it's because we call this function
1715  * in inner loops thus making things quadratic.
1716  */
1717 static int
1718 count_entries (DBusHashTable *table)
1719 {
1720   DBusHashIter iter;
1721   int count;
1722
1723   count = 0;
1724   _dbus_hash_iter_init (table, &iter);
1725   while (_dbus_hash_iter_next (&iter))
1726     ++count;
1727
1728   _dbus_assert (count == _dbus_hash_table_get_n_entries (table));
1729   
1730   return count;
1731 }
1732
1733 /* Copy the foo\0bar\0 double string thing */
1734 static char*
1735 _dbus_strdup2 (const char *str)
1736 {
1737   size_t len;
1738   char *copy;
1739   
1740   if (str == NULL)
1741     return NULL;
1742   
1743   len = strlen (str);
1744   len += strlen ((str + len + 1));
1745
1746   copy = dbus_malloc (len + 2);
1747   if (copy == NULL)
1748     return NULL;
1749
1750   memcpy (copy, str, len + 2);
1751   
1752   return copy;
1753 }
1754
1755 /**
1756  * @ingroup DBusHashTableInternals
1757  * Unit test for DBusHashTable
1758  * @returns #TRUE on success.
1759  */
1760 dbus_bool_t
1761 _dbus_hash_test (void)
1762 {
1763   int i;
1764   DBusHashTable *table1;
1765   DBusHashTable *table2;
1766   DBusHashTable *table3;
1767   DBusHashTable *table4;
1768   DBusHashIter iter;
1769 #define N_HASH_KEYS 5000
1770   char **keys;
1771   dbus_bool_t ret = FALSE;
1772
1773   keys = dbus_new (char *, N_HASH_KEYS);
1774   if (keys == NULL)
1775     _dbus_assert_not_reached ("no memory");
1776
1777   for (i = 0; i < N_HASH_KEYS; i++)
1778     {
1779       keys[i] = dbus_malloc (128);
1780
1781       if (keys[i] == NULL)
1782         _dbus_assert_not_reached ("no memory");
1783     }
1784
1785   printf ("Computing test hash keys...\n");
1786   i = 0;
1787   while (i < N_HASH_KEYS)
1788     {
1789       int len;
1790
1791       /* all the hash keys are TWO_STRINGS, but
1792        * then we can also use those as regular strings.
1793        */
1794       
1795       len = sprintf (keys[i], "Hash key %d", i);
1796       sprintf (keys[i] + len + 1, "Two string %d", i);
1797       _dbus_assert (*(keys[i] + len) == '\0');
1798       _dbus_assert (*(keys[i] + len + 1) != '\0');
1799       ++i;
1800     }
1801   printf ("... done.\n");
1802   
1803   table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
1804                                  dbus_free, dbus_free);
1805   if (table1 == NULL)
1806     goto out;
1807
1808   table2 = _dbus_hash_table_new (DBUS_HASH_INT,
1809                                  NULL, dbus_free);
1810   if (table2 == NULL)
1811     goto out;
1812
1813   table3 = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
1814                                  NULL, dbus_free);
1815   if (table3 == NULL)
1816     goto out;
1817
1818   table4 = _dbus_hash_table_new (DBUS_HASH_TWO_STRINGS,
1819                                  dbus_free, dbus_free);
1820   if (table4 == NULL)
1821     goto out;
1822
1823   
1824   /* Insert and remove a bunch of stuff, counting the table in between
1825    * to be sure it's not broken and that iteration works
1826    */
1827   i = 0;
1828   while (i < 3000)
1829     {
1830       void *value;
1831       char *key;
1832
1833       key = _dbus_strdup (keys[i]);
1834       if (key == NULL)
1835         goto out;
1836       value = _dbus_strdup ("Value!");
1837       if (value == NULL)
1838         goto out;
1839       
1840       if (!_dbus_hash_table_insert_string (table1,
1841                                            key, value))
1842         goto out;
1843
1844       value = _dbus_strdup (keys[i]);
1845       if (value == NULL)
1846         goto out;
1847       
1848       if (!_dbus_hash_table_insert_int (table2,
1849                                         i, value))
1850         goto out;
1851
1852       value = _dbus_strdup (keys[i]);
1853       if (value == NULL)
1854         goto out;
1855       
1856       if (!_dbus_hash_table_insert_uintptr (table3,
1857                                           i, value))
1858         goto out;
1859
1860       key = _dbus_strdup2 (keys[i]);
1861       if (key == NULL)
1862         goto out;
1863       value = _dbus_strdup ("Value!");
1864       if (value == NULL)
1865         goto out;
1866       
1867       if (!_dbus_hash_table_insert_two_strings (table4,
1868                                                 key, value))
1869         goto out;
1870       
1871       _dbus_assert (count_entries (table1) == i + 1);
1872       _dbus_assert (count_entries (table2) == i + 1);
1873       _dbus_assert (count_entries (table3) == i + 1);
1874       _dbus_assert (count_entries (table4) == i + 1);
1875
1876       value = _dbus_hash_table_lookup_string (table1, keys[i]);
1877       _dbus_assert (value != NULL);
1878       _dbus_assert (strcmp (value, "Value!") == 0);
1879
1880       value = _dbus_hash_table_lookup_int (table2, i);
1881       _dbus_assert (value != NULL);
1882       _dbus_assert (strcmp (value, keys[i]) == 0);
1883
1884       value = _dbus_hash_table_lookup_uintptr (table3, i);
1885       _dbus_assert (value != NULL);
1886       _dbus_assert (strcmp (value, keys[i]) == 0);
1887
1888       value = _dbus_hash_table_lookup_two_strings (table4, keys[i]);
1889       _dbus_assert (value != NULL);
1890       _dbus_assert (strcmp (value, "Value!") == 0);
1891       
1892       ++i;
1893     }
1894
1895   --i;
1896   while (i >= 0)
1897     {
1898       _dbus_hash_table_remove_string (table1,
1899                                       keys[i]);
1900
1901       _dbus_hash_table_remove_int (table2, i);
1902
1903       _dbus_hash_table_remove_uintptr (table3, i);
1904
1905       _dbus_hash_table_remove_two_strings (table4,
1906                                            keys[i]);
1907       
1908       _dbus_assert (count_entries (table1) == i);
1909       _dbus_assert (count_entries (table2) == i);
1910       _dbus_assert (count_entries (table3) == i);
1911       _dbus_assert (count_entries (table4) == i);
1912
1913       --i;
1914     }
1915
1916   _dbus_hash_table_ref (table1);
1917   _dbus_hash_table_ref (table2);
1918   _dbus_hash_table_ref (table3);
1919   _dbus_hash_table_ref (table4);
1920   _dbus_hash_table_unref (table1);
1921   _dbus_hash_table_unref (table2);
1922   _dbus_hash_table_unref (table3);
1923   _dbus_hash_table_unref (table4);
1924   _dbus_hash_table_unref (table1);
1925   _dbus_hash_table_unref (table2);
1926   _dbus_hash_table_unref (table3);
1927   _dbus_hash_table_unref (table4);
1928   table3 = NULL;
1929
1930   /* Insert a bunch of stuff then check
1931    * that iteration works correctly (finds the right
1932    * values, iter_set_value works, etc.)
1933    */
1934   table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
1935                                  dbus_free, dbus_free);
1936   if (table1 == NULL)
1937     goto out;
1938   
1939   table2 = _dbus_hash_table_new (DBUS_HASH_INT,
1940                                  NULL, dbus_free);
1941   if (table2 == NULL)
1942     goto out;
1943   
1944   i = 0;
1945   while (i < 5000)
1946     {
1947       char *key;
1948       void *value;      
1949       
1950       key = _dbus_strdup (keys[i]);
1951       if (key == NULL)
1952         goto out;
1953       value = _dbus_strdup ("Value!");
1954       if (value == NULL)
1955         goto out;
1956       
1957       if (!_dbus_hash_table_insert_string (table1,
1958                                            key, value))
1959         goto out;
1960
1961       value = _dbus_strdup (keys[i]);
1962       if (value == NULL)
1963         goto out;
1964       
1965       if (!_dbus_hash_table_insert_int (table2,
1966                                         i, value))
1967         goto out;
1968       
1969       _dbus_assert (count_entries (table1) == i + 1);
1970       _dbus_assert (count_entries (table2) == i + 1);
1971       
1972       ++i;
1973     }
1974
1975   _dbus_hash_iter_init (table1, &iter);
1976   while (_dbus_hash_iter_next (&iter))
1977     {
1978       const char *key;
1979       void *value;
1980
1981       key = _dbus_hash_iter_get_string_key (&iter);
1982       value = _dbus_hash_iter_get_value (&iter);
1983
1984       _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
1985
1986       value = _dbus_strdup ("Different value!");
1987       if (value == NULL)
1988         goto out;
1989       
1990       _dbus_hash_iter_set_value (&iter, value);
1991
1992       _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
1993     }
1994   
1995   _dbus_hash_iter_init (table1, &iter);
1996   while (_dbus_hash_iter_next (&iter))
1997     {
1998       _dbus_hash_iter_remove_entry (&iter);
1999       _dbus_assert (count_entries (table1) == i - 1);
2000       --i;
2001     }
2002
2003   _dbus_hash_iter_init (table2, &iter);
2004   while (_dbus_hash_iter_next (&iter))
2005     {
2006       int key;
2007       void *value;
2008
2009       key = _dbus_hash_iter_get_int_key (&iter);
2010       value = _dbus_hash_iter_get_value (&iter);
2011
2012       _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
2013
2014       value = _dbus_strdup ("Different value!");
2015       if (value == NULL)
2016         goto out;
2017       
2018       _dbus_hash_iter_set_value (&iter, value);
2019
2020       _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
2021     }
2022
2023   i = count_entries (table2);
2024   _dbus_hash_iter_init (table2, &iter);
2025   while (_dbus_hash_iter_next (&iter))
2026     {
2027       _dbus_hash_iter_remove_entry (&iter);
2028       _dbus_assert (count_entries (table2) + 1 == i);
2029       --i;
2030     }
2031
2032   /* add/remove interleaved, to check that we grow/shrink the table
2033    * appropriately
2034    */
2035   i = 0;
2036   while (i < 1000)
2037     {
2038       char *key;
2039       void *value;
2040             
2041       key = _dbus_strdup (keys[i]);
2042       if (key == NULL)
2043         goto out;
2044
2045       value = _dbus_strdup ("Value!");
2046       if (value == NULL)
2047         goto out;
2048       
2049       if (!_dbus_hash_table_insert_string (table1,
2050                                            key, value))
2051         goto out;
2052       
2053       ++i;
2054     }
2055
2056   --i;
2057   while (i >= 0)
2058     {
2059       char *key;
2060       void *value;      
2061       
2062       key = _dbus_strdup (keys[i]);
2063       if (key == NULL)
2064         goto out;
2065       value = _dbus_strdup ("Value!");
2066       if (value == NULL)
2067         goto out;
2068
2069       if (!_dbus_hash_table_remove_string (table1, keys[i]))
2070         goto out;
2071       
2072       if (!_dbus_hash_table_insert_string (table1,
2073                                            key, value))
2074         goto out;
2075
2076       if (!_dbus_hash_table_remove_string (table1, keys[i]))
2077         goto out;
2078       
2079       _dbus_assert (_dbus_hash_table_get_n_entries (table1) == i);
2080       
2081       --i;
2082     }
2083
2084   /* nuke these tables */
2085   _dbus_hash_table_unref (table1);
2086   _dbus_hash_table_unref (table2);
2087
2088
2089   /* Now do a bunch of things again using _dbus_hash_iter_lookup() to
2090    * be sure that interface works.
2091    */
2092   table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
2093                                  dbus_free, dbus_free);
2094   if (table1 == NULL)
2095     goto out;
2096   
2097   table2 = _dbus_hash_table_new (DBUS_HASH_INT,
2098                                  NULL, dbus_free);
2099   if (table2 == NULL)
2100     goto out;
2101   
2102   i = 0;
2103   while (i < 3000)
2104     {
2105       void *value;
2106       char *key;
2107
2108       key = _dbus_strdup (keys[i]);
2109       if (key == NULL)
2110         goto out;
2111       value = _dbus_strdup ("Value!");
2112       if (value == NULL)
2113         goto out;
2114       
2115       if (!_dbus_hash_iter_lookup (table1,
2116                                    key, TRUE, &iter))
2117         goto out;
2118       _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
2119       _dbus_hash_iter_set_value (&iter, value);
2120
2121       value = _dbus_strdup (keys[i]);
2122       if (value == NULL)
2123         goto out;
2124
2125       if (!_dbus_hash_iter_lookup (table2,
2126                                    _DBUS_INT_TO_POINTER (i), TRUE, &iter))
2127         goto out;
2128       _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
2129       _dbus_hash_iter_set_value (&iter, value); 
2130       
2131       _dbus_assert (count_entries (table1) == i + 1);
2132       _dbus_assert (count_entries (table2) == i + 1);
2133
2134       if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
2135         goto out;
2136       
2137       value = _dbus_hash_iter_get_value (&iter);
2138       _dbus_assert (value != NULL);
2139       _dbus_assert (strcmp (value, "Value!") == 0);
2140
2141       /* Iterate just to be sure it works, though
2142        * it's a stupid thing to do
2143        */
2144       while (_dbus_hash_iter_next (&iter))
2145         ;
2146       
2147       if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
2148         goto out;
2149
2150       value = _dbus_hash_iter_get_value (&iter);
2151       _dbus_assert (value != NULL);
2152       _dbus_assert (strcmp (value, keys[i]) == 0);
2153
2154       /* Iterate just to be sure it works, though
2155        * it's a stupid thing to do
2156        */
2157       while (_dbus_hash_iter_next (&iter))
2158         ;
2159       
2160       ++i;
2161     }
2162
2163   --i;
2164   while (i >= 0)
2165     {
2166       if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
2167         _dbus_assert_not_reached ("hash entry should have existed");
2168       _dbus_hash_iter_remove_entry (&iter);
2169       
2170       if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
2171         _dbus_assert_not_reached ("hash entry should have existed");
2172       _dbus_hash_iter_remove_entry (&iter);
2173
2174       _dbus_assert (count_entries (table1) == i);
2175       _dbus_assert (count_entries (table2) == i);
2176
2177       --i;
2178     }
2179
2180   _dbus_hash_table_unref (table1);
2181   _dbus_hash_table_unref (table2);
2182
2183   ret = TRUE;
2184
2185  out:
2186   for (i = 0; i < N_HASH_KEYS; i++)
2187     dbus_free (keys[i]);
2188
2189   dbus_free (keys);
2190   
2191   return ret;
2192 }
2193
2194 #endif /* DBUS_BUILD_TESTS */