1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-hash.c Generic hash table utility (internal to D-Bus implementation)
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.
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.
13 * Licensed under the Academic Free License version 2.1
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.
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.
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
31 * The following copyright applies to code from the Tcl distribution.
33 * Copyright (c) 1991-1993 The Regents of the University of California.
34 * Copyright (c) 1994 Sun Microsystems, Inc.
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.
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.
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.
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.
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.
78 #include "dbus-hash.h"
79 #include "dbus-internals.h"
80 #include "dbus-mempool.h"
83 * @defgroup DBusHashTable Hash table
84 * @ingroup DBusInternals
85 * @brief DBusHashTable data structure
87 * Types and functions related to DBusHashTable.
91 * @defgroup DBusHashTableInternals Hash table implementation details
92 * @ingroup DBusInternals
93 * @brief DBusHashTable implementation details
95 * The guts of DBusHashTable.
101 * When there are this many entries per bucket, on average, rebuild
102 * the hash table to make it larger.
104 #define REBUILD_MULTIPLIER 3
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.)
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?
122 #define RANDOM_INDEX(table, i) \
123 (((((intptr_t) (i))*1103515245) >> (table)->down_shift) & (table)->mask)
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.
130 #define DBUS_SMALL_HASH_TABLE 4
133 * Typedef for DBusHashEntry
135 typedef struct DBusHashEntry DBusHashEntry;
138 * @brief Internal representation of a hash entry.
140 * A single entry (key-value pair) in the hash table.
141 * Internal to hash table implementation.
145 DBusHashEntry *next; /**< Pointer to next entry in this
146 * hash bucket, or #NULL for end of
149 void *key; /**< Hash key */
150 void *value; /**< Hash value */
154 * Function used to find and optionally create a hash entry.
156 typedef DBusHashEntry* (* DBusFindEntryFunction) (DBusHashTable *table,
158 dbus_bool_t create_if_not_found,
159 DBusHashEntry ***bucket,
160 DBusPreallocatedHash *preallocated);
163 * @brief Internals of DBusHashTable.
165 * Hash table internals. Hash tables are opaque objects, they must be
166 * used via accessor functions.
168 struct DBusHashTable {
169 int refcount; /**< Reference count */
171 DBusHashEntry **buckets; /**< Pointer to bucket array. Each
172 * element points to first entry in
173 * bucket's hash chain, or #NULL.
175 DBusHashEntry *static_buckets[DBUS_SMALL_HASH_TABLE];
176 /**< Bucket array used for small tables
177 * (to avoid mallocs and frees).
179 int n_buckets; /**< Total number of buckets allocated
182 int n_entries; /**< Total number of entries present
185 int hi_rebuild_size; /**< Enlarge table when n_entries gets
188 int lo_rebuild_size; /**< Shrink table when n_entries gets
191 int down_shift; /**< Shift count used in hashing
192 * function. Designed to use high-
193 * order bits of randomized keys.
195 int mask; /**< Mask value used in hashing
198 DBusHashType key_type; /**< Type of keys used in this table */
201 DBusFindEntryFunction find_function; /**< Function for finding entries */
203 DBusFreeFunction free_key_function; /**< Function to free keys */
204 DBusFreeFunction free_value_function; /**< Function to free values */
206 DBusMemPool *entry_pool; /**< Memory pool for hash entries */
210 * @brief Internals of DBusHashIter.
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.
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 */
225 _DBUS_STATIC_ASSERT (sizeof (DBusRealHashIter) == sizeof (DBusHashIter));
227 static DBusHashEntry* find_direct_function (DBusHashTable *table,
229 dbus_bool_t create_if_not_found,
230 DBusHashEntry ***bucket,
231 DBusPreallocatedHash *preallocated);
232 static DBusHashEntry* find_string_function (DBusHashTable *table,
234 dbus_bool_t create_if_not_found,
235 DBusHashEntry ***bucket,
236 DBusPreallocatedHash *preallocated);
237 static unsigned int string_hash (const char *str);
238 static void rebuild_table (DBusHashTable *table);
239 static DBusHashEntry* alloc_entry (DBusHashTable *table);
240 static void remove_entry (DBusHashTable *table,
241 DBusHashEntry **bucket,
242 DBusHashEntry *entry);
243 static void free_entry (DBusHashTable *table,
244 DBusHashEntry *entry);
245 static void free_entry_data (DBusHashTable *table,
246 DBusHashEntry *entry);
252 * @addtogroup DBusHashTable
257 * @typedef DBusHashIter
259 * Public opaque hash table iterator object.
263 * @typedef DBusHashTable
265 * Public opaque hash table object.
269 * @typedef DBusHashType
271 * Indicates the type of a key in the hash table.
275 * Constructs a new hash table. Should be freed with
276 * _dbus_hash_table_unref(). If memory cannot be
277 * allocated for the hash table, returns #NULL.
279 * @param type the type of hash key to use.
280 * @param key_free_function function to free hash keys.
281 * @param value_free_function function to free hash values.
282 * @returns a new DBusHashTable or #NULL if no memory.
285 _dbus_hash_table_new (DBusHashType type,
286 DBusFreeFunction key_free_function,
287 DBusFreeFunction value_free_function)
289 DBusHashTable *table;
290 DBusMemPool *entry_pool;
292 table = dbus_new0 (DBusHashTable, 1);
296 entry_pool = _dbus_mem_pool_new (sizeof (DBusHashEntry), TRUE);
297 if (entry_pool == NULL)
304 table->entry_pool = entry_pool;
306 _dbus_assert (DBUS_SMALL_HASH_TABLE == _DBUS_N_ELEMENTS (table->static_buckets));
308 table->buckets = table->static_buckets;
309 table->n_buckets = DBUS_SMALL_HASH_TABLE;
310 table->n_entries = 0;
311 table->hi_rebuild_size = DBUS_SMALL_HASH_TABLE * REBUILD_MULTIPLIER;
312 table->lo_rebuild_size = 0;
313 table->down_shift = 28;
315 table->key_type = type;
317 _dbus_assert (table->mask < table->n_buckets);
319 switch (table->key_type)
322 case DBUS_HASH_UINTPTR:
323 table->find_function = find_direct_function;
325 case DBUS_HASH_STRING:
326 table->find_function = find_string_function;
329 _dbus_assert_not_reached ("Unknown hash table type");
333 table->free_key_function = key_free_function;
334 table->free_value_function = value_free_function;
341 * Increments the reference count for a hash table.
343 * @param table the hash table to add a reference to.
344 * @returns the hash table.
347 _dbus_hash_table_ref (DBusHashTable *table)
349 table->refcount += 1;
355 * Decrements the reference count for a hash table,
356 * freeing the hash table if the count reaches zero.
358 * @param table the hash table to remove a reference from.
361 _dbus_hash_table_unref (DBusHashTable *table)
363 table->refcount -= 1;
365 if (table->refcount == 0)
368 DBusHashEntry *entry;
372 /* Free the entries in the table. */
373 for (i = 0; i < table->n_buckets; i++)
375 entry = table->buckets[i];
376 while (entry != NULL)
380 free_entry (table, entry);
386 DBusHashEntry *entry;
389 /* Free the entries in the table. */
390 for (i = 0; i < table->n_buckets; i++)
392 entry = table->buckets[i];
393 while (entry != NULL)
395 free_entry_data (table, entry);
400 /* We can do this very quickly with memory pools ;-) */
401 _dbus_mem_pool_free (table->entry_pool);
404 /* Free the bucket array, if it was dynamically allocated. */
405 if (table->buckets != table->static_buckets)
406 dbus_free (table->buckets);
413 * Removed all entries from a hash table.
415 * @param table the hash table to remove all entries from.
418 _dbus_hash_table_remove_all (DBusHashTable *table)
421 _dbus_hash_iter_init (table, &iter);
422 while (_dbus_hash_iter_next (&iter))
424 _dbus_hash_iter_remove_entry(&iter);
428 static DBusHashEntry*
429 alloc_entry (DBusHashTable *table)
431 DBusHashEntry *entry;
433 entry = _dbus_mem_pool_alloc (table->entry_pool);
439 free_entry_data (DBusHashTable *table,
440 DBusHashEntry *entry)
442 if (table->free_key_function)
443 (* table->free_key_function) (entry->key);
444 if (table->free_value_function)
445 (* table->free_value_function) (entry->value);
449 free_entry (DBusHashTable *table,
450 DBusHashEntry *entry)
452 free_entry_data (table, entry);
453 _dbus_mem_pool_dealloc (table->entry_pool, entry);
457 remove_entry (DBusHashTable *table,
458 DBusHashEntry **bucket,
459 DBusHashEntry *entry)
461 _dbus_assert (table != NULL);
462 _dbus_assert (bucket != NULL);
463 _dbus_assert (*bucket != NULL);
464 _dbus_assert (entry != NULL);
466 if (*bucket == entry)
467 *bucket = entry->next;
473 while (prev->next != entry)
476 _dbus_assert (prev != NULL);
478 prev->next = entry->next;
481 table->n_entries -= 1;
482 free_entry (table, entry);
486 * Initializes a hash table iterator. To iterate over all entries in a
487 * hash table, use the following code (the printf assumes a hash
488 * from strings to strings obviously):
493 * _dbus_hash_iter_init (table, &iter);
494 * while (_dbus_hash_iter_next (&iter))
496 * printf ("The first key is %s and value is %s\n",
497 * _dbus_hash_iter_get_string_key (&iter),
498 * _dbus_hash_iter_get_value (&iter));
504 * The iterator is initialized pointing "one before" the first hash
505 * entry. The first call to _dbus_hash_iter_next() moves it onto
506 * the first valid entry or returns #FALSE if the hash table is
507 * empty. Subsequent calls move to the next valid entry or return
508 * #FALSE if there are no more entries.
510 * Note that it is guaranteed to be safe to remove a hash entry during
511 * iteration, but it is not safe to add a hash entry.
513 * @param table the hash table to iterate over.
514 * @param iter the iterator to initialize.
517 _dbus_hash_iter_init (DBusHashTable *table,
520 DBusRealHashIter *real;
522 _DBUS_STATIC_ASSERT (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
524 real = (DBusRealHashIter*) iter;
529 real->next_entry = NULL;
530 real->next_bucket = 0;
531 real->n_entries_on_init = table->n_entries;
535 * Move the hash iterator forward one step, to the next hash entry.
536 * The documentation for _dbus_hash_iter_init() explains in more
539 * @param iter the iterator to move forward.
540 * @returns #FALSE if there are no more entries to move to.
543 _dbus_hash_iter_next (DBusHashIter *iter)
545 DBusRealHashIter *real;
547 _DBUS_STATIC_ASSERT (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
549 real = (DBusRealHashIter*) iter;
551 /* if this assertion failed someone probably added hash entries
552 * during iteration, which is bad.
554 _dbus_assert (real->n_entries_on_init >= real->table->n_entries);
556 /* Remember that real->entry may have been deleted */
558 while (real->next_entry == NULL)
560 if (real->next_bucket >= real->table->n_buckets)
562 /* invalidate iter and return false */
569 real->bucket = &(real->table->buckets[real->next_bucket]);
570 real->next_entry = *(real->bucket);
571 real->next_bucket += 1;
574 _dbus_assert (real->next_entry != NULL);
575 _dbus_assert (real->bucket != NULL);
577 real->entry = real->next_entry;
578 real->next_entry = real->entry->next;
584 * Removes the current entry from the hash table.
585 * If a key_free_function or value_free_function
586 * was provided to _dbus_hash_table_new(),
587 * frees the key and/or value for this entry.
589 * @param iter the hash table iterator.
592 _dbus_hash_iter_remove_entry (DBusHashIter *iter)
594 DBusRealHashIter *real;
596 real = (DBusRealHashIter*) iter;
598 _dbus_assert (real->table != NULL);
599 _dbus_assert (real->entry != NULL);
600 _dbus_assert (real->bucket != NULL);
602 remove_entry (real->table, real->bucket, real->entry);
604 real->entry = NULL; /* make it crash if you try to use this entry */
608 * Gets the value of the current entry.
610 * @param iter the hash table iterator.
613 _dbus_hash_iter_get_value (DBusHashIter *iter)
615 DBusRealHashIter *real;
617 real = (DBusRealHashIter*) iter;
619 _dbus_assert (real->table != NULL);
620 _dbus_assert (real->entry != NULL);
622 return real->entry->value;
626 * Sets the value of the current entry.
627 * If the hash table has a value_free_function
628 * it will be used to free the previous value.
629 * The hash table will own the passed-in value
630 * (it will not be copied).
632 * @param iter the hash table iterator.
633 * @param value the new value.
636 _dbus_hash_iter_set_value (DBusHashIter *iter,
639 DBusRealHashIter *real;
641 real = (DBusRealHashIter*) iter;
643 _dbus_assert (real->table != NULL);
644 _dbus_assert (real->entry != NULL);
646 if (real->table->free_value_function && value != real->entry->value)
647 (* real->table->free_value_function) (real->entry->value);
649 real->entry->value = value;
653 * Gets the key for the current entry.
654 * Only works for hash tables of type #DBUS_HASH_INT.
656 * @param iter the hash table iterator.
659 _dbus_hash_iter_get_int_key (DBusHashIter *iter)
661 DBusRealHashIter *real;
663 real = (DBusRealHashIter*) iter;
665 _dbus_assert (real->table != NULL);
666 _dbus_assert (real->entry != NULL);
668 return _DBUS_POINTER_TO_INT (real->entry->key);
672 * Gets the key for the current entry.
673 * Only works for hash tables of type #DBUS_HASH_UINTPTR.
675 * @param iter the hash table iterator.
678 _dbus_hash_iter_get_uintptr_key (DBusHashIter *iter)
680 DBusRealHashIter *real;
682 real = (DBusRealHashIter*) iter;
684 _dbus_assert (real->table != NULL);
685 _dbus_assert (real->entry != NULL);
687 return (uintptr_t) real->entry->key;
691 * Gets the key for the current entry.
692 * Only works for hash tables of type #DBUS_HASH_STRING
693 * @param iter the hash table iterator.
696 _dbus_hash_iter_get_string_key (DBusHashIter *iter)
698 DBusRealHashIter *real;
700 real = (DBusRealHashIter*) iter;
702 _dbus_assert (real->table != NULL);
703 _dbus_assert (real->entry != NULL);
705 return real->entry->key;
709 * A low-level but efficient interface for manipulating the hash
710 * table. It's efficient because you can get, set, and optionally
711 * create the hash entry while only running the hash function one
714 * Note that while calling _dbus_hash_iter_next() on the iterator
715 * filled in by this function may work, it's completely
716 * undefined which entries are after this iter and which
717 * are before it. So it would be silly to iterate using this
720 * If the hash entry is created, its value will be initialized
723 * #FALSE may be returned due to memory allocation failure, or
724 * because create_if_not_found was #FALSE and the entry
727 * If create_if_not_found is #TRUE, the hash
728 * table takes ownership of the key that's passed in (either using it to create
729 * the entry, or freeing it immediately).
731 * For a hash table of type #DBUS_HASH_INT, cast the int
732 * key to the key parameter using #_DBUS_INT_TO_POINTER().
734 * @param table the hash table.
735 * @param key the hash key.
736 * @param create_if_not_found if #TRUE, create the entry if it didn't exist.
737 * @param iter the iterator to initialize.
738 * @returns #TRUE if the hash entry now exists (and the iterator is thus valid).
741 _dbus_hash_iter_lookup (DBusHashTable *table,
743 dbus_bool_t create_if_not_found,
746 DBusRealHashIter *real;
747 DBusHashEntry *entry;
748 DBusHashEntry **bucket;
750 _DBUS_STATIC_ASSERT (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
752 real = (DBusRealHashIter*) iter;
754 entry = (* table->find_function) (table, key, create_if_not_found, &bucket, NULL);
759 if (create_if_not_found)
761 if (table->free_key_function && entry->key != key)
762 (* table->free_key_function) (entry->key);
768 real->bucket = bucket;
770 real->next_entry = entry->next;
771 real->next_bucket = (bucket - table->buckets) + 1;
772 real->n_entries_on_init = table->n_entries;
774 _dbus_assert (&(table->buckets[real->next_bucket-1]) == real->bucket);
780 add_allocated_entry (DBusHashTable *table,
781 DBusHashEntry *entry,
784 DBusHashEntry ***bucket)
790 b = &(table->buckets[idx]);
797 table->n_entries += 1;
799 /* note we ONLY rebuild when ADDING - because you can iterate over a
800 * table and remove entries safely.
802 if (table->n_entries >= table->hi_rebuild_size ||
803 table->n_entries < table->lo_rebuild_size)
804 rebuild_table (table);
807 static DBusHashEntry*
808 add_entry (DBusHashTable *table,
811 DBusHashEntry ***bucket,
812 DBusPreallocatedHash *preallocated)
814 DBusHashEntry *entry;
816 if (preallocated == NULL)
818 entry = alloc_entry (table);
828 entry = (DBusHashEntry*) preallocated;
831 add_allocated_entry (table, entry, idx, key, bucket);
836 /* This is g_str_hash from GLib which was
837 * extensively discussed/tested/profiled
840 string_hash (const char *str)
846 for (p += 1; *p != '\0'; p++)
847 h = (h << 5) - h + *p;
852 /** Key comparison function */
853 typedef int (* KeyCompareFunc) (const void *key_a, const void *key_b);
855 static DBusHashEntry*
856 find_generic_function (DBusHashTable *table,
859 KeyCompareFunc compare_func,
860 dbus_bool_t create_if_not_found,
861 DBusHashEntry ***bucket,
862 DBusPreallocatedHash *preallocated)
864 DBusHashEntry *entry;
869 /* Search all of the entries in this bucket. */
870 entry = table->buckets[idx];
871 while (entry != NULL)
873 if ((compare_func == NULL && key == entry->key) ||
874 (compare_func != NULL && (* compare_func) (key, entry->key) == 0))
877 *bucket = &(table->buckets[idx]);
880 _dbus_hash_table_free_preallocated_entry (table, preallocated);
888 if (create_if_not_found)
889 entry = add_entry (table, idx, key, bucket, preallocated);
890 else if (preallocated)
891 _dbus_hash_table_free_preallocated_entry (table, preallocated);
896 static DBusHashEntry*
897 find_string_function (DBusHashTable *table,
899 dbus_bool_t create_if_not_found,
900 DBusHashEntry ***bucket,
901 DBusPreallocatedHash *preallocated)
905 idx = string_hash (key) & table->mask;
907 return find_generic_function (table, key, idx,
908 (KeyCompareFunc) strcmp, create_if_not_found, bucket,
912 static DBusHashEntry*
913 find_direct_function (DBusHashTable *table,
915 dbus_bool_t create_if_not_found,
916 DBusHashEntry ***bucket,
917 DBusPreallocatedHash *preallocated)
921 idx = RANDOM_INDEX (table, key) & table->mask;
924 return find_generic_function (table, key, idx,
925 NULL, create_if_not_found, bucket,
930 rebuild_table (DBusHashTable *table)
934 DBusHashEntry **old_buckets;
935 DBusHashEntry **old_chain;
936 DBusHashEntry *entry;
940 * Allocate and initialize the new bucket array, and set up
941 * hashing constants for new array size.
944 growing = table->n_entries >= table->hi_rebuild_size;
946 old_size = table->n_buckets;
947 old_buckets = table->buckets;
951 /* overflow paranoia */
952 if (table->n_buckets < _DBUS_INT_MAX / 4 &&
953 table->down_shift >= 2)
954 new_buckets = table->n_buckets * 4;
956 return; /* can't grow anymore */
960 new_buckets = table->n_buckets / 4;
961 if (new_buckets < DBUS_SMALL_HASH_TABLE)
962 return; /* don't bother shrinking this far */
965 table->buckets = dbus_new0 (DBusHashEntry*, new_buckets);
966 if (table->buckets == NULL)
968 /* out of memory, yay - just don't reallocate, the table will
969 * still work, albeit more slowly.
971 table->buckets = old_buckets;
975 table->n_buckets = new_buckets;
979 table->lo_rebuild_size = table->hi_rebuild_size;
980 table->hi_rebuild_size *= 4;
982 table->down_shift -= 2; /* keep 2 more high bits */
983 table->mask = (table->mask << 2) + 3; /* keep 2 more high bits */
987 table->hi_rebuild_size = table->lo_rebuild_size;
988 table->lo_rebuild_size /= 4;
990 table->down_shift += 2; /* keep 2 fewer high bits */
991 table->mask = table->mask >> 2; /* keep 2 fewer high bits */
995 printf ("%s table to lo = %d hi = %d downshift = %d mask = 0x%x\n",
996 growing ? "GROW" : "SHRINK",
997 table->lo_rebuild_size,
998 table->hi_rebuild_size,
1003 _dbus_assert (table->lo_rebuild_size >= 0);
1004 _dbus_assert (table->hi_rebuild_size > table->lo_rebuild_size);
1005 _dbus_assert (table->down_shift >= 0);
1006 _dbus_assert (table->mask != 0);
1007 /* the mask is essentially the max index */
1008 _dbus_assert (table->mask < table->n_buckets);
1011 * Rehash all of the existing entries into the new bucket array.
1014 for (old_chain = old_buckets; old_size > 0; old_size--, old_chain++)
1016 for (entry = *old_chain; entry != NULL; entry = *old_chain)
1019 DBusHashEntry **bucket;
1021 *old_chain = entry->next;
1022 switch (table->key_type)
1024 case DBUS_HASH_STRING:
1025 idx = string_hash (entry->key) & table->mask;
1028 case DBUS_HASH_UINTPTR:
1029 idx = RANDOM_INDEX (table, entry->key);
1033 _dbus_assert_not_reached ("Unknown hash table type");
1037 bucket = &(table->buckets[idx]);
1038 entry->next = *bucket;
1043 /* Free the old bucket array, if it was dynamically allocated. */
1045 if (old_buckets != table->static_buckets)
1046 dbus_free (old_buckets);
1050 * Looks up the value for a given string in a hash table
1051 * of type #DBUS_HASH_STRING. Returns %NULL if the value
1052 * is not present. (A not-present entry is indistinguishable
1053 * from an entry with a value of %NULL.)
1054 * @param table the hash table.
1055 * @param key the string to look up.
1056 * @returns the value of the hash entry.
1059 _dbus_hash_table_lookup_string (DBusHashTable *table,
1062 DBusHashEntry *entry;
1064 _dbus_assert (table->key_type == DBUS_HASH_STRING);
1066 entry = (* table->find_function) (table, (char*) key, FALSE, NULL, NULL);
1069 return entry->value;
1075 * Looks up the value for a given integer in a hash table
1076 * of type #DBUS_HASH_INT. Returns %NULL if the value
1077 * is not present. (A not-present entry is indistinguishable
1078 * from an entry with a value of %NULL.)
1079 * @param table the hash table.
1080 * @param key the integer to look up.
1081 * @returns the value of the hash entry.
1084 _dbus_hash_table_lookup_int (DBusHashTable *table,
1087 DBusHashEntry *entry;
1089 _dbus_assert (table->key_type == DBUS_HASH_INT);
1091 entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, NULL, NULL);
1094 return entry->value;
1100 * Looks up the value for a given integer in a hash table
1101 * of type #DBUS_HASH_UINTPTR. Returns %NULL if the value
1102 * is not present. (A not-present entry is indistinguishable
1103 * from an entry with a value of %NULL.)
1104 * @param table the hash table.
1105 * @param key the integer to look up.
1106 * @returns the value of the hash entry.
1109 _dbus_hash_table_lookup_uintptr (DBusHashTable *table,
1112 DBusHashEntry *entry;
1114 _dbus_assert (table->key_type == DBUS_HASH_UINTPTR);
1116 entry = (* table->find_function) (table, (void*) key, FALSE, NULL, NULL);
1119 return entry->value;
1125 * Removes the hash entry for the given key. If no hash entry
1126 * for the key exists, does nothing.
1128 * @param table the hash table.
1129 * @param key the hash key.
1130 * @returns #TRUE if the entry existed
1133 _dbus_hash_table_remove_string (DBusHashTable *table,
1136 DBusHashEntry *entry;
1137 DBusHashEntry **bucket;
1139 _dbus_assert (table->key_type == DBUS_HASH_STRING);
1141 entry = (* table->find_function) (table, (char*) key, FALSE, &bucket, NULL);
1145 remove_entry (table, bucket, entry);
1153 * Removes the hash entry for the given key. If no hash entry
1154 * for the key exists, does nothing.
1156 * @param table the hash table.
1157 * @param key the hash key.
1158 * @returns #TRUE if the entry existed
1161 _dbus_hash_table_remove_int (DBusHashTable *table,
1164 DBusHashEntry *entry;
1165 DBusHashEntry **bucket;
1167 _dbus_assert (table->key_type == DBUS_HASH_INT);
1169 entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, &bucket, NULL);
1173 remove_entry (table, bucket, entry);
1181 * Removes the hash entry for the given key. If no hash entry
1182 * for the key exists, does nothing.
1184 * @param table the hash table.
1185 * @param key the hash key.
1186 * @returns #TRUE if the entry existed
1189 _dbus_hash_table_remove_uintptr (DBusHashTable *table,
1192 DBusHashEntry *entry;
1193 DBusHashEntry **bucket;
1195 _dbus_assert (table->key_type == DBUS_HASH_UINTPTR);
1197 entry = (* table->find_function) (table, (void*) key, FALSE, &bucket, NULL);
1201 remove_entry (table, bucket, entry);
1209 * Creates a hash entry with the given key and value.
1210 * The key and value are not copied; they are stored
1211 * in the hash table by reference. If an entry with the
1212 * given key already exists, the previous key and value
1213 * are overwritten (and freed if the hash table has
1214 * a key_free_function and/or value_free_function).
1216 * Returns #FALSE if memory for the new hash entry
1217 * can't be allocated.
1219 * @param table the hash table.
1220 * @param key the hash entry key.
1221 * @param value the hash entry value.
1224 _dbus_hash_table_insert_string (DBusHashTable *table,
1228 DBusPreallocatedHash *preallocated;
1230 _dbus_assert (table->key_type == DBUS_HASH_STRING);
1232 preallocated = _dbus_hash_table_preallocate_entry (table);
1233 if (preallocated == NULL)
1236 _dbus_hash_table_insert_string_preallocated (table, preallocated,
1243 * Creates a hash entry with the given key and value.
1244 * The key and value are not copied; they are stored
1245 * in the hash table by reference. If an entry with the
1246 * given key already exists, the previous key and value
1247 * are overwritten (and freed if the hash table has
1248 * a key_free_function and/or value_free_function).
1250 * Returns #FALSE if memory for the new hash entry
1251 * can't be allocated.
1253 * @param table the hash table.
1254 * @param key the hash entry key.
1255 * @param value the hash entry value.
1258 _dbus_hash_table_insert_int (DBusHashTable *table,
1262 DBusHashEntry *entry;
1264 _dbus_assert (table->key_type == DBUS_HASH_INT);
1266 entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), TRUE, NULL, NULL);
1269 return FALSE; /* no memory */
1271 if (table->free_key_function && entry->key != _DBUS_INT_TO_POINTER (key))
1272 (* table->free_key_function) (entry->key);
1274 if (table->free_value_function && entry->value != value)
1275 (* table->free_value_function) (entry->value);
1277 entry->key = _DBUS_INT_TO_POINTER (key);
1278 entry->value = value;
1284 * Creates a hash entry with the given key and value.
1285 * The key and value are not copied; they are stored
1286 * in the hash table by reference. If an entry with the
1287 * given key already exists, the previous key and value
1288 * are overwritten (and freed if the hash table has
1289 * a key_free_function and/or value_free_function).
1291 * Returns #FALSE if memory for the new hash entry
1292 * can't be allocated.
1294 * @param table the hash table.
1295 * @param key the hash entry key.
1296 * @param value the hash entry value.
1299 _dbus_hash_table_insert_uintptr (DBusHashTable *table,
1303 DBusHashEntry *entry;
1305 _dbus_assert (table->key_type == DBUS_HASH_UINTPTR);
1307 entry = (* table->find_function) (table, (void*) key, TRUE, NULL, NULL);
1310 return FALSE; /* no memory */
1312 if (table->free_key_function && entry->key != (void*) key)
1313 (* table->free_key_function) (entry->key);
1315 if (table->free_value_function && entry->value != value)
1316 (* table->free_value_function) (entry->value);
1318 entry->key = (void*) key;
1319 entry->value = value;
1325 * Preallocate an opaque data blob that allows us to insert into the
1326 * hash table at a later time without allocating any memory.
1328 * @param table the hash table
1329 * @returns the preallocated data, or #NULL if no memory
1331 DBusPreallocatedHash*
1332 _dbus_hash_table_preallocate_entry (DBusHashTable *table)
1334 DBusHashEntry *entry;
1336 entry = alloc_entry (table);
1338 return (DBusPreallocatedHash*) entry;
1342 * Frees an opaque DBusPreallocatedHash that was *not* used
1343 * in order to insert into the hash table.
1345 * @param table the hash table
1346 * @param preallocated the preallocated data
1349 _dbus_hash_table_free_preallocated_entry (DBusHashTable *table,
1350 DBusPreallocatedHash *preallocated)
1352 DBusHashEntry *entry;
1354 _dbus_assert (preallocated != NULL);
1356 entry = (DBusHashEntry*) preallocated;
1358 /* Don't use free_entry(), since this entry has no key/data */
1359 _dbus_mem_pool_dealloc (table->entry_pool, entry);
1363 * Inserts a string-keyed entry into the hash table, using a
1364 * preallocated data block from
1365 * _dbus_hash_table_preallocate_entry(). This function cannot fail due
1366 * to lack of memory. The DBusPreallocatedHash object is consumed and
1367 * should not be reused or freed. Otherwise this function works
1368 * just like _dbus_hash_table_insert_string().
1370 * @param table the hash table
1371 * @param preallocated the preallocated data
1372 * @param key the hash key
1373 * @param value the value
1376 _dbus_hash_table_insert_string_preallocated (DBusHashTable *table,
1377 DBusPreallocatedHash *preallocated,
1381 DBusHashEntry *entry;
1383 _dbus_assert (table->key_type == DBUS_HASH_STRING);
1384 _dbus_assert (preallocated != NULL);
1386 entry = (* table->find_function) (table, key, TRUE, NULL, preallocated);
1388 _dbus_assert (entry != NULL);
1390 if (table->free_key_function && entry->key != key)
1391 (* table->free_key_function) (entry->key);
1393 if (table->free_value_function && entry->value != value)
1394 (* table->free_value_function) (entry->value);
1397 entry->value = value;
1401 * Gets the number of hash entries in a hash table.
1403 * @param table the hash table.
1404 * @returns the number of entries in the table.
1407 _dbus_hash_table_get_n_entries (DBusHashTable *table)
1409 return table->n_entries;
1413 * Imports a string array into a hash table
1414 * The hash table needs to be initialized with string keys,
1415 * and dbus_free() as both key and value free-function.
1417 * @param table the hash table
1418 * @param array the string array to import
1419 * @param delimiter the delimiter to separate key and value
1420 * @return #TRUE on success.
1421 * @return #FALSE if not enough memory.
1425 _dbus_hash_table_from_array (DBusHashTable *table, char **array, char delimiter)
1430 dbus_bool_t retval = FALSE;
1432 _dbus_assert (table != NULL);
1433 _dbus_assert (array != NULL);
1435 if (!_dbus_string_init (&key))
1440 if (!_dbus_string_init (&value))
1442 _dbus_string_free (&key);
1446 for (i = 0; array[i] != NULL; i++)
1448 if (!_dbus_string_append (&key, array[i]))
1451 if (_dbus_string_split_on_byte (&key, delimiter, &value))
1453 char *hash_key, *hash_value;
1455 if (!_dbus_string_steal_data (&key, &hash_key))
1458 if (!_dbus_string_steal_data (&value, &hash_value))
1461 if (!_dbus_hash_table_insert_string (table,
1462 hash_key, hash_value))
1465 _dbus_string_set_length (&key, 0);
1466 _dbus_string_set_length (&value, 0);
1469 if (array[i] != NULL)
1475 _dbus_string_free (&key);
1476 _dbus_string_free (&value);
1482 * Creates a string array from a hash table
1484 * @param table the hash table
1485 * @param delimiter the delimiter to join key and value
1486 * @return pointer to created string array (free with dbus_free_string_array)
1487 * @return #FALSE if not enough memory.
1490 _dbus_hash_table_to_array (DBusHashTable *table, char delimiter)
1497 _dbus_assert (table != NULL);
1499 length = _dbus_hash_table_get_n_entries (table);
1501 array = dbus_new0 (char *, length + 1);
1507 _dbus_hash_iter_init (table, &iter);
1509 if (!_dbus_string_init (&entry))
1511 dbus_free_string_array (array);
1515 while (_dbus_hash_iter_next (&iter))
1517 const char *key, *value;
1519 key = (const char *) _dbus_hash_iter_get_string_key (&iter);
1520 value = (const char *) _dbus_hash_iter_get_value (&iter);
1522 if (!_dbus_string_append_printf (&entry, "%s%c%s", key, delimiter, value))
1525 if (!_dbus_string_steal_data (&entry, array + i))
1530 _dbus_string_free (&entry);
1534 dbus_free_string_array (array);
1543 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1544 #include "dbus-test.h"
1547 /* If you're wondering why the hash table test takes
1548 * forever to run, it's because we call this function
1549 * in inner loops thus making things quadratic.
1552 count_entries (DBusHashTable *table)
1558 _dbus_hash_iter_init (table, &iter);
1559 while (_dbus_hash_iter_next (&iter))
1562 _dbus_assert (count == _dbus_hash_table_get_n_entries (table));
1567 static inline void *
1570 /* @ptr is passed in as void* to avoid casting in the call */
1571 void **_ptr = (void **) ptr;
1581 * @ingroup DBusHashTableInternals
1582 * Unit test for DBusHashTable
1583 * @returns #TRUE on success.
1586 _dbus_hash_test (void)
1589 DBusHashTable *table1;
1590 DBusHashTable *table2;
1591 DBusHashTable *table3;
1593 #define N_HASH_KEYS 5000
1595 dbus_bool_t ret = FALSE;
1596 char *str_key = NULL;
1597 char *str_value = NULL;
1599 keys = dbus_new (char *, N_HASH_KEYS);
1601 _dbus_assert_not_reached ("no memory");
1603 for (i = 0; i < N_HASH_KEYS; i++)
1605 keys[i] = dbus_malloc (128);
1607 if (keys[i] == NULL)
1608 _dbus_assert_not_reached ("no memory");
1611 printf ("Computing test hash keys...\n");
1613 while (i < N_HASH_KEYS)
1617 len = sprintf (keys[i], "Hash key %d", i);
1618 _dbus_assert (*(keys[i] + len) == '\0');
1621 printf ("... done.\n");
1623 table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
1624 dbus_free, dbus_free);
1628 table2 = _dbus_hash_table_new (DBUS_HASH_INT,
1633 table3 = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
1638 /* Insert and remove a bunch of stuff, counting the table in between
1639 * to be sure it's not broken and that iteration works
1644 const void *out_value;
1646 str_key = _dbus_strdup (keys[i]);
1647 if (str_key == NULL)
1649 str_value = _dbus_strdup ("Value!");
1650 if (str_value == NULL)
1653 if (!_dbus_hash_table_insert_string (table1,
1655 steal (&str_value)))
1658 str_value = _dbus_strdup (keys[i]);
1659 if (str_value == NULL)
1662 if (!_dbus_hash_table_insert_int (table2,
1663 i, steal (&str_value)))
1666 str_value = _dbus_strdup (keys[i]);
1667 if (str_value == NULL)
1670 if (!_dbus_hash_table_insert_uintptr (table3,
1671 i, steal (&str_value)))
1674 _dbus_assert (count_entries (table1) == i + 1);
1675 _dbus_assert (count_entries (table2) == i + 1);
1676 _dbus_assert (count_entries (table3) == i + 1);
1678 out_value = _dbus_hash_table_lookup_string (table1, keys[i]);
1679 _dbus_assert (out_value != NULL);
1680 _dbus_assert (strcmp (out_value, "Value!") == 0);
1682 out_value = _dbus_hash_table_lookup_int (table2, i);
1683 _dbus_assert (out_value != NULL);
1684 _dbus_assert (strcmp (out_value, keys[i]) == 0);
1686 out_value = _dbus_hash_table_lookup_uintptr (table3, i);
1687 _dbus_assert (out_value != NULL);
1688 _dbus_assert (strcmp (out_value, keys[i]) == 0);
1696 _dbus_hash_table_remove_string (table1,
1699 _dbus_hash_table_remove_int (table2, i);
1701 _dbus_hash_table_remove_uintptr (table3, i);
1703 _dbus_assert (count_entries (table1) == i);
1704 _dbus_assert (count_entries (table2) == i);
1705 _dbus_assert (count_entries (table3) == i);
1710 _dbus_hash_table_ref (table1);
1711 _dbus_hash_table_ref (table2);
1712 _dbus_hash_table_ref (table3);
1713 _dbus_hash_table_unref (table1);
1714 _dbus_hash_table_unref (table2);
1715 _dbus_hash_table_unref (table3);
1716 _dbus_hash_table_unref (table1);
1717 _dbus_hash_table_unref (table2);
1718 _dbus_hash_table_unref (table3);
1721 /* Insert a bunch of stuff then check
1722 * that iteration works correctly (finds the right
1723 * values, iter_set_value works, etc.)
1725 table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
1726 dbus_free, dbus_free);
1730 table2 = _dbus_hash_table_new (DBUS_HASH_INT,
1738 str_key = _dbus_strdup (keys[i]);
1739 if (str_key == NULL)
1741 str_value = _dbus_strdup ("Value!");
1742 if (str_value == NULL)
1745 if (!_dbus_hash_table_insert_string (table1,
1747 steal (&str_value)))
1750 str_value = _dbus_strdup (keys[i]);
1751 if (str_value == NULL)
1754 if (!_dbus_hash_table_insert_int (table2,
1755 i, steal (&str_value)))
1758 _dbus_assert (count_entries (table1) == i + 1);
1759 _dbus_assert (count_entries (table2) == i + 1);
1764 _dbus_hash_iter_init (table1, &iter);
1765 while (_dbus_hash_iter_next (&iter))
1770 key = _dbus_hash_iter_get_string_key (&iter);
1771 value = _dbus_hash_iter_get_value (&iter);
1773 _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
1775 str_value = _dbus_strdup ("Different value!");
1776 if (str_value == NULL)
1780 _dbus_hash_iter_set_value (&iter, steal (&str_value));
1781 _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
1784 _dbus_hash_iter_init (table1, &iter);
1785 while (_dbus_hash_iter_next (&iter))
1787 _dbus_hash_iter_remove_entry (&iter);
1788 _dbus_assert (count_entries (table1) == i - 1);
1792 _dbus_hash_iter_init (table2, &iter);
1793 while (_dbus_hash_iter_next (&iter))
1798 key = _dbus_hash_iter_get_int_key (&iter);
1799 value = _dbus_hash_iter_get_value (&iter);
1801 _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
1803 str_value = _dbus_strdup ("Different value!");
1804 if (str_value == NULL)
1808 _dbus_hash_iter_set_value (&iter, steal (&str_value));
1809 _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
1812 i = count_entries (table2);
1813 _dbus_hash_iter_init (table2, &iter);
1814 while (_dbus_hash_iter_next (&iter))
1816 _dbus_hash_iter_remove_entry (&iter);
1817 _dbus_assert (count_entries (table2) + 1 == i);
1821 /* add/remove interleaved, to check that we grow/shrink the table
1827 str_key = _dbus_strdup (keys[i]);
1828 if (str_key == NULL)
1831 str_value = _dbus_strdup ("Value!");
1832 if (str_value == NULL)
1835 if (!_dbus_hash_table_insert_string (table1,
1837 steal (&str_value)))
1846 str_key = _dbus_strdup (keys[i]);
1847 if (str_key == NULL)
1849 str_value = _dbus_strdup ("Value!");
1850 if (str_value == NULL)
1853 if (!_dbus_hash_table_remove_string (table1, keys[i]))
1856 if (!_dbus_hash_table_insert_string (table1,
1858 steal (&str_value)))
1861 if (!_dbus_hash_table_remove_string (table1, keys[i]))
1864 _dbus_assert (_dbus_hash_table_get_n_entries (table1) == i);
1869 /* nuke these tables */
1870 _dbus_hash_table_unref (table1);
1871 _dbus_hash_table_unref (table2);
1874 /* Now do a bunch of things again using _dbus_hash_iter_lookup() to
1875 * be sure that interface works.
1877 table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
1878 dbus_free, dbus_free);
1882 table2 = _dbus_hash_table_new (DBUS_HASH_INT,
1890 const void *out_value;
1892 str_key = _dbus_strdup (keys[i]);
1893 if (str_key == NULL)
1895 str_value = _dbus_strdup ("Value!");
1896 if (str_value == NULL)
1899 if (!_dbus_hash_iter_lookup (table1,
1900 steal (&str_key), TRUE, &iter))
1902 _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
1903 _dbus_hash_iter_set_value (&iter, steal (&str_value));
1905 str_value = _dbus_strdup (keys[i]);
1906 if (str_value == NULL)
1909 if (!_dbus_hash_iter_lookup (table2,
1910 _DBUS_INT_TO_POINTER (i), TRUE, &iter))
1912 _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
1913 _dbus_hash_iter_set_value (&iter, steal (&str_value));
1915 _dbus_assert (count_entries (table1) == i + 1);
1916 _dbus_assert (count_entries (table2) == i + 1);
1918 if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
1921 out_value = _dbus_hash_iter_get_value (&iter);
1922 _dbus_assert (out_value != NULL);
1923 _dbus_assert (strcmp (out_value, "Value!") == 0);
1925 /* Iterate just to be sure it works, though
1926 * it's a stupid thing to do
1928 while (_dbus_hash_iter_next (&iter))
1931 if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
1934 out_value = _dbus_hash_iter_get_value (&iter);
1935 _dbus_assert (out_value != NULL);
1936 _dbus_assert (strcmp (out_value, keys[i]) == 0);
1938 /* Iterate just to be sure it works, though
1939 * it's a stupid thing to do
1941 while (_dbus_hash_iter_next (&iter))
1950 if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
1951 _dbus_assert_not_reached ("hash entry should have existed");
1952 _dbus_hash_iter_remove_entry (&iter);
1954 if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
1955 _dbus_assert_not_reached ("hash entry should have existed");
1956 _dbus_hash_iter_remove_entry (&iter);
1958 _dbus_assert (count_entries (table1) == i);
1959 _dbus_assert (count_entries (table2) == i);
1964 _dbus_hash_table_unref (table1);
1965 _dbus_hash_table_unref (table2);
1970 for (i = 0; i < N_HASH_KEYS; i++)
1971 dbus_free (keys[i]);
1975 dbus_free (str_key);
1976 dbus_free (str_value);
1981 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */