Home | History | Annotate | Download | only in dbus
      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 */
   2195