* Added some power saving features, needs some testing to confirm this is working...
[monky] / src / dbus / dbus-hash.c
diff --git a/src/dbus/dbus-hash.c b/src/dbus/dbus-hash.c
deleted file mode 100644 (file)
index d0778bf..0000000
+++ /dev/null
@@ -1,2193 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/* dbus-hash.c Generic hash table utility (internal to D-Bus implementation)
- * 
- * Copyright (C) 2002  Red Hat, Inc.
- * Copyright (c) 1991-1993 The Regents of the University of California.
- * Copyright (c) 1994 Sun Microsystems, Inc.
- * 
- * Hash table implementation based on generic/tclHash.c from the Tcl
- * source code. The original Tcl license applies to portions of the
- * code from tclHash.c; the Tcl license follows this standad D-Bus 
- * license information.
- *
- * Licensed under the Academic Free License version 2.1
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-/* 
- * The following copyright applies to code from the Tcl distribution.
- *
- * Copyright (c) 1991-1993 The Regents of the University of California.
- * Copyright (c) 1994 Sun Microsystems, Inc.
- *
- * This software is copyrighted by the Regents of the University of
- * California, Sun Microsystems, Inc., Scriptics Corporation, and
- * other parties.  The following terms apply to all files associated
- * with the software unless explicitly disclaimed in individual files.
- * 
- * The authors hereby grant permission to use, copy, modify,
- * distribute, and license this software and its documentation for any
- * purpose, provided that existing copyright notices are retained in
- * all copies and that this notice is included verbatim in any
- * distributions. No written agreement, license, or royalty fee is
- * required for any of the authorized uses.  Modifications to this
- * software may be copyrighted by their authors and need not follow
- * the licensing terms described here, provided that the new terms are
- * clearly indicated on the first page of each file where they apply.
- * 
- * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
- * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
- * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
- * OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
- * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
- * NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
- * AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
- * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- * 
- * GOVERNMENT USE: If you are acquiring this software on behalf of the
- * U.S. government, the Government shall have only "Restricted Rights"
- * in the software and related documentation as defined in the Federal
- * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
- * are acquiring the software on behalf of the Department of Defense,
- * the software shall be classified as "Commercial Computer Software"
- * and the Government shall have only "Restricted Rights" as defined
- * in Clause 252.227-7013 (c) (1) of DFARs.  Notwithstanding the
- * foregoing, the authors grant the U.S. Government and others acting
- * in its behalf permission to use and distribute the software in
- * accordance with the terms specified in this license.
- */
-
-#include "dbus-hash.h"
-#include "dbus-internals.h"
-#include "dbus-mempool.h"
-
-/**
- * @defgroup DBusHashTable Hash table
- * @ingroup  DBusInternals
- * @brief DBusHashTable data structure
- *
- * Types and functions related to DBusHashTable.
- */
-
-/**
- * @defgroup DBusHashTableInternals Hash table implementation details
- * @ingroup  DBusInternals
- * @brief DBusHashTable implementation details
- *
- * The guts of DBusHashTable.
- *
- * @{
- */
-
-/**
- * When there are this many entries per bucket, on average, rebuild
- * the hash table to make it larger.
- */
-#define REBUILD_MULTIPLIER  3
-
-/**
- * Takes a preliminary integer hash value and produces an index into a
- * hash tables bucket list.  The idea is to make it so that
- * preliminary values that are arbitrarily similar will end up in
- * different buckets.  The hash function was taken from a
- * random-number generator. (This is used to hash integers.)
- *
- * The down_shift drops off the high bits of the hash index, and
- * decreases as we increase the number of hash buckets (to keep more
- * range in the hash index). The mask also strips high bits and strips
- * fewer high bits as the number of hash buckets increases.
- * I don't understand two things: why is the initial downshift 28
- * to keep 4 bits when the initial mask is 011 to keep 2 bits,
- * and why do we have both a mask and a downshift?
- * 
- */
-#define RANDOM_INDEX(table, i) \
-    (((((long) (i))*1103515245) >> (table)->down_shift) & (table)->mask)
-
-/**
- * Initial number of buckets in hash table (hash table statically
- * allocates its buckets for this size and below).
- * The initial mask has to be synced to this.
- */
-#define DBUS_SMALL_HASH_TABLE 4
-
-/**
- * Typedef for DBusHashEntry
- */
-typedef struct DBusHashEntry DBusHashEntry;
-
-/**
- * @brief Internal representation of a hash entry.
- * 
- * A single entry (key-value pair) in the hash table.
- * Internal to hash table implementation.
- */
-struct DBusHashEntry
-{
-  DBusHashEntry *next;    /**< Pointer to next entry in this
-                           * hash bucket, or #NULL for end of
-                           * chain.
-                           */
-  void *key;              /**< Hash key */
-  void *value;            /**< Hash value */
-};
-
-/**
- * Function used to find and optionally create a hash entry.
- */
-typedef DBusHashEntry* (* DBusFindEntryFunction) (DBusHashTable        *table,
-                                                  void                 *key,
-                                                  dbus_bool_t           create_if_not_found,
-                                                  DBusHashEntry      ***bucket,
-                                                  DBusPreallocatedHash *preallocated);
-
-/**
- * @brief Internals of DBusHashTable.
- * 
- * Hash table internals. Hash tables are opaque objects, they must be
- * used via accessor functions.
- */
-struct DBusHashTable {
-  int refcount;                       /**< Reference count */
-  
-  DBusHashEntry **buckets;            /**< Pointer to bucket array.  Each
-                                       * element points to first entry in
-                                       * bucket's hash chain, or #NULL.
-                                       */
-  DBusHashEntry *static_buckets[DBUS_SMALL_HASH_TABLE];
-                                       /**< Bucket array used for small tables
-                                        * (to avoid mallocs and frees).
-                                        */
-  int n_buckets;                       /**< Total number of buckets allocated
-                                        * at **buckets.
-                                        */
-  int n_entries;                       /**< Total number of entries present
-                                        * in table.
-                                        */
-  int hi_rebuild_size;                 /**< Enlarge table when n_entries gets
-                                        * to be this large.
-                                        */
-  int lo_rebuild_size;                 /**< Shrink table when n_entries gets
-                                        * below this.
-                                        */
-  int down_shift;                      /**< Shift count used in hashing
-                                        * function.  Designed to use high-
-                                        * order bits of randomized keys.
-                                        */
-  int mask;                            /**< Mask value used in hashing
-                                        * function.
-                                        */
-  DBusHashType key_type;               /**< Type of keys used in this table */
-
-
-  DBusFindEntryFunction find_function; /**< Function for finding entries */
-
-  DBusFreeFunction free_key_function;   /**< Function to free keys */
-  DBusFreeFunction free_value_function; /**< Function to free values */
-
-  DBusMemPool *entry_pool;              /**< Memory pool for hash entries */
-};
-
-/** 
- * @brief Internals of DBusHashIter.
- */
-typedef struct
-{
-  DBusHashTable *table;     /**< Pointer to table containing entry. */
-  DBusHashEntry **bucket;   /**< Pointer to bucket that points to
-                             * first entry in this entry's chain:
-                             * used for deleting the entry.
-                             */
-  DBusHashEntry *entry;      /**< Current hash entry */
-  DBusHashEntry *next_entry; /**< Next entry to be iterated onto in current bucket */
-  int next_bucket;           /**< index of next bucket */
-  int n_entries_on_init;     /**< used to detect table resize since initialization */
-} DBusRealHashIter;
-
-static DBusHashEntry* find_direct_function      (DBusHashTable          *table,
-                                                 void                   *key,
-                                                 dbus_bool_t             create_if_not_found,
-                                                 DBusHashEntry        ***bucket,
-                                                 DBusPreallocatedHash   *preallocated);
-static DBusHashEntry* find_string_function      (DBusHashTable          *table,
-                                                 void                   *key,
-                                                 dbus_bool_t             create_if_not_found,
-                                                 DBusHashEntry        ***bucket,
-                                                 DBusPreallocatedHash   *preallocated);
-#ifdef DBUS_BUILD_TESTS
-static DBusHashEntry* find_two_strings_function (DBusHashTable          *table,
-                                                 void                   *key,
-                                                 dbus_bool_t             create_if_not_found,
-                                                 DBusHashEntry        ***bucket,
-                                                 DBusPreallocatedHash   *preallocated);
-#endif
-static unsigned int   string_hash               (const char             *str);
-#ifdef DBUS_BUILD_TESTS
-static unsigned int   two_strings_hash          (const char             *str);
-#endif
-static void           rebuild_table             (DBusHashTable          *table);
-static DBusHashEntry* alloc_entry               (DBusHashTable          *table);
-static void           remove_entry              (DBusHashTable          *table,
-                                                 DBusHashEntry         **bucket,
-                                                 DBusHashEntry          *entry);
-static void           free_entry                (DBusHashTable          *table,
-                                                 DBusHashEntry          *entry);
-static void           free_entry_data           (DBusHashTable          *table,
-                                                 DBusHashEntry          *entry);
-
-
-/** @} */
-
-/**
- * @addtogroup DBusHashTable
- * @{
- */
-
-/**
- * @typedef DBusHashIter
- *
- * Public opaque hash table iterator object.
- */
-
-/**
- * @typedef DBusHashTable
- *
- * Public opaque hash table object.
- */
-
-/**
- * @typedef DBusHashType
- *
- * Indicates the type of a key in the hash table.
- */
-
-/**
- * Constructs a new hash table. Should be freed with
- * _dbus_hash_table_unref(). If memory cannot be
- * allocated for the hash table, returns #NULL.
- *
- * @param type the type of hash key to use.
- * @param key_free_function function to free hash keys.
- * @param value_free_function function to free hash values.
- * @returns a new DBusHashTable or #NULL if no memory.
- */
-DBusHashTable*
-_dbus_hash_table_new (DBusHashType     type,
-                      DBusFreeFunction key_free_function,
-                      DBusFreeFunction value_free_function)
-{
-  DBusHashTable *table;
-  DBusMemPool *entry_pool;
-  
-  table = dbus_new0 (DBusHashTable, 1);
-  if (table == NULL)
-    return NULL;
-
-  entry_pool = _dbus_mem_pool_new (sizeof (DBusHashEntry), TRUE);
-  if (entry_pool == NULL)
-    {
-      dbus_free (table);
-      return NULL;
-    }
-  
-  table->refcount = 1;
-  table->entry_pool = entry_pool;
-  
-  _dbus_assert (DBUS_SMALL_HASH_TABLE == _DBUS_N_ELEMENTS (table->static_buckets));
-  
-  table->buckets = table->static_buckets;  
-  table->n_buckets = DBUS_SMALL_HASH_TABLE;
-  table->n_entries = 0;
-  table->hi_rebuild_size = DBUS_SMALL_HASH_TABLE * REBUILD_MULTIPLIER;
-  table->lo_rebuild_size = 0;
-  table->down_shift = 28;
-  table->mask = 3;
-  table->key_type = type;
-
-  _dbus_assert (table->mask < table->n_buckets);
-  
-  switch (table->key_type)
-    {
-    case DBUS_HASH_INT:
-    case DBUS_HASH_POINTER:
-    case DBUS_HASH_ULONG:
-      table->find_function = find_direct_function;
-      break;
-    case DBUS_HASH_STRING:
-      table->find_function = find_string_function;
-      break;
-    case DBUS_HASH_TWO_STRINGS:
-#ifdef DBUS_BUILD_TESTS
-      table->find_function = find_two_strings_function;
-#endif
-      break;
-    default:
-      _dbus_assert_not_reached ("Unknown hash table type");
-      break;
-    }
-
-  table->free_key_function = key_free_function;
-  table->free_value_function = value_free_function;
-
-  return table;
-}
-
-
-/**
- * Increments the reference count for a hash table.
- *
- * @param table the hash table to add a reference to.
- * @returns the hash table.
- */
-DBusHashTable *
-_dbus_hash_table_ref (DBusHashTable *table)
-{
-  table->refcount += 1;
-  
-  return table;
-}
-
-/**
- * Decrements the reference count for a hash table,
- * freeing the hash table if the count reaches zero.
- *
- * @param table the hash table to remove a reference from.
- */
-void
-_dbus_hash_table_unref (DBusHashTable *table)
-{
-  table->refcount -= 1;
-
-  if (table->refcount == 0)
-    {
-#if 0
-      DBusHashEntry *entry;
-      DBusHashEntry *next;
-      int i;
-
-      /* Free the entries in the table. */
-      for (i = 0; i < table->n_buckets; i++)
-        {
-          entry = table->buckets[i];
-          while (entry != NULL)
-            {
-              next = entry->next;
-
-              free_entry (table, entry);
-              
-              entry = next;
-            }
-        }
-#else
-      DBusHashEntry *entry;
-      int i;
-
-      /* Free the entries in the table. */
-      for (i = 0; i < table->n_buckets; i++)
-        {
-          entry = table->buckets[i];
-          while (entry != NULL)
-            {
-              free_entry_data (table, entry);
-              
-              entry = entry->next;
-            }
-        }
-      /* We can do this very quickly with memory pools ;-) */
-      _dbus_mem_pool_free (table->entry_pool);
-#endif
-      
-      /* Free the bucket array, if it was dynamically allocated. */
-      if (table->buckets != table->static_buckets)
-        dbus_free (table->buckets);
-
-      dbus_free (table);
-    }
-}
-
-/**
- * Removed all entries from a hash table.
- *
- * @param table the hash table to remove all entries from.
- */
-void
-_dbus_hash_table_remove_all (DBusHashTable *table)
-{
-  DBusHashIter iter;
-  _dbus_hash_iter_init (table, &iter);
-  while (_dbus_hash_iter_next (&iter))
-    {
-      _dbus_hash_iter_remove_entry(&iter);
-    }
-}
-
-static DBusHashEntry*
-alloc_entry (DBusHashTable *table)
-{
-  DBusHashEntry *entry;
-
-  entry = _dbus_mem_pool_alloc (table->entry_pool);
-  
-  return entry;
-}
-
-static void
-free_entry_data (DBusHashTable  *table,
-                DBusHashEntry  *entry)
-{
-  if (table->free_key_function)
-    (* table->free_key_function) (entry->key);
-  if (table->free_value_function)
-    (* table->free_value_function) (entry->value);
-}
-
-static void
-free_entry (DBusHashTable  *table,
-            DBusHashEntry  *entry)
-{
-  free_entry_data (table, entry);
-  _dbus_mem_pool_dealloc (table->entry_pool, entry);
-}
-
-static void
-remove_entry (DBusHashTable  *table,
-              DBusHashEntry **bucket,
-              DBusHashEntry  *entry)
-{
-  _dbus_assert (table != NULL);
-  _dbus_assert (bucket != NULL);
-  _dbus_assert (*bucket != NULL);  
-  _dbus_assert (entry != NULL);
-  
-  if (*bucket == entry)
-    *bucket = entry->next;
-  else
-    {
-      DBusHashEntry *prev;
-      prev = *bucket;
-
-      while (prev->next != entry)
-        prev = prev->next;      
-      
-      _dbus_assert (prev != NULL);
-
-      prev->next = entry->next;
-    }
-  
-  table->n_entries -= 1;
-  free_entry (table, entry);
-}
-
-/**
- * Initializes a hash table iterator. To iterate over all entries in a
- * hash table, use the following code (the printf assumes a hash
- * from strings to strings obviously):
- *
- * @code
- * DBusHashIter iter;
- *
- * _dbus_hash_iter_init (table, &iter);
- * while (_dbus_hash_iter_next (&iter))
- *   {
- *      printf ("The first key is %s and value is %s\n",
- *              _dbus_hash_iter_get_string_key (&iter),
- *              _dbus_hash_iter_get_value (&iter));
- *   }
- * 
- * 
- * @endcode
- *
- * The iterator is initialized pointing "one before" the first hash
- * entry. The first call to _dbus_hash_iter_next() moves it onto
- * the first valid entry or returns #FALSE if the hash table is
- * empty. Subsequent calls move to the next valid entry or return
- * #FALSE if there are no more entries.
- *
- * Note that it is guaranteed to be safe to remove a hash entry during
- * iteration, but it is not safe to add a hash entry.
- * 
- * @param table the hash table to iterate over.
- * @param iter the iterator to initialize.
- */
-void
-_dbus_hash_iter_init (DBusHashTable *table,
-                      DBusHashIter  *iter)
-{
-  DBusRealHashIter *real;
-  
-  _dbus_assert (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
-  
-  real = (DBusRealHashIter*) iter;
-
-  real->table = table;
-  real->bucket = NULL;
-  real->entry = NULL;
-  real->next_entry = NULL;
-  real->next_bucket = 0;
-  real->n_entries_on_init = table->n_entries;
-}
-
-/**
- * Move the hash iterator forward one step, to the next hash entry.
- * The documentation for _dbus_hash_iter_init() explains in more
- * detail.
- *
- * @param iter the iterator to move forward.
- * @returns #FALSE if there are no more entries to move to.
- */
-dbus_bool_t
-_dbus_hash_iter_next (DBusHashIter  *iter)
-{
-  DBusRealHashIter *real;
-  
-  _dbus_assert (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
-  
-  real = (DBusRealHashIter*) iter;
-
-  /* if this assertion failed someone probably added hash entries
-   * during iteration, which is bad.
-   */
-  _dbus_assert (real->n_entries_on_init >= real->table->n_entries);
-  
-  /* Remember that real->entry may have been deleted */
-  
-  while (real->next_entry == NULL)
-    {
-      if (real->next_bucket >= real->table->n_buckets)
-        {
-          /* invalidate iter and return false */
-          real->entry = NULL;
-          real->table = NULL;
-          real->bucket = NULL;
-          return FALSE;
-        }
-
-      real->bucket = &(real->table->buckets[real->next_bucket]);
-      real->next_entry = *(real->bucket);
-      real->next_bucket += 1;
-    }
-
-  _dbus_assert (real->next_entry != NULL);
-  _dbus_assert (real->bucket != NULL);
-  
-  real->entry = real->next_entry;
-  real->next_entry = real->entry->next;
-  
-  return TRUE;
-}
-
-/**
- * Removes the current entry from the hash table.
- * If a key_free_function or value_free_function
- * was provided to _dbus_hash_table_new(),
- * frees the key and/or value for this entry.
- *
- * @param iter the hash table iterator.
- */
-void
-_dbus_hash_iter_remove_entry (DBusHashIter *iter)
-{
-  DBusRealHashIter *real;
-
-  real = (DBusRealHashIter*) iter;
-
-  _dbus_assert (real->table != NULL);
-  _dbus_assert (real->entry != NULL);
-  _dbus_assert (real->bucket != NULL);
-  
-  remove_entry (real->table, real->bucket, real->entry);
-
-  real->entry = NULL; /* make it crash if you try to use this entry */
-}
-
-/**
- * Gets the value of the current entry.
- *
- * @param iter the hash table iterator.
- */
-void*
-_dbus_hash_iter_get_value (DBusHashIter *iter)
-{
-  DBusRealHashIter *real;
-
-  real = (DBusRealHashIter*) iter;
-
-  _dbus_assert (real->table != NULL);
-  _dbus_assert (real->entry != NULL);
-
-  return real->entry->value;
-}
-
-/**
- * Sets the value of the current entry.
- * If the hash table has a value_free_function
- * it will be used to free the previous value.
- * The hash table will own the passed-in value
- * (it will not be copied).
- *
- * @param iter the hash table iterator.
- * @param value the new value.
- */
-void
-_dbus_hash_iter_set_value (DBusHashIter *iter,
-                           void         *value)
-{
-  DBusRealHashIter *real;
-
-  real = (DBusRealHashIter*) iter;
-
-  _dbus_assert (real->table != NULL);
-  _dbus_assert (real->entry != NULL);
-
-  if (real->table->free_value_function && value != real->entry->value)    
-    (* real->table->free_value_function) (real->entry->value);
-  
-  real->entry->value = value;
-}
-
-/**
- * Gets the key for the current entry.
- * Only works for hash tables of type #DBUS_HASH_INT.
- *
- * @param iter the hash table iterator.
- */
-int
-_dbus_hash_iter_get_int_key (DBusHashIter *iter)
-{
-  DBusRealHashIter *real;
-
-  real = (DBusRealHashIter*) iter;
-
-  _dbus_assert (real->table != NULL);
-  _dbus_assert (real->entry != NULL);
-
-  return _DBUS_POINTER_TO_INT (real->entry->key);
-}
-
-/**
- * Gets the key for the current entry.
- * Only works for hash tables of type #DBUS_HASH_ULONG.
- *
- * @param iter the hash table iterator.
- */
-unsigned long
-_dbus_hash_iter_get_ulong_key (DBusHashIter *iter)
-{
-  DBusRealHashIter *real;
-
-  real = (DBusRealHashIter*) iter;
-
-  _dbus_assert (real->table != NULL);
-  _dbus_assert (real->entry != NULL);
-
-  return (unsigned long) real->entry->key;
-}
-
-/**
- * Gets the key for the current entry.
- * Only works for hash tables of type #DBUS_HASH_STRING
- * @param iter the hash table iterator.
- */
-const char*
-_dbus_hash_iter_get_string_key (DBusHashIter *iter)
-{
-  DBusRealHashIter *real;
-
-  real = (DBusRealHashIter*) iter;
-
-  _dbus_assert (real->table != NULL);
-  _dbus_assert (real->entry != NULL);
-
-  return real->entry->key;
-}
-
-#ifdef DBUS_BUILD_TESTS
-/**
- * Gets the key for the current entry.
- * Only works for hash tables of type #DBUS_HASH_TWO_STRINGS
- * @param iter the hash table iterator.
- */
-const char*
-_dbus_hash_iter_get_two_strings_key (DBusHashIter *iter)
-{
-  DBusRealHashIter *real;
-
-  real = (DBusRealHashIter*) iter;
-
-  _dbus_assert (real->table != NULL);
-  _dbus_assert (real->entry != NULL);
-
-  return real->entry->key;
-}
-#endif /* DBUS_BUILD_TESTS */
-
-/**
- * A low-level but efficient interface for manipulating the hash
- * table.  It's efficient because you can get, set, and optionally
- * create the hash entry while only running the hash function one
- * time.
- *
- * Note that while calling _dbus_hash_iter_next() on the iterator
- * filled in by this function may work, it's completely
- * undefined which entries are after this iter and which
- * are before it. So it would be silly to iterate using this
- * iterator.
- *
- * If the hash entry is created, its value will be initialized
- * to all bits zero.
- *
- * #FALSE may be returned due to memory allocation failure, or
- * because create_if_not_found was #FALSE and the entry
- * did not exist.
- *
- * If create_if_not_found is #TRUE and the entry is created, the hash
- * table takes ownership of the key that's passed in.
- *
- * For a hash table of type #DBUS_HASH_INT, cast the int
- * key to the key parameter using #_DBUS_INT_TO_POINTER().
- * 
- * @param table the hash table.
- * @param key the hash key.
- * @param create_if_not_found if #TRUE, create the entry if it didn't exist.
- * @param iter the iterator to initialize.
- * @returns #TRUE if the hash entry now exists (and the iterator is thus valid).
- */
-dbus_bool_t
-_dbus_hash_iter_lookup (DBusHashTable *table,
-                        void          *key,
-                        dbus_bool_t    create_if_not_found,
-                        DBusHashIter  *iter)
-{
-  DBusRealHashIter *real;
-  DBusHashEntry *entry;
-  DBusHashEntry **bucket;
-  
-  _dbus_assert (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
-  
-  real = (DBusRealHashIter*) iter;
-
-  entry = (* table->find_function) (table, key, create_if_not_found, &bucket, NULL);
-
-  if (entry == NULL)
-    return FALSE;
-  
-  real->table = table;
-  real->bucket = bucket;
-  real->entry = entry;
-  real->next_entry = entry->next;
-  real->next_bucket = (bucket - table->buckets) + 1;
-  real->n_entries_on_init = table->n_entries; 
-
-  _dbus_assert (&(table->buckets[real->next_bucket-1]) == real->bucket);
-  
-  return TRUE;
-}
-
-static void
-add_allocated_entry (DBusHashTable   *table,
-                     DBusHashEntry   *entry,
-                     unsigned int     idx,
-                     void            *key,
-                     DBusHashEntry ***bucket)
-{
-  DBusHashEntry **b;  
-  
-  entry->key = key;
-  
-  b = &(table->buckets[idx]);
-  entry->next = *b;
-  *b = entry;
-
-  if (bucket)
-    *bucket = b;
-  
-  table->n_entries += 1;
-
-  /* note we ONLY rebuild when ADDING - because you can iterate over a
-   * table and remove entries safely.
-   */
-  if (table->n_entries >= table->hi_rebuild_size ||
-      table->n_entries < table->lo_rebuild_size)
-    rebuild_table (table);
-}
-
-static DBusHashEntry*
-add_entry (DBusHashTable        *table, 
-           unsigned int          idx,
-           void                 *key,
-           DBusHashEntry      ***bucket,
-           DBusPreallocatedHash *preallocated)
-{
-  DBusHashEntry  *entry;
-
-  if (preallocated == NULL)
-    {
-      entry = alloc_entry (table);
-      if (entry == NULL)
-        {
-          if (bucket)
-            *bucket = NULL;
-          return NULL;
-        }
-    }
-  else
-    {
-      entry = (DBusHashEntry*) preallocated;
-    }
-
-  add_allocated_entry (table, entry, idx, key, bucket);
-
-  return entry;
-}
-
-/* This is g_str_hash from GLib which was
- * extensively discussed/tested/profiled
- */
-static unsigned int
-string_hash (const char *str)
-{
-  const char *p = str;
-  unsigned int h = *p;
-
-  if (h)
-    for (p += 1; *p != '\0'; p++)
-      h = (h << 5) - h + *p;
-
-  return h;
-}
-
-#ifdef DBUS_BUILD_TESTS
-/* This hashes a memory block with two nul-terminated strings
- * in it, used in dbus-object-registry.c at the moment.
- */
-static unsigned int
-two_strings_hash (const char *str)
-{
-  const char *p = str;
-  unsigned int h = *p;
-
-  if (h)
-    for (p += 1; *p != '\0'; p++)
-      h = (h << 5) - h + *p;
-
-  for (p += 1; *p != '\0'; p++)
-    h = (h << 5) - h + *p;
-  
-  return h;
-}
-#endif /* DBUS_BUILD_TESTS */
-
-/** Key comparison function */
-typedef int (* KeyCompareFunc) (const void *key_a, const void *key_b);
-
-static DBusHashEntry*
-find_generic_function (DBusHashTable        *table,
-                       void                 *key,
-                       unsigned int          idx,
-                       KeyCompareFunc        compare_func,
-                       dbus_bool_t           create_if_not_found,
-                       DBusHashEntry      ***bucket,
-                       DBusPreallocatedHash *preallocated)
-{
-  DBusHashEntry *entry;
-
-  if (bucket)
-    *bucket = NULL;
-
-  /* Search all of the entries in this bucket. */
-  entry = table->buckets[idx];
-  while (entry != NULL)
-    {
-      if ((compare_func == NULL && key == entry->key) ||
-          (compare_func != NULL && (* compare_func) (key, entry->key) == 0))
-        {
-          if (bucket)
-            *bucket = &(table->buckets[idx]);
-
-          if (preallocated)
-            _dbus_hash_table_free_preallocated_entry (table, preallocated);
-          
-          return entry;
-        }
-      
-      entry = entry->next;
-    }
-
-  if (create_if_not_found)
-    entry = add_entry (table, idx, key, bucket, preallocated);
-  else if (preallocated)
-    _dbus_hash_table_free_preallocated_entry (table, preallocated);
-  
-  return entry;
-}
-
-static DBusHashEntry*
-find_string_function (DBusHashTable        *table,
-                      void                 *key,
-                      dbus_bool_t           create_if_not_found,
-                      DBusHashEntry      ***bucket,
-                      DBusPreallocatedHash *preallocated)
-{
-  unsigned int idx;
-  
-  idx = string_hash (key) & table->mask;
-
-  return find_generic_function (table, key, idx,
-                                (KeyCompareFunc) strcmp, create_if_not_found, bucket,
-                                preallocated);
-}
-
-#ifdef DBUS_BUILD_TESTS
-static int
-two_strings_cmp (const char *a,
-                 const char *b)
-{
-  size_t len_a;
-  size_t len_b;
-  int res;
-  
-  res = strcmp (a, b);
-  if (res != 0)
-    return res;
-
-  len_a = strlen (a);
-  len_b = strlen (b);
-
-  return strcmp (a + len_a + 1, b + len_b + 1);
-}
-#endif
-
-#ifdef DBUS_BUILD_TESTS
-static DBusHashEntry*
-find_two_strings_function (DBusHashTable        *table,
-                           void                 *key,
-                           dbus_bool_t           create_if_not_found,
-                           DBusHashEntry      ***bucket,
-                           DBusPreallocatedHash *preallocated)
-{
-  unsigned int idx;
-  
-  idx = two_strings_hash (key) & table->mask;
-
-  return find_generic_function (table, key, idx,
-                                (KeyCompareFunc) two_strings_cmp, create_if_not_found, bucket,
-                                preallocated);
-}
-#endif /* DBUS_BUILD_TESTS */
-
-static DBusHashEntry*
-find_direct_function (DBusHashTable        *table,
-                      void                 *key,
-                      dbus_bool_t           create_if_not_found,
-                      DBusHashEntry      ***bucket,
-                      DBusPreallocatedHash *preallocated)
-{
-  unsigned int idx;
-  
-  idx = RANDOM_INDEX (table, key) & table->mask;
-
-
-  return find_generic_function (table, key, idx,
-                                NULL, create_if_not_found, bucket,
-                                preallocated);
-}
-
-static void
-rebuild_table (DBusHashTable *table)
-{
-  int old_size;
-  int new_buckets;
-  DBusHashEntry **old_buckets;
-  DBusHashEntry **old_chain;
-  DBusHashEntry *entry;
-  dbus_bool_t growing;
-  
-  /*
-   * Allocate and initialize the new bucket array, and set up
-   * hashing constants for new array size.
-   */
-
-  growing = table->n_entries >= table->hi_rebuild_size;
-  
-  old_size = table->n_buckets;
-  old_buckets = table->buckets;
-
-  if (growing)
-    {
-      /* overflow paranoia */
-      if (table->n_buckets < _DBUS_INT_MAX / 4 &&
-          table->down_shift >= 0)
-        new_buckets = table->n_buckets * 4;
-      else
-        return; /* can't grow anymore */
-    }
-  else
-    {
-      new_buckets = table->n_buckets / 4;
-      if (new_buckets < DBUS_SMALL_HASH_TABLE)
-        return; /* don't bother shrinking this far */
-    }
-
-  table->buckets = dbus_new0 (DBusHashEntry*, new_buckets);
-  if (table->buckets == NULL)
-    {
-      /* out of memory, yay - just don't reallocate, the table will
-       * still work, albeit more slowly.
-       */
-      table->buckets = old_buckets;
-      return;
-    }
-
-  table->n_buckets = new_buckets;
-  
-  if (growing)
-    {
-      table->lo_rebuild_size = table->hi_rebuild_size;
-      table->hi_rebuild_size *= 4;
-      
-      table->down_shift -= 2;               /* keep 2 more high bits */
-      table->mask = (table->mask << 2) + 3; /* keep 2 more high bits */
-    }
-  else
-    {
-      table->hi_rebuild_size = table->lo_rebuild_size;
-      table->lo_rebuild_size /= 4;
-
-      table->down_shift += 2;         /* keep 2 fewer high bits */
-      table->mask = table->mask >> 2; /* keep 2 fewer high bits */
-    }
-
-#if 0
-  printf ("%s table to lo = %d hi = %d downshift = %d mask = 0x%x\n",
-          growing ? "GROW" : "SHRINK",
-          table->lo_rebuild_size,
-          table->hi_rebuild_size,
-          table->down_shift,
-          table->mask);
-#endif
-  
-  _dbus_assert (table->lo_rebuild_size >= 0);
-  _dbus_assert (table->hi_rebuild_size > table->lo_rebuild_size);
-  _dbus_assert (table->mask != 0);
-  /* the mask is essentially the max index */
-  _dbus_assert (table->mask < table->n_buckets);
-  
-  /*
-   * Rehash all of the existing entries into the new bucket array.
-   */
-
-  for (old_chain = old_buckets; old_size > 0; old_size--, old_chain++)
-    {
-      for (entry = *old_chain; entry != NULL; entry = *old_chain)
-        {
-          unsigned int idx;
-          DBusHashEntry **bucket;
-          
-          *old_chain = entry->next;
-          switch (table->key_type)
-            {
-            case DBUS_HASH_STRING:
-              idx = string_hash (entry->key) & table->mask;
-              break;
-            case DBUS_HASH_TWO_STRINGS:
-#ifdef DBUS_BUILD_TESTS
-              idx = two_strings_hash (entry->key) & table->mask;
-#else
-              idx = 0;
-              _dbus_assert_not_reached ("two-strings is not enabled");
-#endif
-              break;
-            case DBUS_HASH_INT:
-            case DBUS_HASH_ULONG:
-            case DBUS_HASH_POINTER:
-              idx = RANDOM_INDEX (table, entry->key);
-              break;
-            default:
-              idx = 0;
-              _dbus_assert_not_reached ("Unknown hash table type");
-              break;
-            }
-          
-          bucket = &(table->buckets[idx]);
-          entry->next = *bucket;
-          *bucket = entry;
-        }
-    }
-  
-  /* Free the old bucket array, if it was dynamically allocated. */
-
-  if (old_buckets != table->static_buckets)
-    dbus_free (old_buckets);
-}
-
-/**
- * Looks up the value for a given string in a hash table
- * of type #DBUS_HASH_STRING. Returns %NULL if the value
- * is not present. (A not-present entry is indistinguishable
- * from an entry with a value of %NULL.)
- * @param table the hash table.
- * @param key the string to look up.
- * @returns the value of the hash entry.
- */
-void*
-_dbus_hash_table_lookup_string (DBusHashTable *table,
-                                const char    *key)
-{
-  DBusHashEntry *entry;
-
-  _dbus_assert (table->key_type == DBUS_HASH_STRING);
-  
-  entry = (* table->find_function) (table, (char*) key, FALSE, NULL, NULL);
-
-  if (entry)
-    return entry->value;
-  else
-    return NULL;
-}
-
-#ifdef DBUS_BUILD_TESTS
-/**
- * Looks up the value for a given string in a hash table
- * of type #DBUS_HASH_TWO_STRINGS. Returns %NULL if the value
- * is not present. (A not-present entry is indistinguishable
- * from an entry with a value of %NULL.)
- * @param table the hash table.
- * @param key the string to look up.
- * @returns the value of the hash entry.
- */
-void*
-_dbus_hash_table_lookup_two_strings (DBusHashTable *table,
-                                     const char    *key)
-{
-  DBusHashEntry *entry;
-
-  _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
-  
-  entry = (* table->find_function) (table, (char*) key, FALSE, NULL, NULL);
-
-  if (entry)
-    return entry->value;
-  else
-    return NULL;
-}
-#endif /* DBUS_BUILD_TESTS */
-
-/**
- * Looks up the value for a given integer in a hash table
- * of type #DBUS_HASH_INT. Returns %NULL if the value
- * is not present. (A not-present entry is indistinguishable
- * from an entry with a value of %NULL.)
- * @param table the hash table.
- * @param key the integer to look up.
- * @returns the value of the hash entry.
- */
-void*
-_dbus_hash_table_lookup_int (DBusHashTable *table,
-                             int            key)
-{
-  DBusHashEntry *entry;
-
-  _dbus_assert (table->key_type == DBUS_HASH_INT);
-  
-  entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, NULL, NULL);
-
-  if (entry)
-    return entry->value;
-  else
-    return NULL;
-}
-
-#ifdef DBUS_BUILD_TESTS
-/* disabled since it's only used for testing */
-/**
- * Looks up the value for a given integer in a hash table
- * of type #DBUS_HASH_POINTER. Returns %NULL if the value
- * is not present. (A not-present entry is indistinguishable
- * from an entry with a value of %NULL.)
- * @param table the hash table.
- * @param key the integer to look up.
- * @returns the value of the hash entry.
- */
-void*
-_dbus_hash_table_lookup_pointer (DBusHashTable *table,
-                                 void          *key)
-{
-  DBusHashEntry *entry;
-
-  _dbus_assert (table->key_type == DBUS_HASH_POINTER);
-  
-  entry = (* table->find_function) (table, key, FALSE, NULL, NULL);
-
-  if (entry)
-    return entry->value;
-  else
-    return NULL;
-}
-#endif /* DBUS_BUILD_TESTS */
-
-/**
- * Looks up the value for a given integer in a hash table
- * of type #DBUS_HASH_ULONG. Returns %NULL if the value
- * is not present. (A not-present entry is indistinguishable
- * from an entry with a value of %NULL.)
- * @param table the hash table.
- * @param key the integer to look up.
- * @returns the value of the hash entry.
- */
-void*
-_dbus_hash_table_lookup_ulong (DBusHashTable *table,
-                               unsigned long  key)
-{
-  DBusHashEntry *entry;
-
-  _dbus_assert (table->key_type == DBUS_HASH_ULONG);
-  
-  entry = (* table->find_function) (table, (void*) key, FALSE, NULL, NULL);
-
-  if (entry)
-    return entry->value;
-  else
-    return NULL;
-}
-
-/**
- * Removes the hash entry for the given key. If no hash entry
- * for the key exists, does nothing.
- *
- * @param table the hash table.
- * @param key the hash key.
- * @returns #TRUE if the entry existed
- */
-dbus_bool_t
-_dbus_hash_table_remove_string (DBusHashTable *table,
-                                const char    *key)
-{
-  DBusHashEntry *entry;
-  DBusHashEntry **bucket;
-  
-  _dbus_assert (table->key_type == DBUS_HASH_STRING);
-  
-  entry = (* table->find_function) (table, (char*) key, FALSE, &bucket, NULL);
-
-  if (entry)
-    {
-      remove_entry (table, bucket, entry);
-      return TRUE;
-    }
-  else
-    return FALSE;
-}
-
-#ifdef DBUS_BUILD_TESTS
-/**
- * Removes the hash entry for the given key. If no hash entry
- * for the key exists, does nothing.
- *
- * @param table the hash table.
- * @param key the hash key.
- * @returns #TRUE if the entry existed
- */
-dbus_bool_t
-_dbus_hash_table_remove_two_strings (DBusHashTable *table,
-                                     const char    *key)
-{
-  DBusHashEntry *entry;
-  DBusHashEntry **bucket;
-  
-  _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
-  
-  entry = (* table->find_function) (table, (char*) key, FALSE, &bucket, NULL);
-
-  if (entry)
-    {
-      remove_entry (table, bucket, entry);
-      return TRUE;
-    }
-  else
-    return FALSE;
-}
-#endif /* DBUS_BUILD_TESTS */
-
-/**
- * Removes the hash entry for the given key. If no hash entry
- * for the key exists, does nothing.
- *
- * @param table the hash table.
- * @param key the hash key.
- * @returns #TRUE if the entry existed
- */
-dbus_bool_t
-_dbus_hash_table_remove_int (DBusHashTable *table,
-                             int            key)
-{
-  DBusHashEntry *entry;
-  DBusHashEntry **bucket;
-  
-  _dbus_assert (table->key_type == DBUS_HASH_INT);
-  
-  entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, &bucket, NULL);
-  
-  if (entry)
-    {
-      remove_entry (table, bucket, entry);
-      return TRUE;
-    }
-  else
-    return FALSE;
-}
-
-#ifdef DBUS_BUILD_TESTS
-/* disabled since it's only used for testing */
-/**
- * Removes the hash entry for the given key. If no hash entry
- * for the key exists, does nothing.
- *
- * @param table the hash table.
- * @param key the hash key.
- * @returns #TRUE if the entry existed
- */
-dbus_bool_t
-_dbus_hash_table_remove_pointer (DBusHashTable *table,
-                                 void          *key)
-{
-  DBusHashEntry *entry;
-  DBusHashEntry **bucket;
-  
-  _dbus_assert (table->key_type == DBUS_HASH_POINTER);
-  
-  entry = (* table->find_function) (table, key, FALSE, &bucket, NULL);
-  
-  if (entry)
-    {
-      remove_entry (table, bucket, entry);
-      return TRUE;
-    }
-  else
-    return FALSE;
-}
-#endif /* DBUS_BUILD_TESTS */
-
-/**
- * Removes the hash entry for the given key. If no hash entry
- * for the key exists, does nothing.
- *
- * @param table the hash table.
- * @param key the hash key.
- * @returns #TRUE if the entry existed
- */
-dbus_bool_t
-_dbus_hash_table_remove_ulong (DBusHashTable *table,
-                               unsigned long  key)
-{
-  DBusHashEntry *entry;
-  DBusHashEntry **bucket;
-  
-  _dbus_assert (table->key_type == DBUS_HASH_ULONG);
-  
-  entry = (* table->find_function) (table, (void*) key, FALSE, &bucket, NULL);
-  
-  if (entry)
-    {
-      remove_entry (table, bucket, entry);
-      return TRUE;
-    }
-  else
-    return FALSE;
-}
-
-/**
- * Creates a hash entry with the given key and value.
- * The key and value are not copied; they are stored
- * in the hash table by reference. If an entry with the
- * given key already exists, the previous key and value
- * are overwritten (and freed if the hash table has
- * a key_free_function and/or value_free_function).
- *
- * Returns #FALSE if memory for the new hash entry
- * can't be allocated.
- * 
- * @param table the hash table.
- * @param key the hash entry key.
- * @param value the hash entry value.
- */
-dbus_bool_t
-_dbus_hash_table_insert_string (DBusHashTable *table,
-                                char          *key,
-                                void          *value)
-{
-  DBusPreallocatedHash *preallocated;
-
-  _dbus_assert (table->key_type == DBUS_HASH_STRING);
-
-  preallocated = _dbus_hash_table_preallocate_entry (table);
-  if (preallocated == NULL)
-    return FALSE;
-
-  _dbus_hash_table_insert_string_preallocated (table, preallocated,
-                                               key, value);
-  
-  return TRUE;
-}
-
-#ifdef DBUS_BUILD_TESTS
-/**
- * Creates a hash entry with the given key and value.
- * The key and value are not copied; they are stored
- * in the hash table by reference. If an entry with the
- * given key already exists, the previous key and value
- * are overwritten (and freed if the hash table has
- * a key_free_function and/or value_free_function).
- *
- * Returns #FALSE if memory for the new hash entry
- * can't be allocated.
- * 
- * @param table the hash table.
- * @param key the hash entry key.
- * @param value the hash entry value.
- */
-dbus_bool_t
-_dbus_hash_table_insert_two_strings (DBusHashTable *table,
-                                     char          *key,
-                                     void          *value)
-{
-  DBusHashEntry *entry;
-  
-  _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
-  
-  entry = (* table->find_function) (table, key, TRUE, NULL, NULL);
-
-  if (entry == NULL)
-    return FALSE; /* no memory */
-
-  if (table->free_key_function && entry->key != key)
-    (* table->free_key_function) (entry->key);
-  
-  if (table->free_value_function && entry->value != value)
-    (* table->free_value_function) (entry->value);
-  
-  entry->key = key;
-  entry->value = value;
-
-  return TRUE;
-}
-#endif /* DBUS_BUILD_TESTS */
-
-/**
- * Creates a hash entry with the given key and value.
- * The key and value are not copied; they are stored
- * in the hash table by reference. If an entry with the
- * given key already exists, the previous key and value
- * are overwritten (and freed if the hash table has
- * a key_free_function and/or value_free_function).
- *
- * Returns #FALSE if memory for the new hash entry
- * can't be allocated.
- * 
- * @param table the hash table.
- * @param key the hash entry key.
- * @param value the hash entry value.
- */
-dbus_bool_t
-_dbus_hash_table_insert_int (DBusHashTable *table,
-                             int            key,
-                             void          *value)
-{
-  DBusHashEntry *entry;
-
-  _dbus_assert (table->key_type == DBUS_HASH_INT);
-  
-  entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), TRUE, NULL, NULL);
-
-  if (entry == NULL)
-    return FALSE; /* no memory */
-
-  if (table->free_key_function && entry->key != _DBUS_INT_TO_POINTER (key))
-    (* table->free_key_function) (entry->key);
-  
-  if (table->free_value_function && entry->value != value)
-    (* table->free_value_function) (entry->value);
-  
-  entry->key = _DBUS_INT_TO_POINTER (key);
-  entry->value = value;
-
-  return TRUE;
-}
-
-#ifdef DBUS_BUILD_TESTS
-/* disabled since it's only used for testing */
-/**
- * Creates a hash entry with the given key and value.
- * The key and value are not copied; they are stored
- * in the hash table by reference. If an entry with the
- * given key already exists, the previous key and value
- * are overwritten (and freed if the hash table has
- * a key_free_function and/or value_free_function).
- *
- * Returns #FALSE if memory for the new hash entry
- * can't be allocated.
- * 
- * @param table the hash table.
- * @param key the hash entry key.
- * @param value the hash entry value.
- */
-dbus_bool_t
-_dbus_hash_table_insert_pointer (DBusHashTable *table,
-                                 void          *key,
-                                 void          *value)
-{
-  DBusHashEntry *entry;
-
-  _dbus_assert (table->key_type == DBUS_HASH_POINTER);
-  
-  entry = (* table->find_function) (table, key, TRUE, NULL, NULL);
-
-  if (entry == NULL)
-    return FALSE; /* no memory */
-
-  if (table->free_key_function && entry->key != key)
-    (* table->free_key_function) (entry->key);
-  
-  if (table->free_value_function && entry->value != value)
-    (* table->free_value_function) (entry->value);
-  
-  entry->key = key;
-  entry->value = value;
-
-  return TRUE;
-}
-#endif /* DBUS_BUILD_TESTS */
-
-/**
- * Creates a hash entry with the given key and value.
- * The key and value are not copied; they are stored
- * in the hash table by reference. If an entry with the
- * given key already exists, the previous key and value
- * are overwritten (and freed if the hash table has
- * a key_free_function and/or value_free_function).
- *
- * Returns #FALSE if memory for the new hash entry
- * can't be allocated.
- * 
- * @param table the hash table.
- * @param key the hash entry key.
- * @param value the hash entry value.
- */
-dbus_bool_t
-_dbus_hash_table_insert_ulong (DBusHashTable *table,
-                               unsigned long  key,
-                               void          *value)
-{
-  DBusHashEntry *entry;
-
-  _dbus_assert (table->key_type == DBUS_HASH_ULONG);
-  
-  entry = (* table->find_function) (table, (void*) key, TRUE, NULL, NULL);
-
-  if (entry == NULL)
-    return FALSE; /* no memory */
-
-  if (table->free_key_function && entry->key != (void*) key)
-    (* table->free_key_function) (entry->key);
-  
-  if (table->free_value_function && entry->value != value)
-    (* table->free_value_function) (entry->value);
-  
-  entry->key = (void*) key;
-  entry->value = value;
-
-  return TRUE;
-}
-
-/**
- * Preallocate an opaque data blob that allows us to insert into the
- * hash table at a later time without allocating any memory.
- *
- * @param table the hash table
- * @returns the preallocated data, or #NULL if no memory
- */
-DBusPreallocatedHash*
-_dbus_hash_table_preallocate_entry (DBusHashTable *table)
-{
-  DBusHashEntry *entry;
-  
-  entry = alloc_entry (table);
-
-  return (DBusPreallocatedHash*) entry;
-}
-
-/**
- * Frees an opaque DBusPreallocatedHash that was *not* used
- * in order to insert into the hash table.
- *
- * @param table the hash table
- * @param preallocated the preallocated data
- */
-void
-_dbus_hash_table_free_preallocated_entry (DBusHashTable        *table,
-                                          DBusPreallocatedHash *preallocated)
-{
-  DBusHashEntry *entry;
-
-  _dbus_assert (preallocated != NULL);
-  
-  entry = (DBusHashEntry*) preallocated;
-  
-  /* Don't use free_entry(), since this entry has no key/data */
-  _dbus_mem_pool_dealloc (table->entry_pool, entry);
-}
-
-/**
- * Inserts a string-keyed entry into the hash table, using a
- * preallocated data block from
- * _dbus_hash_table_preallocate_entry(). This function cannot fail due
- * to lack of memory. The DBusPreallocatedHash object is consumed and
- * should not be reused or freed. Otherwise this function works
- * just like _dbus_hash_table_insert_string().
- *
- * @param table the hash table
- * @param preallocated the preallocated data
- * @param key the hash key
- * @param value the value 
- */
-void
-_dbus_hash_table_insert_string_preallocated (DBusHashTable        *table,
-                                             DBusPreallocatedHash *preallocated,
-                                             char                 *key,
-                                             void                 *value)
-{
-  DBusHashEntry *entry;
-
-  _dbus_assert (table->key_type == DBUS_HASH_STRING);
-  _dbus_assert (preallocated != NULL);
-  
-  entry = (* table->find_function) (table, key, TRUE, NULL, preallocated);
-
-  _dbus_assert (entry != NULL);
-  
-  if (table->free_key_function && entry->key != key)
-    (* table->free_key_function) (entry->key);
-
-  if (table->free_value_function && entry->value != value)
-    (* table->free_value_function) (entry->value);
-      
-  entry->key = key;
-  entry->value = value;
-}
-
-/**
- * Gets the number of hash entries in a hash table.
- *
- * @param table the hash table.
- * @returns the number of entries in the table.
- */
-int
-_dbus_hash_table_get_n_entries (DBusHashTable *table)
-{
-  return table->n_entries;
-}
-
-/** @} */
-
-#ifdef DBUS_BUILD_TESTS
-#include "dbus-test.h"
-#include <stdio.h>
-
-/* If you're wondering why the hash table test takes
- * forever to run, it's because we call this function
- * in inner loops thus making things quadratic.
- */
-static int
-count_entries (DBusHashTable *table)
-{
-  DBusHashIter iter;
-  int count;
-
-  count = 0;
-  _dbus_hash_iter_init (table, &iter);
-  while (_dbus_hash_iter_next (&iter))
-    ++count;
-
-  _dbus_assert (count == _dbus_hash_table_get_n_entries (table));
-  
-  return count;
-}
-
-/* Copy the foo\0bar\0 double string thing */
-static char*
-_dbus_strdup2 (const char *str)
-{
-  size_t len;
-  char *copy;
-  
-  if (str == NULL)
-    return NULL;
-  
-  len = strlen (str);
-  len += strlen ((str + len + 1));
-
-  copy = dbus_malloc (len + 2);
-  if (copy == NULL)
-    return NULL;
-
-  memcpy (copy, str, len + 2);
-  
-  return copy;
-}
-
-/**
- * @ingroup DBusHashTableInternals
- * Unit test for DBusHashTable
- * @returns #TRUE on success.
- */
-dbus_bool_t
-_dbus_hash_test (void)
-{
-  int i;
-  DBusHashTable *table1;
-  DBusHashTable *table2;
-  DBusHashTable *table3;
-  DBusHashTable *table4;
-  DBusHashIter iter;
-#define N_HASH_KEYS 5000
-  char **keys;
-  dbus_bool_t ret = FALSE;
-
-  keys = dbus_new (char *, N_HASH_KEYS);
-  if (keys == NULL)
-    _dbus_assert_not_reached ("no memory");
-
-  for (i = 0; i < N_HASH_KEYS; i++)
-    {
-      keys[i] = dbus_malloc (128);
-
-      if (keys[i] == NULL)
-       _dbus_assert_not_reached ("no memory");
-    }
-
-  printf ("Computing test hash keys...\n");
-  i = 0;
-  while (i < N_HASH_KEYS)
-    {
-      int len;
-
-      /* all the hash keys are TWO_STRINGS, but
-       * then we can also use those as regular strings.
-       */
-      
-      len = sprintf (keys[i], "Hash key %d", i);
-      sprintf (keys[i] + len + 1, "Two string %d", i);
-      _dbus_assert (*(keys[i] + len) == '\0');
-      _dbus_assert (*(keys[i] + len + 1) != '\0');
-      ++i;
-    }
-  printf ("... done.\n");
-  
-  table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
-                                 dbus_free, dbus_free);
-  if (table1 == NULL)
-    goto out;
-
-  table2 = _dbus_hash_table_new (DBUS_HASH_INT,
-                                 NULL, dbus_free);
-  if (table2 == NULL)
-    goto out;
-
-  table3 = _dbus_hash_table_new (DBUS_HASH_ULONG,
-                                 NULL, dbus_free);
-  if (table3 == NULL)
-    goto out;
-
-  table4 = _dbus_hash_table_new (DBUS_HASH_TWO_STRINGS,
-                                 dbus_free, dbus_free);
-  if (table4 == NULL)
-    goto out;
-
-  
-  /* Insert and remove a bunch of stuff, counting the table in between
-   * to be sure it's not broken and that iteration works
-   */
-  i = 0;
-  while (i < 3000)
-    {
-      void *value;
-      char *key;
-
-      key = _dbus_strdup (keys[i]);
-      if (key == NULL)
-        goto out;
-      value = _dbus_strdup ("Value!");
-      if (value == NULL)
-        goto out;
-      
-      if (!_dbus_hash_table_insert_string (table1,
-                                           key, value))
-        goto out;
-
-      value = _dbus_strdup (keys[i]);
-      if (value == NULL)
-        goto out;
-      
-      if (!_dbus_hash_table_insert_int (table2,
-                                        i, value))
-        goto out;
-
-      value = _dbus_strdup (keys[i]);
-      if (value == NULL)
-        goto out;
-      
-      if (!_dbus_hash_table_insert_ulong (table3,
-                                          i, value))
-        goto out;
-
-      key = _dbus_strdup2 (keys[i]);
-      if (key == NULL)
-        goto out;
-      value = _dbus_strdup ("Value!");
-      if (value == NULL)
-        goto out;
-      
-      if (!_dbus_hash_table_insert_two_strings (table4,
-                                                key, value))
-        goto out;
-      
-      _dbus_assert (count_entries (table1) == i + 1);
-      _dbus_assert (count_entries (table2) == i + 1);
-      _dbus_assert (count_entries (table3) == i + 1);
-      _dbus_assert (count_entries (table4) == i + 1);
-
-      value = _dbus_hash_table_lookup_string (table1, keys[i]);
-      _dbus_assert (value != NULL);
-      _dbus_assert (strcmp (value, "Value!") == 0);
-
-      value = _dbus_hash_table_lookup_int (table2, i);
-      _dbus_assert (value != NULL);
-      _dbus_assert (strcmp (value, keys[i]) == 0);
-
-      value = _dbus_hash_table_lookup_ulong (table3, i);
-      _dbus_assert (value != NULL);
-      _dbus_assert (strcmp (value, keys[i]) == 0);
-
-      value = _dbus_hash_table_lookup_two_strings (table4, keys[i]);
-      _dbus_assert (value != NULL);
-      _dbus_assert (strcmp (value, "Value!") == 0);
-      
-      ++i;
-    }
-
-  --i;
-  while (i >= 0)
-    {
-      _dbus_hash_table_remove_string (table1,
-                                      keys[i]);
-
-      _dbus_hash_table_remove_int (table2, i);
-
-      _dbus_hash_table_remove_ulong (table3, i); 
-
-      _dbus_hash_table_remove_two_strings (table4,
-                                           keys[i]);
-      
-      _dbus_assert (count_entries (table1) == i);
-      _dbus_assert (count_entries (table2) == i);
-      _dbus_assert (count_entries (table3) == i);
-      _dbus_assert (count_entries (table4) == i);
-
-      --i;
-    }
-
-  _dbus_hash_table_ref (table1);
-  _dbus_hash_table_ref (table2);
-  _dbus_hash_table_ref (table3);
-  _dbus_hash_table_ref (table4);
-  _dbus_hash_table_unref (table1);
-  _dbus_hash_table_unref (table2);
-  _dbus_hash_table_unref (table3);
-  _dbus_hash_table_unref (table4);
-  _dbus_hash_table_unref (table1);
-  _dbus_hash_table_unref (table2);
-  _dbus_hash_table_unref (table3);
-  _dbus_hash_table_unref (table4);
-  table3 = NULL;
-
-  /* Insert a bunch of stuff then check
-   * that iteration works correctly (finds the right
-   * values, iter_set_value works, etc.)
-   */
-  table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
-                                 dbus_free, dbus_free);
-  if (table1 == NULL)
-    goto out;
-  
-  table2 = _dbus_hash_table_new (DBUS_HASH_INT,
-                                 NULL, dbus_free);
-  if (table2 == NULL)
-    goto out;
-  
-  i = 0;
-  while (i < 5000)
-    {
-      char *key;
-      void *value;      
-      
-      key = _dbus_strdup (keys[i]);
-      if (key == NULL)
-        goto out;
-      value = _dbus_strdup ("Value!");
-      if (value == NULL)
-        goto out;
-      
-      if (!_dbus_hash_table_insert_string (table1,
-                                           key, value))
-        goto out;
-
-      value = _dbus_strdup (keys[i]);
-      if (value == NULL)
-        goto out;
-      
-      if (!_dbus_hash_table_insert_int (table2,
-                                        i, value))
-        goto out;
-      
-      _dbus_assert (count_entries (table1) == i + 1);
-      _dbus_assert (count_entries (table2) == i + 1);
-      
-      ++i;
-    }
-
-  _dbus_hash_iter_init (table1, &iter);
-  while (_dbus_hash_iter_next (&iter))
-    {
-      const char *key;
-      void *value;
-
-      key = _dbus_hash_iter_get_string_key (&iter);
-      value = _dbus_hash_iter_get_value (&iter);
-
-      _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
-
-      value = _dbus_strdup ("Different value!");
-      if (value == NULL)
-        goto out;
-      
-      _dbus_hash_iter_set_value (&iter, value);
-
-      _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
-    }
-  
-  _dbus_hash_iter_init (table1, &iter);
-  while (_dbus_hash_iter_next (&iter))
-    {
-      _dbus_hash_iter_remove_entry (&iter);
-      _dbus_assert (count_entries (table1) == i - 1);
-      --i;
-    }
-
-  _dbus_hash_iter_init (table2, &iter);
-  while (_dbus_hash_iter_next (&iter))
-    {
-      int key;
-      void *value;
-
-      key = _dbus_hash_iter_get_int_key (&iter);
-      value = _dbus_hash_iter_get_value (&iter);
-
-      _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
-
-      value = _dbus_strdup ("Different value!");
-      if (value == NULL)
-        goto out;
-      
-      _dbus_hash_iter_set_value (&iter, value);
-
-      _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
-    }
-
-  i = count_entries (table2);
-  _dbus_hash_iter_init (table2, &iter);
-  while (_dbus_hash_iter_next (&iter))
-    {
-      _dbus_hash_iter_remove_entry (&iter);
-      _dbus_assert (count_entries (table2) + 1 == i);
-      --i;
-    }
-
-  /* add/remove interleaved, to check that we grow/shrink the table
-   * appropriately
-   */
-  i = 0;
-  while (i < 1000)
-    {
-      char *key;
-      void *value;
-            
-      key = _dbus_strdup (keys[i]);
-      if (key == NULL)
-        goto out;
-
-      value = _dbus_strdup ("Value!");
-      if (value == NULL)
-        goto out;
-      
-      if (!_dbus_hash_table_insert_string (table1,
-                                           key, value))
-        goto out;
-      
-      ++i;
-    }
-
-  --i;
-  while (i >= 0)
-    {
-      char *key;
-      void *value;      
-      
-      key = _dbus_strdup (keys[i]);
-      if (key == NULL)
-        goto out;
-      value = _dbus_strdup ("Value!");
-      if (value == NULL)
-        goto out;
-
-      if (!_dbus_hash_table_remove_string (table1, keys[i]))
-        goto out;
-      
-      if (!_dbus_hash_table_insert_string (table1,
-                                           key, value))
-        goto out;
-
-      if (!_dbus_hash_table_remove_string (table1, keys[i]))
-        goto out;
-      
-      _dbus_assert (_dbus_hash_table_get_n_entries (table1) == i);
-      
-      --i;
-    }
-
-  /* nuke these tables */
-  _dbus_hash_table_unref (table1);
-  _dbus_hash_table_unref (table2);
-
-
-  /* Now do a bunch of things again using _dbus_hash_iter_lookup() to
-   * be sure that interface works.
-   */
-  table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
-                                 dbus_free, dbus_free);
-  if (table1 == NULL)
-    goto out;
-  
-  table2 = _dbus_hash_table_new (DBUS_HASH_INT,
-                                 NULL, dbus_free);
-  if (table2 == NULL)
-    goto out;
-  
-  i = 0;
-  while (i < 3000)
-    {
-      void *value;
-      char *key;
-
-      key = _dbus_strdup (keys[i]);
-      if (key == NULL)
-        goto out;
-      value = _dbus_strdup ("Value!");
-      if (value == NULL)
-        goto out;
-      
-      if (!_dbus_hash_iter_lookup (table1,
-                                   key, TRUE, &iter))
-        goto out;
-      _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
-      _dbus_hash_iter_set_value (&iter, value);
-
-      value = _dbus_strdup (keys[i]);
-      if (value == NULL)
-        goto out;
-
-      if (!_dbus_hash_iter_lookup (table2,
-                                   _DBUS_INT_TO_POINTER (i), TRUE, &iter))
-        goto out;
-      _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
-      _dbus_hash_iter_set_value (&iter, value); 
-      
-      _dbus_assert (count_entries (table1) == i + 1);
-      _dbus_assert (count_entries (table2) == i + 1);
-
-      if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
-        goto out;
-      
-      value = _dbus_hash_iter_get_value (&iter);
-      _dbus_assert (value != NULL);
-      _dbus_assert (strcmp (value, "Value!") == 0);
-
-      /* Iterate just to be sure it works, though
-       * it's a stupid thing to do
-       */
-      while (_dbus_hash_iter_next (&iter))
-        ;
-      
-      if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
-        goto out;
-
-      value = _dbus_hash_iter_get_value (&iter);
-      _dbus_assert (value != NULL);
-      _dbus_assert (strcmp (value, keys[i]) == 0);
-
-      /* Iterate just to be sure it works, though
-       * it's a stupid thing to do
-       */
-      while (_dbus_hash_iter_next (&iter))
-        ;
-      
-      ++i;
-    }
-
-  --i;
-  while (i >= 0)
-    {
-      if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
-        _dbus_assert_not_reached ("hash entry should have existed");
-      _dbus_hash_iter_remove_entry (&iter);
-      
-      if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
-        _dbus_assert_not_reached ("hash entry should have existed");
-      _dbus_hash_iter_remove_entry (&iter);
-
-      _dbus_assert (count_entries (table1) == i);
-      _dbus_assert (count_entries (table2) == i);
-
-      --i;
-    }
-
-  _dbus_hash_table_unref (table1);
-  _dbus_hash_table_unref (table2);
-
-  ret = TRUE;
-
- out:
-  for (i = 0; i < N_HASH_KEYS; i++)
-    dbus_free (keys[i]);
-
-  dbus_free (keys);
-  
-  return ret;
-}
-
-#endif /* DBUS_BUILD_TESTS */