1d012387afef0ba02185ebe27bc6bb15551912e92Havoc Pennington/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
27652304bff969afb3969603149bb385efe861fe8John (J/* dbus-hash.c Generic hash table utility (internal to D-Bus implementation)
3ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
4ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * Copyright (C) 2002  Red Hat, Inc.
5ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * Copyright (c) 1991-1993 The Regents of the University of California.
6ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * Copyright (c) 1994 Sun Microsystems, Inc.
7ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
8ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * Hash table implementation based on generic/tclHash.c from the Tcl
9ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * source code. The original Tcl license applies to portions of the
107652304bff969afb3969603149bb385efe861fe8John (J * code from tclHash.c; the Tcl license follows this standad D-Bus
11ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * license information.
12ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
1343605a6f4e78a8c28afb4b1e924dff0301e0e95cHavoc Pennington * Licensed under the Academic Free License version 2.1
14ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
15ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * This program is free software; you can redistribute it and/or modify
16ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * it under the terms of the GNU General Public License as published by
17ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * the Free Software Foundation; either version 2 of the License, or
18ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * (at your option) any later version.
19ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
20ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * This program is distributed in the hope that it will be useful,
21ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * but WITHOUT ANY WARRANTY; without even the implied warranty of
22ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * GNU General Public License for more details.
24ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
25ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * You should have received a copy of the GNU General Public License
26ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * along with this program; if not, write to the Free Software
275baf2f856a9c6625993234855b07680da1c8916fTobias Mueller * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
28ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
29ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
30ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington/*
31ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * The following copyright applies to code from the Tcl distribution.
32ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
33ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * Copyright (c) 1991-1993 The Regents of the University of California.
34ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * Copyright (c) 1994 Sun Microsystems, Inc.
35ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
36ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * This software is copyrighted by the Regents of the University of
37ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * California, Sun Microsystems, Inc., Scriptics Corporation, and
38ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * other parties.  The following terms apply to all files associated
39ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * with the software unless explicitly disclaimed in individual files.
40ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
41ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * The authors hereby grant permission to use, copy, modify,
42ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * distribute, and license this software and its documentation for any
43ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * purpose, provided that existing copyright notices are retained in
44ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * all copies and that this notice is included verbatim in any
45ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * distributions. No written agreement, license, or royalty fee is
46ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * required for any of the authorized uses.  Modifications to this
47ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * software may be copyrighted by their authors and need not follow
48ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * the licensing terms described here, provided that the new terms are
49ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * clearly indicated on the first page of each file where they apply.
50ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
51ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
52ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
53ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
54ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
55ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * OF THE POSSIBILITY OF SUCH DAMAGE.
56ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
57ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
58ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
59ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
60ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
61ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
62ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
63ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
64ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * GOVERNMENT USE: If you are acquiring this software on behalf of the
65ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * U.S. government, the Government shall have only "Restricted Rights"
66ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * in the software and related documentation as defined in the Federal
67ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
68ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * are acquiring the software on behalf of the Department of Defense,
69ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * the software shall be classified as "Commercial Computer Software"
70ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * and the Government shall have only "Restricted Rights" as defined
71ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * in Clause 252.227-7013 (c) (1) of DFARs.  Notwithstanding the
72ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * foregoing, the authors grant the U.S. Government and others acting
73ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * in its behalf permission to use and distribute the software in
74ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington * accordance with the terms specified in this license.
75ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
76ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
77dbecdeabb20e0ce11121819c63373f0afba57c58Marcus Brinkmann#include <config.h>
781428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington#include "dbus-hash.h"
791428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington#include "dbus-internals.h"
8017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington#include "dbus-mempool.h"
81ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
821428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
831428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @defgroup DBusHashTable Hash table
841428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @ingroup  DBusInternals
851428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @brief DBusHashTable data structure
861428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
871428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Types and functions related to DBusHashTable.
88ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
89ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
901428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
911428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @defgroup DBusHashTableInternals Hash table implementation details
921428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @ingroup  DBusInternals
931428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @brief DBusHashTable implementation details
941428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
951428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * The guts of DBusHashTable.
961428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
971428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @{
981428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
99ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
1001428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
1011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * When there are this many entries per bucket, on average, rebuild
1021428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * the hash table to make it larger.
1031428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
1041428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington#define REBUILD_MULTIPLIER  3
1051428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
1061428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
1071428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Takes a preliminary integer hash value and produces an index into a
1081428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * hash tables bucket list.  The idea is to make it so that
1091428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * preliminary values that are arbitrarily similar will end up in
1101428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * different buckets.  The hash function was taken from a
1111428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * random-number generator. (This is used to hash integers.)
11217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington *
11317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * The down_shift drops off the high bits of the hash index, and
11417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * decreases as we increase the number of hash buckets (to keep more
11517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * range in the hash index). The mask also strips high bits and strips
11617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * fewer high bits as the number of hash buckets increases.
11717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * I don't understand two things: why is the initial downshift 28
11817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * to keep 4 bits when the initial mask is 011 to keep 2 bits,
11917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * and why do we have both a mask and a downshift?
12017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington *
121ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
1221428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington#define RANDOM_INDEX(table, i) \
123c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba    (((((intptr_t) (i))*1103515245) >> (table)->down_shift) & (table)->mask)
124ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
1251428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
1261428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Initial number of buckets in hash table (hash table statically
1271428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * allocates its buckets for this size and below).
12817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * The initial mask has to be synced to this.
129ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
1301428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington#define DBUS_SMALL_HASH_TABLE 4
131ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
1321428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
1331428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Typedef for DBusHashEntry
134ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
1351428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtontypedef struct DBusHashEntry DBusHashEntry;
136ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
1371428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
138f09921965c769ff6411ae2f684f6b855d4c8f38dHavoc Pennington * @brief Internal representation of a hash entry.
139f09921965c769ff6411ae2f684f6b855d4c8f38dHavoc Pennington *
1401428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * A single entry (key-value pair) in the hash table.
1411428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Internal to hash table implementation.
1421428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
1431428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonstruct DBusHashEntry
1441428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
1451428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry *next;    /**< Pointer to next entry in this
1461428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                           * hash bucket, or #NULL for end of
1471428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                           * chain.
1481428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                           */
1491428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  void *key;              /**< Hash key */
1501428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  void *value;            /**< Hash value */
1511428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington};
1521428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
1531428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
1541428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Function used to find and optionally create a hash entry.
1551428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
1566be547d32f018c23ba56426a0bccd08baa2cf440Havoc Penningtontypedef DBusHashEntry* (* DBusFindEntryFunction) (DBusHashTable        *table,
1576be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                                                  void                 *key,
1586be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                                                  dbus_bool_t           create_if_not_found,
1596be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                                                  DBusHashEntry      ***bucket,
1606be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                                                  DBusPreallocatedHash *preallocated);
161ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
1621428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
163f09921965c769ff6411ae2f684f6b855d4c8f38dHavoc Pennington * @brief Internals of DBusHashTable.
164f09921965c769ff6411ae2f684f6b855d4c8f38dHavoc Pennington *
165f09921965c769ff6411ae2f684f6b855d4c8f38dHavoc Pennington * Hash table internals. Hash tables are opaque objects, they must be
166f09921965c769ff6411ae2f684f6b855d4c8f38dHavoc Pennington * used via accessor functions.
1671428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
1681428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonstruct DBusHashTable {
1691428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  int refcount;                       /**< Reference count */
1701428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
1711428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry **buckets;            /**< Pointer to bucket array.  Each
1721428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                       * element points to first entry in
1731428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                       * bucket's hash chain, or #NULL.
1741428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                       */
1751428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry *static_buckets[DBUS_SMALL_HASH_TABLE];
1761428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                       /**< Bucket array used for small tables
1771428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        * (to avoid mallocs and frees).
1781428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        */
1791428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  int n_buckets;                       /**< Total number of buckets allocated
1801428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        * at **buckets.
1811428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        */
1821428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  int n_entries;                       /**< Total number of entries present
1831428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        * in table.
1841428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        */
18517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  int hi_rebuild_size;                 /**< Enlarge table when n_entries gets
1861428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        * to be this large.
1871428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        */
18817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  int lo_rebuild_size;                 /**< Shrink table when n_entries gets
18917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington                                        * below this.
19017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington                                        */
1911428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  int down_shift;                      /**< Shift count used in hashing
1921428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        * function.  Designed to use high-
1931428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        * order bits of randomized keys.
1941428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        */
1951428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  int mask;                            /**< Mask value used in hashing
1961428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        * function.
1971428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        */
1981428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashType key_type;               /**< Type of keys used in this table */
1991428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
2001428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
2011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusFindEntryFunction find_function; /**< Function for finding entries */
2021428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
2031428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusFreeFunction free_key_function;   /**< Function to free keys */
2041428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusFreeFunction free_value_function; /**< Function to free values */
20517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
20617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  DBusMemPool *entry_pool;              /**< Memory pool for hash entries */
2071428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington};
2081428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
209f09921965c769ff6411ae2f684f6b855d4c8f38dHavoc Pennington/**
210f09921965c769ff6411ae2f684f6b855d4c8f38dHavoc Pennington * @brief Internals of DBusHashIter.
2111428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
2121428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtontypedef struct
2131428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
2141428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashTable *table;     /**< Pointer to table containing entry. */
2151428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry **bucket;   /**< Pointer to bucket that points to
2161428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                             * first entry in this entry's chain:
2171428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                             * used for deleting the entry.
2181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                             */
2191428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry *entry;      /**< Current hash entry */
2201428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry *next_entry; /**< Next entry to be iterated onto in current bucket */
2211428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  int next_bucket;           /**< index of next bucket */
2221428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  int n_entries_on_init;     /**< used to detect table resize since initialization */
2231428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington} DBusRealHashIter;
2241428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
22595717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic DBusHashEntry* find_direct_function      (DBusHashTable          *table,
22695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 void                   *key,
22795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 dbus_bool_t             create_if_not_found,
22895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 DBusHashEntry        ***bucket,
22995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 DBusPreallocatedHash   *preallocated);
23095717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic DBusHashEntry* find_string_function      (DBusHashTable          *table,
23195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 void                   *key,
23295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 dbus_bool_t             create_if_not_found,
23395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 DBusHashEntry        ***bucket,
23495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 DBusPreallocatedHash   *preallocated);
2357bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
23695717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic DBusHashEntry* find_two_strings_function (DBusHashTable          *table,
23795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 void                   *key,
23895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 dbus_bool_t             create_if_not_found,
23995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 DBusHashEntry        ***bucket,
24095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 DBusPreallocatedHash   *preallocated);
2417bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif
24295717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic unsigned int   string_hash               (const char             *str);
2437bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
24495717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic unsigned int   two_strings_hash          (const char             *str);
2457bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif
24695717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic void           rebuild_table             (DBusHashTable          *table);
24795717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic DBusHashEntry* alloc_entry               (DBusHashTable          *table);
24895717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic void           remove_entry              (DBusHashTable          *table,
24995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 DBusHashEntry         **bucket,
25095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 DBusHashEntry          *entry);
25195717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic void           free_entry                (DBusHashTable          *table,
25295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 DBusHashEntry          *entry);
25395717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic void           free_entry_data           (DBusHashTable          *table,
25495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                                 DBusHashEntry          *entry);
2556be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
2561428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
25755de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington/** @} */
2581428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
2591428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
2601428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @addtogroup DBusHashTable
2611428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @{
2621428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
263ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
2641428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
2651428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @typedef DBusHashIter
2661428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
2671428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Public opaque hash table iterator object.
268ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
269ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
2701428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
2711428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @typedef DBusHashTable
2721428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
2731428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Public opaque hash table object.
2741428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
275ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
2761428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
2771428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @typedef DBusHashType
2781428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
2791428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Indicates the type of a key in the hash table.
2801428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
281ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
2821428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
2831428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Constructs a new hash table. Should be freed with
2841428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * _dbus_hash_table_unref(). If memory cannot be
2851428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * allocated for the hash table, returns #NULL.
2861428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
2871428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param type the type of hash key to use.
2881428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param key_free_function function to free hash keys.
2891428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param value_free_function function to free hash values.
2901428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @returns a new DBusHashTable or #NULL if no memory.
291ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
2921428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc PenningtonDBusHashTable*
2931428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_table_new (DBusHashType     type,
2941428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                      DBusFreeFunction key_free_function,
2951428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                      DBusFreeFunction value_free_function)
2961428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
2971428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashTable *table;
29817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  DBusMemPool *entry_pool;
29917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
3001428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table = dbus_new0 (DBusHashTable, 1);
3011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (table == NULL)
3021428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    return NULL;
30317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
30417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  entry_pool = _dbus_mem_pool_new (sizeof (DBusHashEntry), TRUE);
30517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  if (entry_pool == NULL)
30617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    {
30717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      dbus_free (table);
30817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      return NULL;
30917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    }
3101428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
3111428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table->refcount = 1;
31217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  table->entry_pool = entry_pool;
31317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
3141428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (DBUS_SMALL_HASH_TABLE == _DBUS_N_ELEMENTS (table->static_buckets));
3151428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
3161428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table->buckets = table->static_buckets;
3171428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table->n_buckets = DBUS_SMALL_HASH_TABLE;
3181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table->n_entries = 0;
31917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  table->hi_rebuild_size = DBUS_SMALL_HASH_TABLE * REBUILD_MULTIPLIER;
32017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  table->lo_rebuild_size = 0;
3211428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table->down_shift = 28;
3221428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table->mask = 3;
3231428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table->key_type = type;
32417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
32517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  _dbus_assert (table->mask < table->n_buckets);
3261428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
3271428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  switch (table->key_type)
3281428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
3291428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    case DBUS_HASH_INT:
33096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    case DBUS_HASH_POINTER:
331c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba    case DBUS_HASH_UINTPTR:
33296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington      table->find_function = find_direct_function;
3331428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      break;
3341428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    case DBUS_HASH_STRING:
3351428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      table->find_function = find_string_function;
3361428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      break;
33795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    case DBUS_HASH_TWO_STRINGS:
3387bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
33995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      table->find_function = find_two_strings_function;
3407bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif
34195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      break;
3421428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    default:
3431428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert_not_reached ("Unknown hash table type");
3441428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      break;
3451428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    }
346ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
3471428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table->free_key_function = key_free_function;
3481428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table->free_value_function = value_free_function;
349ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
3501428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  return table;
3511428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
352ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
3531428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
3541428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
3551428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Increments the reference count for a hash table.
356ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
3571428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param table the hash table to add a reference to.
3589f1a60dbba69844c0a04b3dd86280352736187ceMikael Hallendal * @returns the hash table.
359ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
3609f1a60dbba69844c0a04b3dd86280352736187ceMikael HallendalDBusHashTable *
3611428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_table_ref (DBusHashTable *table)
362ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington{
3631428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table->refcount += 1;
3649f1a60dbba69844c0a04b3dd86280352736187ceMikael Hallendal
3659f1a60dbba69844c0a04b3dd86280352736187ceMikael Hallendal  return table;
366ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington}
3671428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
3681428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
3691428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Decrements the reference count for a hash table,
3701428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * freeing the hash table if the count reaches zero.
371ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
3721428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param table the hash table to remove a reference from.
373ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
374ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Penningtonvoid
3751428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_table_unref (DBusHashTable *table)
376ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington{
3771428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table->refcount -= 1;
3781428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
3791428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (table->refcount == 0)
3801428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
38117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington#if 0
3821428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      DBusHashEntry *entry;
3831428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      DBusHashEntry *next;
3841428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      int i;
3851428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
3861428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      /* Free the entries in the table. */
3871428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      for (i = 0; i < table->n_buckets; i++)
3881428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        {
3891428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          entry = table->buckets[i];
3901428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          while (entry != NULL)
3911428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington            {
3921428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington              next = entry->next;
3931428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
3941428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington              free_entry (table, entry);
3951428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
3961428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington              entry = next;
3971428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington            }
3981428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        }
39917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington#else
4008925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson      DBusHashEntry *entry;
4018925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson      int i;
4028925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson
4038925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson      /* Free the entries in the table. */
4048925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson      for (i = 0; i < table->n_buckets; i++)
4058925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson        {
4068925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson          entry = table->buckets[i];
4078925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson          while (entry != NULL)
4088925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson            {
4098925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson              free_entry_data (table, entry);
4108925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson
4118925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson              entry = entry->next;
4128925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson            }
4138925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson        }
41417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      /* We can do this very quickly with memory pools ;-) */
41517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      _dbus_mem_pool_free (table->entry_pool);
41617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington#endif
41717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
4181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      /* Free the bucket array, if it was dynamically allocated. */
4191428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (table->buckets != table->static_buckets)
4201428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        dbus_free (table->buckets);
4211428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
4221428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      dbus_free (table);
423ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington    }
424ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington}
4251428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
426caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons/**
427caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons * Removed all entries from a hash table.
428caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons *
429caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons * @param table the hash table to remove all entries from.
430caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons */
431caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simonsvoid
432caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons_dbus_hash_table_remove_all (DBusHashTable *table)
433caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons{
434caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons  DBusHashIter iter;
435caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons  _dbus_hash_iter_init (table, &iter);
436caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons  while (_dbus_hash_iter_next (&iter))
437caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons    {
438caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons      _dbus_hash_iter_remove_entry(&iter);
439caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons    }
440caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons}
441caf220015ba1afd9dfca2a93cfa5208058041610Sjoerd Simons
4421428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonstatic DBusHashEntry*
4431428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonalloc_entry (DBusHashTable *table)
4441428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
4451428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry *entry;
4461428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
44717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  entry = _dbus_mem_pool_alloc (table->entry_pool);
44817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
4491428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  return entry;
4501428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
4511428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
4521428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonstatic void
4538925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larssonfree_entry_data (DBusHashTable  *table,
4548925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson		 DBusHashEntry  *entry)
4551428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
4561428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (table->free_key_function)
4571428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    (* table->free_key_function) (entry->key);
4581428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (table->free_value_function)
4591428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    (* table->free_value_function) (entry->value);
4608925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson}
4618925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson
4628925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larssonstatic void
4638925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larssonfree_entry (DBusHashTable  *table,
4648925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson            DBusHashEntry  *entry)
4658925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson{
4668925ff6d9870ccaab0feeb4f9af6e1f075d313efAlexander Larsson  free_entry_data (table, entry);
46717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  _dbus_mem_pool_dealloc (table->entry_pool, entry);
4681428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
4691428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
4701428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonstatic void
4711428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonremove_entry (DBusHashTable  *table,
4721428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington              DBusHashEntry **bucket,
4731428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington              DBusHashEntry  *entry)
4741428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
4751428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (table != NULL);
4761428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (bucket != NULL);
4771428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (*bucket != NULL);
4781428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (entry != NULL);
4791428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
4801428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (*bucket == entry)
4811428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    *bucket = entry->next;
4821428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  else
4831428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
4841428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      DBusHashEntry *prev;
4851428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      prev = *bucket;
4861428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
4871428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      while (prev->next != entry)
4881428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        prev = prev->next;
4891428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
4901428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (prev != NULL);
4911428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
4921428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      prev->next = entry->next;
4931428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    }
4941428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
4951428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table->n_entries -= 1;
4961428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  free_entry (table, entry);
4971428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
4981428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
4991428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
5001428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Initializes a hash table iterator. To iterate over all entries in a
5011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * hash table, use the following code (the printf assumes a hash
5021428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * from strings to strings obviously):
5031428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
5041428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @code
5051428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * DBusHashIter iter;
5061428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
5071428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * _dbus_hash_iter_init (table, &iter);
5081428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * while (_dbus_hash_iter_next (&iter))
5091428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *   {
5101428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *      printf ("The first key is %s and value is %s\n",
5111428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *              _dbus_hash_iter_get_string_key (&iter),
5121428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *              _dbus_hash_iter_get_value (&iter));
5131428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *   }
5141428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
5151428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
5161428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @endcode
517ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
5181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * The iterator is initialized pointing "one before" the first hash
5191428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * entry. The first call to _dbus_hash_iter_next() moves it onto
5201428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * the first valid entry or returns #FALSE if the hash table is
5211428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * empty. Subsequent calls move to the next valid entry or return
5221428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * #FALSE if there are no more entries.
523ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
5241428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Note that it is guaranteed to be safe to remove a hash entry during
5251428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * iteration, but it is not safe to add a hash entry.
5261428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
5271428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param table the hash table to iterate over.
5281428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param iter the iterator to initialize.
529ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
530ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Penningtonvoid
5311428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_iter_init (DBusHashTable *table,
5321428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                      DBusHashIter  *iter)
533ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington{
5341428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusRealHashIter *real;
5351428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
5361428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
5371428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
5381428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real = (DBusRealHashIter*) iter;
5391428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
5401428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->table = table;
5411428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->bucket = NULL;
5421428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->entry = NULL;
5431428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->next_entry = NULL;
5441428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->next_bucket = 0;
5451428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->n_entries_on_init = table->n_entries;
5461428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
547ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
5481428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
5491428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Move the hash iterator forward one step, to the next hash entry.
5501428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * The documentation for _dbus_hash_iter_init() explains in more
5511428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * detail.
5521428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
5531428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param iter the iterator to move forward.
5541428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @returns #FALSE if there are no more entries to move to.
5551428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
5561428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtondbus_bool_t
5571428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_iter_next (DBusHashIter  *iter)
5581428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
5591428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusRealHashIter *real;
5601428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
5611428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
5621428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
5631428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real = (DBusRealHashIter*) iter;
5641428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
5651428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  /* if this assertion failed someone probably added hash entries
5661428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington   * during iteration, which is bad.
567ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington   */
5681428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->n_entries_on_init >= real->table->n_entries);
5691428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
5701428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  /* Remember that real->entry may have been deleted */
5711428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
5721428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  while (real->next_entry == NULL)
5731428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
5741428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (real->next_bucket >= real->table->n_buckets)
5751428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        {
5761428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          /* invalidate iter and return false */
5771428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          real->entry = NULL;
5781428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          real->table = NULL;
5791428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          real->bucket = NULL;
5801428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          return FALSE;
5811428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        }
582ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
5831428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      real->bucket = &(real->table->buckets[real->next_bucket]);
5841428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      real->next_entry = *(real->bucket);
5851428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      real->next_bucket += 1;
586ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington    }
587ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
5881428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->next_entry != NULL);
5891428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->bucket != NULL);
5901428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
5911428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->entry = real->next_entry;
5921428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->next_entry = real->entry->next;
5931428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
5941428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  return TRUE;
5951428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
596ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
5971428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
5981428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Removes the current entry from the hash table.
5991428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * If a key_free_function or value_free_function
6001428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * was provided to _dbus_hash_table_new(),
6011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * frees the key and/or value for this entry.
6021428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
6031428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param iter the hash table iterator.
6041428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
6051428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonvoid
6061428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_iter_remove_entry (DBusHashIter *iter)
6071428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
6081428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusRealHashIter *real;
609ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
6101428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real = (DBusRealHashIter*) iter;
611ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
6121428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->table != NULL);
6131428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->entry != NULL);
6141428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->bucket != NULL);
6151428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
6161428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  remove_entry (real->table, real->bucket, real->entry);
6171428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
6181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->entry = NULL; /* make it crash if you try to use this entry */
619ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington}
6201428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
6211428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
6221428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Gets the value of the current entry.
623ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
6241428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param iter the hash table iterator.
625ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
6261428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonvoid*
6271428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_iter_get_value (DBusHashIter *iter)
628ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington{
6291428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusRealHashIter *real;
6301428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
6311428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real = (DBusRealHashIter*) iter;
6321428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
6331428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->table != NULL);
6341428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->entry != NULL);
6351428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
6361428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  return real->entry->value;
637ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington}
6381428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
6391428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
6401428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Sets the value of the current entry.
6411428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * If the hash table has a value_free_function
6421428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * it will be used to free the previous value.
6431428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * The hash table will own the passed-in value
6441428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * (it will not be copied).
645ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
6461428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param iter the hash table iterator.
6471428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param value the new value.
648ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
6491428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonvoid
6501428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_iter_set_value (DBusHashIter *iter,
6511428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                           void         *value)
652ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington{
6531428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusRealHashIter *real;
654ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
6551428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real = (DBusRealHashIter*) iter;
6561428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
6571428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->table != NULL);
6581428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->entry != NULL);
6591428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
6601428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (real->table->free_value_function && value != real->entry->value)
6611428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    (* real->table->free_value_function) (real->entry->value);
6621428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
6631428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->entry->value = value;
664ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington}
6651428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
6661428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
6671428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Gets the key for the current entry.
6681428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Only works for hash tables of type #DBUS_HASH_INT.
669ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
6701428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param iter the hash table iterator.
671ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
6721428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonint
6731428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_iter_get_int_key (DBusHashIter *iter)
674ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington{
6751428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusRealHashIter *real;
676ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
6771428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real = (DBusRealHashIter*) iter;
678ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
6791428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->table != NULL);
6801428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->entry != NULL);
681ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
6821428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  return _DBUS_POINTER_TO_INT (real->entry->key);
6831428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
684ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
6851428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
6861428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Gets the key for the current entry.
687c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba * Only works for hash tables of type #DBUS_HASH_UINTPTR.
688a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington *
689a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * @param iter the hash table iterator.
690a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington */
691c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trbauintptr_t
692c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba_dbus_hash_iter_get_uintptr_key (DBusHashIter *iter)
693a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington{
694a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  DBusRealHashIter *real;
695a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
696a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  real = (DBusRealHashIter*) iter;
697a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
698a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  _dbus_assert (real->table != NULL);
699a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  _dbus_assert (real->entry != NULL);
700a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
701c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba  return (uintptr_t) real->entry->key;
702a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington}
703a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
704a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington/**
705a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * Gets the key for the current entry.
7061428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Only works for hash tables of type #DBUS_HASH_STRING
7071428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param iter the hash table iterator.
7081428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
7091428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonconst char*
7101428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_iter_get_string_key (DBusHashIter *iter)
7111428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
7121428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusRealHashIter *real;
7131428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
7141428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real = (DBusRealHashIter*) iter;
7151428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
7161428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->table != NULL);
7171428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (real->entry != NULL);
7181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
7191428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  return real->entry->key;
720ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington}
7211428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
7227bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
7231428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
72495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * Gets the key for the current entry.
72595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * Only works for hash tables of type #DBUS_HASH_TWO_STRINGS
72695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param iter the hash table iterator.
72795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington */
72895717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonconst char*
72995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington_dbus_hash_iter_get_two_strings_key (DBusHashIter *iter)
73095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington{
73195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  DBusRealHashIter *real;
73295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
73395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  real = (DBusRealHashIter*) iter;
73495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
73595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  _dbus_assert (real->table != NULL);
73695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  _dbus_assert (real->entry != NULL);
73795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
73895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  return real->entry->key;
73995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington}
7407bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
74195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
74295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington/**
7431428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * A low-level but efficient interface for manipulating the hash
7441428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * table.  It's efficient because you can get, set, and optionally
7451428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * create the hash entry while only running the hash function one
7461428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * time.
747ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
7481428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Note that while calling _dbus_hash_iter_next() on the iterator
7491428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * filled in by this function may work, it's completely
7501428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * undefined which entries are after this iter and which
7511428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * are before it. So it would be silly to iterate using this
7521428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * iterator.
753ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
7541428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * If the hash entry is created, its value will be initialized
7551428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * to all bits zero.
756ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
7571428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * #FALSE may be returned due to memory allocation failure, or
7581428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * because create_if_not_found was #FALSE and the entry
7591428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * did not exist.
760ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
76117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * If create_if_not_found is #TRUE and the entry is created, the hash
76217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * table takes ownership of the key that's passed in.
76317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington *
7641428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * For a hash table of type #DBUS_HASH_INT, cast the int
7651428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * key to the key parameter using #_DBUS_INT_TO_POINTER().
7661428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
7671428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param table the hash table.
7681428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param key the hash key.
7691428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param create_if_not_found if #TRUE, create the entry if it didn't exist.
7701428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param iter the iterator to initialize.
7711428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @returns #TRUE if the hash entry now exists (and the iterator is thus valid).
772ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
7731428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtondbus_bool_t
7741428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_iter_lookup (DBusHashTable *table,
7751428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                        void          *key,
7761428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                        dbus_bool_t    create_if_not_found,
7771428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                        DBusHashIter  *iter)
7781428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
7791428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusRealHashIter *real;
7801428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry *entry;
7811428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry **bucket;
7821428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
7831428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
7841428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
7851428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real = (DBusRealHashIter*) iter;
7861428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
7876be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (* table->find_function) (table, key, create_if_not_found, &bucket, NULL);
7881428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
7891428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (entry == NULL)
7901428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    return FALSE;
7911428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
7921428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->table = table;
7931428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->bucket = bucket;
7941428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->entry = entry;
7951428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->next_entry = entry->next;
7961428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->next_bucket = (bucket - table->buckets) + 1;
7971428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  real->n_entries_on_init = table->n_entries;
7981428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
7991428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (&(table->buckets[real->next_bucket-1]) == real->bucket);
8001428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
8011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  return TRUE;
8021428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
803ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
8046be547d32f018c23ba56426a0bccd08baa2cf440Havoc Penningtonstatic void
8056be547d32f018c23ba56426a0bccd08baa2cf440Havoc Penningtonadd_allocated_entry (DBusHashTable   *table,
8066be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                     DBusHashEntry   *entry,
8076be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                     unsigned int     idx,
8086be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                     void            *key,
8096be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                     DBusHashEntry ***bucket)
8101428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
8116be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  DBusHashEntry **b;
8121428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
8131428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  entry->key = key;
8141428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
8151428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  b = &(table->buckets[idx]);
8161428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  entry->next = *b;
8171428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  *b = entry;
8181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
8191428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (bucket)
8201428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    *bucket = b;
8211428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
8221428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table->n_entries += 1;
82317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
82417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  /* note we ONLY rebuild when ADDING - because you can iterate over a
82517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington   * table and remove entries safely.
82617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington   */
82717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  if (table->n_entries >= table->hi_rebuild_size ||
82817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      table->n_entries < table->lo_rebuild_size)
8291428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    rebuild_table (table);
8306be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington}
8316be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
8326be547d32f018c23ba56426a0bccd08baa2cf440Havoc Penningtonstatic DBusHashEntry*
8336be547d32f018c23ba56426a0bccd08baa2cf440Havoc Penningtonadd_entry (DBusHashTable        *table,
8346be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington           unsigned int          idx,
8356be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington           void                 *key,
8366be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington           DBusHashEntry      ***bucket,
8376be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington           DBusPreallocatedHash *preallocated)
8386be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington{
8396be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  DBusHashEntry  *entry;
8406be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
8416be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  if (preallocated == NULL)
8426be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington    {
8436be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington      entry = alloc_entry (table);
8446be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington      if (entry == NULL)
8456be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington        {
8466be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington          if (bucket)
8476be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington            *bucket = NULL;
8486be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington          return NULL;
8496be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington        }
8506be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington    }
8516be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  else
8526be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington    {
8536be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington      entry = (DBusHashEntry*) preallocated;
8546be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington    }
8556be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
8566be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  add_allocated_entry (table, entry, idx, key, bucket);
8571428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
8581428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  return entry;
8591428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
8606be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
86195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington/* This is g_str_hash from GLib which was
86295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * extensively discussed/tested/profiled
86395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington */
864ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Penningtonstatic unsigned int
8651428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonstring_hash (const char *str)
866ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington{
86795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  const char *p = str;
86895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  unsigned int h = *p;
869ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
87095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  if (h)
87195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    for (p += 1; *p != '\0'; p++)
87295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      h = (h << 5) - h + *p;
873ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
87495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  return h;
87595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington}
87695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
8777bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
87895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington/* This hashes a memory block with two nul-terminated strings
87995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * in it, used in dbus-object-registry.c at the moment.
88095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington */
88195717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic unsigned int
88295717a938b237d12211935f6a7467ef610288fe5Havoc Penningtontwo_strings_hash (const char *str)
88395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington{
88495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  const char *p = str;
88595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  unsigned int h = *p;
88695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
88795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  if (h)
88895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    for (p += 1; *p != '\0'; p++)
88995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      h = (h << 5) - h + *p;
89095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
89195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  for (p += 1; *p != '\0'; p++)
89295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    h = (h << 5) - h + *p;
8931428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
89495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  return h;
895ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington}
8967bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
897ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
89885ab0327d82e4945ad16630e583d8cc68df25a90Havoc Pennington/** Key comparison function */
89995717a938b237d12211935f6a7467ef610288fe5Havoc Penningtontypedef int (* KeyCompareFunc) (const void *key_a, const void *key_b);
90095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
9011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonstatic DBusHashEntry*
90295717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonfind_generic_function (DBusHashTable        *table,
90395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                       void                 *key,
90495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                       unsigned int          idx,
90595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                       KeyCompareFunc        compare_func,
90695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                       dbus_bool_t           create_if_not_found,
90795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                       DBusHashEntry      ***bucket,
90895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                       DBusPreallocatedHash *preallocated)
909ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington{
9101428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry *entry;
9111428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
9121428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (bucket)
9131428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    *bucket = NULL;
9141428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
9151428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  /* Search all of the entries in this bucket. */
9161428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  entry = table->buckets[idx];
9171428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  while (entry != NULL)
9181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
91995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      if ((compare_func == NULL && key == entry->key) ||
92095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington          (compare_func != NULL && (* compare_func) (key, entry->key) == 0))
9211428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        {
9221428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          if (bucket)
9231428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington            *bucket = &(table->buckets[idx]);
9246be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
9256be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington          if (preallocated)
9266be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington            _dbus_hash_table_free_preallocated_entry (table, preallocated);
9276be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
9281428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          return entry;
9291428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        }
9301428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
9311428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      entry = entry->next;
9321428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    }
933ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
9341428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (create_if_not_found)
9356be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington    entry = add_entry (table, idx, key, bucket, preallocated);
9366be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  else if (preallocated)
9376be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington    _dbus_hash_table_free_preallocated_entry (table, preallocated);
93895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
9391428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  return entry;
940ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington}
941ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
9421428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonstatic DBusHashEntry*
94395717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonfind_string_function (DBusHashTable        *table,
9446be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                      void                 *key,
9456be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                      dbus_bool_t           create_if_not_found,
9466be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                      DBusHashEntry      ***bucket,
9476be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                      DBusPreallocatedHash *preallocated)
948ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington{
9491428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  unsigned int idx;
95095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
95195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  idx = string_hash (key) & table->mask;
9521428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
95395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  return find_generic_function (table, key, idx,
95495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                (KeyCompareFunc) strcmp, create_if_not_found, bucket,
95595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                preallocated);
95695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington}
95795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
9587bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
95995717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic int
96095717a938b237d12211935f6a7467ef610288fe5Havoc Penningtontwo_strings_cmp (const char *a,
96195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                 const char *b)
96295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington{
96395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  size_t len_a;
96495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  size_t len_b;
96595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  int res;
9661428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
96795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  res = strcmp (a, b);
96895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  if (res != 0)
96995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    return res;
9701428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
97195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  len_a = strlen (a);
97295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  len_b = strlen (b);
9736be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
97495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  return strcmp (a + len_a + 1, b + len_b + 1);
97595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington}
9767bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif
977ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
9787bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
97995717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic DBusHashEntry*
98095717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonfind_two_strings_function (DBusHashTable        *table,
98195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                           void                 *key,
98295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                           dbus_bool_t           create_if_not_found,
98395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                           DBusHashEntry      ***bucket,
98495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                           DBusPreallocatedHash *preallocated)
98595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington{
98695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  unsigned int idx;
98795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
98895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  idx = two_strings_hash (key) & table->mask;
989ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
99095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  return find_generic_function (table, key, idx,
99195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                (KeyCompareFunc) two_strings_cmp, create_if_not_found, bucket,
99295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                preallocated);
99395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington}
9947bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
99595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
99695717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic DBusHashEntry*
99795717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonfind_direct_function (DBusHashTable        *table,
99895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                      void                 *key,
99995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                      dbus_bool_t           create_if_not_found,
100095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                      DBusHashEntry      ***bucket,
100195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                      DBusPreallocatedHash *preallocated)
100295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington{
100395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  unsigned int idx;
100495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
100595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  idx = RANDOM_INDEX (table, key) & table->mask;
100695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
100795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
100895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  return find_generic_function (table, key, idx,
100995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                NULL, create_if_not_found, bucket,
101095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                preallocated);
10111428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
1012ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
10131428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonstatic void
10141428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonrebuild_table (DBusHashTable *table)
10151428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
10161428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  int old_size;
101717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  int new_buckets;
10181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry **old_buckets;
10191428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry **old_chain;
10201428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry *entry;
102117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  dbus_bool_t growing;
102217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
1023ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington  /*
10241428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington   * Allocate and initialize the new bucket array, and set up
10251428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington   * hashing constants for new array size.
1026ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington   */
102717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
102817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  growing = table->n_entries >= table->hi_rebuild_size;
10291428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
10301428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  old_size = table->n_buckets;
10311428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  old_buckets = table->buckets;
10321428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
103317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  if (growing)
103417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    {
103517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      /* overflow paranoia */
103617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      if (table->n_buckets < _DBUS_INT_MAX / 4 &&
103717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington          table->down_shift >= 0)
103817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington        new_buckets = table->n_buckets * 4;
103917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      else
104017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington        return; /* can't grow anymore */
104117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    }
104217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  else
104317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    {
104417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      new_buckets = table->n_buckets / 4;
104517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      if (new_buckets < DBUS_SMALL_HASH_TABLE)
104617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington        return; /* don't bother shrinking this far */
104717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    }
104817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
104917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  table->buckets = dbus_new0 (DBusHashEntry*, new_buckets);
10501428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (table->buckets == NULL)
10511428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
10521428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      /* out of memory, yay - just don't reallocate, the table will
10531428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington       * still work, albeit more slowly.
10541428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington       */
10551428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      table->buckets = old_buckets;
10561428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      return;
10571428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    }
1058ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
105917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  table->n_buckets = new_buckets;
106017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
106117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  if (growing)
106217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    {
106317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      table->lo_rebuild_size = table->hi_rebuild_size;
106417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      table->hi_rebuild_size *= 4;
106517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
106617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      table->down_shift -= 2;               /* keep 2 more high bits */
106717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      table->mask = (table->mask << 2) + 3; /* keep 2 more high bits */
106817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    }
106917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  else
107017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    {
107117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      table->hi_rebuild_size = table->lo_rebuild_size;
107217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      table->lo_rebuild_size /= 4;
107317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
107417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      table->down_shift += 2;         /* keep 2 fewer high bits */
107517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      table->mask = table->mask >> 2; /* keep 2 fewer high bits */
107617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    }
1077ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
107817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington#if 0
107917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  printf ("%s table to lo = %d hi = %d downshift = %d mask = 0x%x\n",
108017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington          growing ? "GROW" : "SHRINK",
108117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington          table->lo_rebuild_size,
108217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington          table->hi_rebuild_size,
108317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington          table->down_shift,
108417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington          table->mask);
108517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington#endif
108617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
108717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  _dbus_assert (table->lo_rebuild_size >= 0);
108817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  _dbus_assert (table->hi_rebuild_size > table->lo_rebuild_size);
108917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  _dbus_assert (table->mask != 0);
109017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  /* the mask is essentially the max index */
109117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  _dbus_assert (table->mask < table->n_buckets);
109217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
1093ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington  /*
10941428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington   * Rehash all of the existing entries into the new bucket array.
1095ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington   */
1096ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
10971428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  for (old_chain = old_buckets; old_size > 0; old_size--, old_chain++)
10981428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
10991428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      for (entry = *old_chain; entry != NULL; entry = *old_chain)
11001428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        {
11011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          unsigned int idx;
11021428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          DBusHashEntry **bucket;
11031428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
11041428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          *old_chain = entry->next;
11051428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          switch (table->key_type)
11061428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington            {
11071428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington            case DBUS_HASH_STRING:
11081428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington              idx = string_hash (entry->key) & table->mask;
11091428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington              break;
111095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington            case DBUS_HASH_TWO_STRINGS:
11117bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
111295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington              idx = two_strings_hash (entry->key) & table->mask;
11137bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#else
11147bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington              idx = 0;
11157bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington              _dbus_assert_not_reached ("two-strings is not enabled");
11167bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif
111795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington              break;
11181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington            case DBUS_HASH_INT:
1119c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba            case DBUS_HASH_UINTPTR:
112096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington            case DBUS_HASH_POINTER:
11211428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington              idx = RANDOM_INDEX (table, entry->key);
11221428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington              break;
11231428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington            default:
11241428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington              idx = 0;
11251428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington              _dbus_assert_not_reached ("Unknown hash table type");
11261428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington              break;
11271428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington            }
112817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
11291428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          bucket = &(table->buckets[idx]);
11301428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          entry->next = *bucket;
11311428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington          *bucket = entry;
11321428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        }
11331428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    }
11341428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
11351428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  /* Free the old bucket array, if it was dynamically allocated. */
11361428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
11371428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (old_buckets != table->static_buckets)
11381428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    dbus_free (old_buckets);
1139ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington}
1140ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
11411428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
11421428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Looks up the value for a given string in a hash table
11431428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * of type #DBUS_HASH_STRING. Returns %NULL if the value
11441428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * is not present. (A not-present entry is indistinguishable
11451428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * from an entry with a value of %NULL.)
11461428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param table the hash table.
11471428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param key the string to look up.
11481428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @returns the value of the hash entry.
11491428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
11501428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonvoid*
11511428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_table_lookup_string (DBusHashTable *table,
11521428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                const char    *key)
1153ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington{
11541428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry *entry;
1155ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
11561428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (table->key_type == DBUS_HASH_STRING);
11571428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
11586be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (* table->find_function) (table, (char*) key, FALSE, NULL, NULL);
1159ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
11601428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (entry)
11611428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    return entry->value;
11621428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  else
11631428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    return NULL;
11641428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
1165ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
11667bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
11671428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
116895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * Looks up the value for a given string in a hash table
116995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * of type #DBUS_HASH_TWO_STRINGS. Returns %NULL if the value
117095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * is not present. (A not-present entry is indistinguishable
117195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * from an entry with a value of %NULL.)
117295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param table the hash table.
117395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param key the string to look up.
117495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @returns the value of the hash entry.
117595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington */
117695717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonvoid*
117795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington_dbus_hash_table_lookup_two_strings (DBusHashTable *table,
117895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                     const char    *key)
117995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington{
118095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  DBusHashEntry *entry;
118195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
118295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
118395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
118495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  entry = (* table->find_function) (table, (char*) key, FALSE, NULL, NULL);
118595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
118695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  if (entry)
118795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    return entry->value;
118895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  else
118995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    return NULL;
119095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington}
11917bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
119295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
119395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington/**
11941428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Looks up the value for a given integer in a hash table
11951428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * of type #DBUS_HASH_INT. Returns %NULL if the value
11961428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * is not present. (A not-present entry is indistinguishable
11971428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * from an entry with a value of %NULL.)
11981428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param table the hash table.
11991428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param key the integer to look up.
12001428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @returns the value of the hash entry.
12011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
12021428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonvoid*
12031428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_table_lookup_int (DBusHashTable *table,
12041428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                             int            key)
12051428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
12061428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry *entry;
12071428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
12081428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (table->key_type == DBUS_HASH_INT);
12091428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
12106be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, NULL, NULL);
12111428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
12121428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (entry)
12131428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    return entry->value;
12141428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  else
12151428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    return NULL;
1216ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington}
12171428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
1218d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington#ifdef DBUS_BUILD_TESTS
1219d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington/* disabled since it's only used for testing */
12201428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
122196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * Looks up the value for a given integer in a hash table
122296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * of type #DBUS_HASH_POINTER. Returns %NULL if the value
122396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * is not present. (A not-present entry is indistinguishable
122496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * from an entry with a value of %NULL.)
122596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * @param table the hash table.
122696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * @param key the integer to look up.
122796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * @returns the value of the hash entry.
122896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington */
122996a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonvoid*
123096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington_dbus_hash_table_lookup_pointer (DBusHashTable *table,
123196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                 void          *key)
123296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington{
123396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  DBusHashEntry *entry;
123496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
123596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  _dbus_assert (table->key_type == DBUS_HASH_POINTER);
123696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
12376be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (* table->find_function) (table, key, FALSE, NULL, NULL);
123896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
123996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  if (entry)
124096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    return entry->value;
124196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  else
124296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    return NULL;
124396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington}
1244d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington#endif /* DBUS_BUILD_TESTS */
124596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
124696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington/**
1247a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * Looks up the value for a given integer in a hash table
1248c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba * of type #DBUS_HASH_UINTPTR. Returns %NULL if the value
1249a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * is not present. (A not-present entry is indistinguishable
1250a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * from an entry with a value of %NULL.)
1251a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * @param table the hash table.
1252a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * @param key the integer to look up.
1253a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * @returns the value of the hash entry.
1254a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington */
1255a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Penningtonvoid*
1256c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba_dbus_hash_table_lookup_uintptr (DBusHashTable *table,
1257c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba                                 uintptr_t      key)
1258a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington{
1259a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  DBusHashEntry *entry;
1260a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1261c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba  _dbus_assert (table->key_type == DBUS_HASH_UINTPTR);
1262a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
12636be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (* table->find_function) (table, (void*) key, FALSE, NULL, NULL);
1264a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1265a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  if (entry)
1266a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington    return entry->value;
1267a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  else
1268a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington    return NULL;
1269a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington}
1270a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1271a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington/**
12721428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Removes the hash entry for the given key. If no hash entry
12731428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * for the key exists, does nothing.
1274ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
12751428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param table the hash table.
12761428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param key the hash key.
1277576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington * @returns #TRUE if the entry existed
1278ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
1279576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Penningtondbus_bool_t
12801428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_table_remove_string (DBusHashTable *table,
12811428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                const char    *key)
1282ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington{
12831428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry *entry;
12841428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry **bucket;
12851428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
12861428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (table->key_type == DBUS_HASH_STRING);
12871428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
12886be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (* table->find_function) (table, (char*) key, FALSE, &bucket, NULL);
12891428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
12901428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (entry)
1291576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington    {
1292576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington      remove_entry (table, bucket, entry);
1293576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington      return TRUE;
1294576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington    }
1295576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington  else
1296576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington    return FALSE;
12971428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
1298ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
12997bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
13001428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
13011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Removes the hash entry for the given key. If no hash entry
13021428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * for the key exists, does nothing.
13031428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
13041428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param table the hash table.
13051428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param key the hash key.
1306576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington * @returns #TRUE if the entry existed
13071428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
1308576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Penningtondbus_bool_t
130995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington_dbus_hash_table_remove_two_strings (DBusHashTable *table,
131095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                     const char    *key)
131195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington{
131295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  DBusHashEntry *entry;
131395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  DBusHashEntry **bucket;
131495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
131595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
131695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
131795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  entry = (* table->find_function) (table, (char*) key, FALSE, &bucket, NULL);
131895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
131995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  if (entry)
132095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    {
132195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      remove_entry (table, bucket, entry);
132295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      return TRUE;
132395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    }
132495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  else
132595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    return FALSE;
132695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington}
13277bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
132895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
132995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington/**
133095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * Removes the hash entry for the given key. If no hash entry
133195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * for the key exists, does nothing.
133295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington *
133395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param table the hash table.
133495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param key the hash key.
133595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @returns #TRUE if the entry existed
133695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington */
133795717a938b237d12211935f6a7467ef610288fe5Havoc Penningtondbus_bool_t
13381428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_table_remove_int (DBusHashTable *table,
13391428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                             int            key)
13401428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
13411428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry *entry;
13421428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry **bucket;
13431428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
13441428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (table->key_type == DBUS_HASH_INT);
13451428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
13466be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, &bucket, NULL);
13471428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
13481428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (entry)
1349576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington    {
1350576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington      remove_entry (table, bucket, entry);
1351576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington      return TRUE;
1352576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington    }
1353576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington  else
1354576cdb6e0b1274e9fa5276e01337aef330dd4e8cHavoc Pennington    return FALSE;
13551428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
1356ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
1357d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington#ifdef DBUS_BUILD_TESTS
1358d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington/* disabled since it's only used for testing */
13591428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
136096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * Removes the hash entry for the given key. If no hash entry
136196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * for the key exists, does nothing.
136296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington *
136396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * @param table the hash table.
136496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * @param key the hash key.
136596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * @returns #TRUE if the entry existed
136696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington */
136796a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtondbus_bool_t
136896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington_dbus_hash_table_remove_pointer (DBusHashTable *table,
136996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                 void          *key)
137096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington{
137196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  DBusHashEntry *entry;
137296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  DBusHashEntry **bucket;
137396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
137496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  _dbus_assert (table->key_type == DBUS_HASH_POINTER);
137596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
13766be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (* table->find_function) (table, key, FALSE, &bucket, NULL);
137796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
137896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  if (entry)
137996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    {
138096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington      remove_entry (table, bucket, entry);
138196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington      return TRUE;
138296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    }
138396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  else
138496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    return FALSE;
138596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington}
1386d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington#endif /* DBUS_BUILD_TESTS */
138796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
138896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington/**
1389a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * Removes the hash entry for the given key. If no hash entry
1390a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * for the key exists, does nothing.
1391a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington *
1392a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * @param table the hash table.
1393a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * @param key the hash key.
1394a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * @returns #TRUE if the entry existed
1395a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington */
1396a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Penningtondbus_bool_t
1397c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba_dbus_hash_table_remove_uintptr (DBusHashTable *table,
1398c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba                                 uintptr_t      key)
1399a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington{
1400a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  DBusHashEntry *entry;
1401a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  DBusHashEntry **bucket;
1402a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1403c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba  _dbus_assert (table->key_type == DBUS_HASH_UINTPTR);
1404a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
14056be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (* table->find_function) (table, (void*) key, FALSE, &bucket, NULL);
1406a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1407a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  if (entry)
1408a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington    {
1409a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington      remove_entry (table, bucket, entry);
1410a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington      return TRUE;
1411a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington    }
1412a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  else
1413a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington    return FALSE;
1414a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington}
1415a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1416a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington/**
14171428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Creates a hash entry with the given key and value.
14181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * The key and value are not copied; they are stored
14191428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * in the hash table by reference. If an entry with the
14201428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * given key already exists, the previous key and value
14211428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * are overwritten (and freed if the hash table has
14221428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * a key_free_function and/or value_free_function).
14231428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
14241428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Returns #FALSE if memory for the new hash entry
14251428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * can't be allocated.
14261428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
14271428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param table the hash table.
14281428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param key the hash entry key.
14291428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param value the hash entry value.
14301428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
14311428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtondbus_bool_t
14321428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_table_insert_string (DBusHashTable *table,
14331428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                char          *key,
14341428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                void          *value)
14351428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
14366be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  DBusPreallocatedHash *preallocated;
1437ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
14381428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (table->key_type == DBUS_HASH_STRING);
1439ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
14406be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  preallocated = _dbus_hash_table_preallocate_entry (table);
14416be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  if (preallocated == NULL)
14426be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington    return FALSE;
1443ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
14446be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  _dbus_hash_table_insert_string_preallocated (table, preallocated,
14456be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                                               key, value);
14466be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
14471428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  return TRUE;
1448ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington}
14491428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
14507bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
14511428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
14521428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Creates a hash entry with the given key and value.
14531428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * The key and value are not copied; they are stored
14541428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * in the hash table by reference. If an entry with the
14551428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * given key already exists, the previous key and value
14561428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * are overwritten (and freed if the hash table has
14571428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * a key_free_function and/or value_free_function).
1458ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
14591428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Returns #FALSE if memory for the new hash entry
14601428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * can't be allocated.
14611428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington *
14621428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param table the hash table.
14631428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param key the hash entry key.
14641428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param value the hash entry value.
1465ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
14661428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtondbus_bool_t
146795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington_dbus_hash_table_insert_two_strings (DBusHashTable *table,
146895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                     char          *key,
146995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                     void          *value)
147095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington{
147168a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington  DBusHashEntry *entry;
147268a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington
147395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
147468a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington
147568a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington  entry = (* table->find_function) (table, key, TRUE, NULL, NULL);
147695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
147768a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington  if (entry == NULL)
147868a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington    return FALSE; /* no memory */
147995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
148068a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington  if (table->free_key_function && entry->key != key)
148168a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington    (* table->free_key_function) (entry->key);
148268a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington
148368a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington  if (table->free_value_function && entry->value != value)
148468a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington    (* table->free_value_function) (entry->value);
148595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
148668a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington  entry->key = key;
148768a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington  entry->value = value;
148868a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington
148995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  return TRUE;
149095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington}
14917bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
149295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
149395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington/**
149495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * Creates a hash entry with the given key and value.
149595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * The key and value are not copied; they are stored
149695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * in the hash table by reference. If an entry with the
149795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * given key already exists, the previous key and value
149895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * are overwritten (and freed if the hash table has
149995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * a key_free_function and/or value_free_function).
150095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington *
150195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * Returns #FALSE if memory for the new hash entry
150295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * can't be allocated.
150395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington *
150495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param table the hash table.
150595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param key the hash entry key.
150695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param value the hash entry value.
150795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington */
150895717a938b237d12211935f6a7467ef610288fe5Havoc Penningtondbus_bool_t
15091428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_table_insert_int (DBusHashTable *table,
15101428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                             int            key,
15111428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                             void          *value)
1512ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington{
15131428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashEntry *entry;
1514ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
15151428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (table->key_type == DBUS_HASH_INT);
15161428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
15176be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), TRUE, NULL, NULL);
1518ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
15191428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (entry == NULL)
15201428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    return FALSE; /* no memory */
1521ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
15221428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (table->free_key_function && entry->key != _DBUS_INT_TO_POINTER (key))
15231428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    (* table->free_key_function) (entry->key);
15241428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
15251428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (table->free_value_function && entry->value != value)
15261428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    (* table->free_value_function) (entry->value);
15271428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
15281428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  entry->key = _DBUS_INT_TO_POINTER (key);
15291428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  entry->value = value;
15301428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
15311428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  return TRUE;
1532ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington}
15331428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
1534d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington#ifdef DBUS_BUILD_TESTS
1535d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington/* disabled since it's only used for testing */
15361428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
153796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * Creates a hash entry with the given key and value.
153896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * The key and value are not copied; they are stored
153996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * in the hash table by reference. If an entry with the
154096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * given key already exists, the previous key and value
154196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * are overwritten (and freed if the hash table has
154296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * a key_free_function and/or value_free_function).
154396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington *
154496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * Returns #FALSE if memory for the new hash entry
154596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * can't be allocated.
154696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington *
154796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * @param table the hash table.
154896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * @param key the hash entry key.
154996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * @param value the hash entry value.
155096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington */
155196a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtondbus_bool_t
155296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington_dbus_hash_table_insert_pointer (DBusHashTable *table,
155396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                 void          *key,
155496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                 void          *value)
155596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington{
155696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  DBusHashEntry *entry;
155796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
155896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  _dbus_assert (table->key_type == DBUS_HASH_POINTER);
155996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
15606be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (* table->find_function) (table, key, TRUE, NULL, NULL);
156196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
156296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  if (entry == NULL)
156396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    return FALSE; /* no memory */
156496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
156596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  if (table->free_key_function && entry->key != key)
156696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    (* table->free_key_function) (entry->key);
156796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
156896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  if (table->free_value_function && entry->value != value)
156996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    (* table->free_value_function) (entry->value);
157096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
157196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  entry->key = key;
157296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  entry->value = value;
157396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
157496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  return TRUE;
157596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington}
1576d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington#endif /* DBUS_BUILD_TESTS */
1577a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1578a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington/**
1579a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * Creates a hash entry with the given key and value.
1580a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * The key and value are not copied; they are stored
1581a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * in the hash table by reference. If an entry with the
1582a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * given key already exists, the previous key and value
1583a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * are overwritten (and freed if the hash table has
1584a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * a key_free_function and/or value_free_function).
1585a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington *
1586a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * Returns #FALSE if memory for the new hash entry
1587a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * can't be allocated.
1588a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington *
1589a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * @param table the hash table.
1590a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * @param key the hash entry key.
1591a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington * @param value the hash entry value.
1592a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington */
1593a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Penningtondbus_bool_t
1594c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba_dbus_hash_table_insert_uintptr (DBusHashTable *table,
1595c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba                                 uintptr_t      key,
1596c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba                                 void          *value)
1597a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington{
1598a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  DBusHashEntry *entry;
1599a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1600c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba  _dbus_assert (table->key_type == DBUS_HASH_UINTPTR);
1601a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
16026be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (* table->find_function) (table, (void*) key, TRUE, NULL, NULL);
1603a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1604a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  if (entry == NULL)
1605a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington    return FALSE; /* no memory */
1606a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1607a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  if (table->free_key_function && entry->key != (void*) key)
1608a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington    (* table->free_key_function) (entry->key);
1609a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1610a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  if (table->free_value_function && entry->value != value)
1611a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington    (* table->free_value_function) (entry->value);
1612a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1613a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  entry->key = (void*) key;
1614a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  entry->value = value;
1615a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1616a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  return TRUE;
1617a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington}
1618a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
161996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington/**
16206be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * Preallocate an opaque data blob that allows us to insert into the
16216be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * hash table at a later time without allocating any memory.
16226be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington *
16236be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * @param table the hash table
16246be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * @returns the preallocated data, or #NULL if no memory
16256be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington */
16266be547d32f018c23ba56426a0bccd08baa2cf440Havoc PenningtonDBusPreallocatedHash*
16276be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington_dbus_hash_table_preallocate_entry (DBusHashTable *table)
16286be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington{
16296be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  DBusHashEntry *entry;
16306be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16316be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = alloc_entry (table);
16326be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16336be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  return (DBusPreallocatedHash*) entry;
16346be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington}
16356be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16366be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington/**
16376be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * Frees an opaque DBusPreallocatedHash that was *not* used
16386be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * in order to insert into the hash table.
16396be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington *
16406be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * @param table the hash table
16416be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * @param preallocated the preallocated data
16426be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington */
16436be547d32f018c23ba56426a0bccd08baa2cf440Havoc Penningtonvoid
16446be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington_dbus_hash_table_free_preallocated_entry (DBusHashTable        *table,
16456be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                                          DBusPreallocatedHash *preallocated)
16466be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington{
16476be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  DBusHashEntry *entry;
16486be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16496be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  _dbus_assert (preallocated != NULL);
16506be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16516be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (DBusHashEntry*) preallocated;
16526be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16536be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  /* Don't use free_entry(), since this entry has no key/data */
16546be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  _dbus_mem_pool_dealloc (table->entry_pool, entry);
16556be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington}
16566be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16576be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington/**
16586be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * Inserts a string-keyed entry into the hash table, using a
16596be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * preallocated data block from
16606be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * _dbus_hash_table_preallocate_entry(). This function cannot fail due
16616be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * to lack of memory. The DBusPreallocatedHash object is consumed and
16626be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * should not be reused or freed. Otherwise this function works
16636be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * just like _dbus_hash_table_insert_string().
16646be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington *
16656be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * @param table the hash table
16666be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * @param preallocated the preallocated data
16676be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * @param key the hash key
16686be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington * @param value the value
16696be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington */
16706be547d32f018c23ba56426a0bccd08baa2cf440Havoc Penningtonvoid
16716be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington_dbus_hash_table_insert_string_preallocated (DBusHashTable        *table,
16726be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                                             DBusPreallocatedHash *preallocated,
16736be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                                             char                 *key,
16746be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington                                             void                 *value)
16756be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington{
16766be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  DBusHashEntry *entry;
16776be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16786be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  _dbus_assert (table->key_type == DBUS_HASH_STRING);
16796be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  _dbus_assert (preallocated != NULL);
16806be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16816be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry = (* table->find_function) (table, key, TRUE, NULL, preallocated);
16826be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16836be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  _dbus_assert (entry != NULL);
16846be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16856be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  if (table->free_key_function && entry->key != key)
16866be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington    (* table->free_key_function) (entry->key);
16876be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16886be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  if (table->free_value_function && entry->value != value)
16896be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington    (* table->free_value_function) (entry->value);
16906be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16916be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry->key = key;
16926be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington  entry->value = value;
16936be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington}
16946be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington
16956be547d32f018c23ba56426a0bccd08baa2cf440Havoc Pennington/**
16961428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Gets the number of hash entries in a hash table.
1697ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington *
16981428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @param table the hash table.
16991428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @returns the number of entries in the table.
1700ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington */
17011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonint
17021428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_table_get_n_entries (DBusHashTable *table)
17031428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
17041428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  return table->n_entries;
17051428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
1706ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
170755de3878c42f8254bac653b7c1998e79a1658ae2Havoc Pennington/** @} */
17081428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
17091428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington#ifdef DBUS_BUILD_TESTS
17101428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington#include "dbus-test.h"
17111428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington#include <stdio.h>
17121428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
171317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington/* If you're wondering why the hash table test takes
171417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * forever to run, it's because we call this function
171517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington * in inner loops thus making things quadratic.
171617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington */
17171428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtonstatic int
17181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtoncount_entries (DBusHashTable *table)
1719ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington{
17201428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashIter iter;
17211428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  int count;
1722ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
17231428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  count = 0;
17241428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_iter_init (table, &iter);
17251428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  while (_dbus_hash_iter_next (&iter))
17261428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    ++count;
1727ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
17281428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_assert (count == _dbus_hash_table_get_n_entries (table));
17291428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
17301428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  return count;
17311428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington}
17321428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
173395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington/* Copy the foo\0bar\0 double string thing */
173495717a938b237d12211935f6a7467ef610288fe5Havoc Penningtonstatic char*
173595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington_dbus_strdup2 (const char *str)
173695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington{
173795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  size_t len;
173895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  char *copy;
173995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
174095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  if (str == NULL)
174195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    return NULL;
174295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
174395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  len = strlen (str);
174495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  len += strlen ((str + len + 1));
174595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
174695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  copy = dbus_malloc (len + 2);
174795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  if (copy == NULL)
174895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    return NULL;
174995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
175095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  memcpy (copy, str, len + 2);
175195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
175295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  return copy;
175395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington}
175495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
17551428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington/**
17561428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @ingroup DBusHashTableInternals
17571428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * Unit test for DBusHashTable
17581428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington * @returns #TRUE on success.
17591428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington */
17601428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Penningtondbus_bool_t
17611428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington_dbus_hash_test (void)
17621428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington{
17631428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  int i;
17641428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashTable *table1;
17651428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashTable *table2;
1766a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  DBusHashTable *table3;
176795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  DBusHashTable *table4;
17681428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  DBusHashIter iter;
176917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington#define N_HASH_KEYS 5000
17709ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw  char **keys;
17719ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw  dbus_bool_t ret = FALSE;
17729ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw
17739ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw  keys = dbus_new (char *, N_HASH_KEYS);
17749ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw  if (keys == NULL)
17759ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw    _dbus_assert_not_reached ("no memory");
17769ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw
17779ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw  for (i = 0; i < N_HASH_KEYS; i++)
17789ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw    {
17799ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw      keys[i] = dbus_malloc (128);
17809ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw
17819ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw      if (keys[i] == NULL)
17829ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw	_dbus_assert_not_reached ("no memory");
17839ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw    }
178417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
178517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  printf ("Computing test hash keys...\n");
178617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  i = 0;
178717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  while (i < N_HASH_KEYS)
178817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    {
178995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      int len;
179095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
179195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      /* all the hash keys are TWO_STRINGS, but
179295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington       * then we can also use those as regular strings.
179395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington       */
179495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
179595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      len = sprintf (keys[i], "Hash key %d", i);
179695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      sprintf (keys[i] + len + 1, "Two string %d", i);
179795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      _dbus_assert (*(keys[i] + len) == '\0');
179895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      _dbus_assert (*(keys[i] + len + 1) != '\0');
179917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      ++i;
180017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    }
180117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  printf ("... done.\n");
18021428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
18031428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
18041428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                 dbus_free, dbus_free);
18051428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (table1 == NULL)
18069ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw    goto out;
18071428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
18081428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table2 = _dbus_hash_table_new (DBUS_HASH_INT,
18091428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                 NULL, dbus_free);
18101428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (table2 == NULL)
18119ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw    goto out;
18121428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
1813c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba  table3 = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
1814a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington                                 NULL, dbus_free);
1815a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  if (table3 == NULL)
1816a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington    goto out;
181795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
181895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  table4 = _dbus_hash_table_new (DBUS_HASH_TWO_STRINGS,
181995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                 dbus_free, dbus_free);
182095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  if (table4 == NULL)
182195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    goto out;
182295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
1823a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
18241428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  /* Insert and remove a bunch of stuff, counting the table in between
18251428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington   * to be sure it's not broken and that iteration works
1826ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington   */
18271428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  i = 0;
18281428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  while (i < 3000)
18291428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
18301428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      void *value;
18311428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      char *key;
18321428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
183317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      key = _dbus_strdup (keys[i]);
18341428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (key == NULL)
18359ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
18361428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      value = _dbus_strdup ("Value!");
18371428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (value == NULL)
18389ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
18391428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
18401428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (!_dbus_hash_table_insert_string (table1,
18411428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                           key, value))
18429ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
18431428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
184417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      value = _dbus_strdup (keys[i]);
18451428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (value == NULL)
18469ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
18471428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
18481428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (!_dbus_hash_table_insert_int (table2,
18491428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        i, value))
18509ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
1851a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1852a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington      value = _dbus_strdup (keys[i]);
1853a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington      if (value == NULL)
1854a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington        goto out;
1855a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1856c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba      if (!_dbus_hash_table_insert_uintptr (table3,
1857a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington                                          i, value))
1858a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington        goto out;
185995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
186095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      key = _dbus_strdup2 (keys[i]);
186195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      if (key == NULL)
186295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington        goto out;
186395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      value = _dbus_strdup ("Value!");
186495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      if (value == NULL)
186595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington        goto out;
186695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
186768a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington      if (!_dbus_hash_table_insert_two_strings (table4,
186868a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington                                                key, value))
186995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington        goto out;
18701428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
18711428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (count_entries (table1) == i + 1);
18721428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (count_entries (table2) == i + 1);
1873a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington      _dbus_assert (count_entries (table3) == i + 1);
187495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      _dbus_assert (count_entries (table4) == i + 1);
18751428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
187617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      value = _dbus_hash_table_lookup_string (table1, keys[i]);
18771428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (value != NULL);
18781428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (strcmp (value, "Value!") == 0);
18791428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
18801428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      value = _dbus_hash_table_lookup_int (table2, i);
18811428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (value != NULL);
188217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      _dbus_assert (strcmp (value, keys[i]) == 0);
1883a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
1884c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba      value = _dbus_hash_table_lookup_uintptr (table3, i);
1885a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington      _dbus_assert (value != NULL);
1886a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington      _dbus_assert (strcmp (value, keys[i]) == 0);
188795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
188868a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington      value = _dbus_hash_table_lookup_two_strings (table4, keys[i]);
188995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      _dbus_assert (value != NULL);
189068a3c593b9e77b33614726363c7b6fd85d113021Havoc Pennington      _dbus_assert (strcmp (value, "Value!") == 0);
18911428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
18921428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      ++i;
18931428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    }
1894ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
18951428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  --i;
18961428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  while (i >= 0)
18971428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
18981428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_hash_table_remove_string (table1,
189917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington                                      keys[i]);
19001428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
19011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_hash_table_remove_int (table2, i);
19021428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
1903c096c5cb9ac636626e158ed327b3d9279c4de347Fridrich Å trba      _dbus_hash_table_remove_uintptr (table3, i);
1904a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington
190595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      _dbus_hash_table_remove_two_strings (table4,
190695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                           keys[i]);
190795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
19081428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (count_entries (table1) == i);
19091428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (count_entries (table2) == i);
1910a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington      _dbus_assert (count_entries (table3) == i);
191195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      _dbus_assert (count_entries (table4) == i);
19121428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
19131428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      --i;
1914ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington    }
1915ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
19161428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_table_ref (table1);
19171428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_table_ref (table2);
1918a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  _dbus_hash_table_ref (table3);
191995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  _dbus_hash_table_ref (table4);
19201428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_table_unref (table1);
19211428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_table_unref (table2);
1922a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  _dbus_hash_table_unref (table3);
192395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  _dbus_hash_table_unref (table4);
19241428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_table_unref (table1);
19251428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_table_unref (table2);
1926a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  _dbus_hash_table_unref (table3);
192795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  _dbus_hash_table_unref (table4);
1928a26607ab68bf0878f23d2dbddec781b4b760d034Havoc Pennington  table3 = NULL;
1929ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
19301428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  /* Insert a bunch of stuff then check
19311428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington   * that iteration works correctly (finds the right
19321428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington   * values, iter_set_value works, etc.)
1933ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington   */
19341428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
19351428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                 dbus_free, dbus_free);
19361428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (table1 == NULL)
19379ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw    goto out;
19381428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
19391428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table2 = _dbus_hash_table_new (DBUS_HASH_INT,
19401428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                 NULL, dbus_free);
19411428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (table2 == NULL)
19429ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw    goto out;
19431428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
19441428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  i = 0;
19451428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  while (i < 5000)
19461428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
19471428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      char *key;
19481428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      void *value;
19491428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
195017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      key = _dbus_strdup (keys[i]);
19511428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (key == NULL)
19529ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
19531428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      value = _dbus_strdup ("Value!");
19541428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (value == NULL)
19559ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
19561428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
19571428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (!_dbus_hash_table_insert_string (table1,
19581428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                           key, value))
19599ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
19601428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
196117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      value = _dbus_strdup (keys[i]);
19621428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (value == NULL)
19639ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
19641428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
19651428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (!_dbus_hash_table_insert_int (table2,
19661428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                        i, value))
19679ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
19681428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
19691428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (count_entries (table1) == i + 1);
19701428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (count_entries (table2) == i + 1);
19711428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
19721428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      ++i;
19731428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    }
1974ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
19751428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_iter_init (table1, &iter);
19761428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  while (_dbus_hash_iter_next (&iter))
19771428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
19781428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      const char *key;
19791428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      void *value;
1980ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
19811428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      key = _dbus_hash_iter_get_string_key (&iter);
19821428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      value = _dbus_hash_iter_get_value (&iter);
1983ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
19841428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
1985ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
19861428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      value = _dbus_strdup ("Different value!");
19871428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (value == NULL)
19889ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
19891428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
19901428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_hash_iter_set_value (&iter, value);
1991ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
19921428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
19931428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    }
19941428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
19951428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_iter_init (table1, &iter);
19961428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  while (_dbus_hash_iter_next (&iter))
19971428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
19981428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_hash_iter_remove_entry (&iter);
19991428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (count_entries (table1) == i - 1);
20001428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      --i;
20011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    }
2002ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
20031428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_iter_init (table2, &iter);
20041428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  while (_dbus_hash_iter_next (&iter))
20051428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
20061428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      int key;
20071428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      void *value;
2008ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
20091428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      key = _dbus_hash_iter_get_int_key (&iter);
20101428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      value = _dbus_hash_iter_get_value (&iter);
2011ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
20121428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
2013ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
20141428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      value = _dbus_strdup ("Different value!");
20151428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (value == NULL)
20169ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
20171428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
20181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_hash_iter_set_value (&iter, value);
20191428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
20201428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
2021ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington    }
2022ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
20231428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  i = count_entries (table2);
20241428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_iter_init (table2, &iter);
20251428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  while (_dbus_hash_iter_next (&iter))
20261428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
20271428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_hash_iter_remove_entry (&iter);
20281428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (count_entries (table2) + 1 == i);
20291428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      --i;
20301428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    }
203117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
203217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  /* add/remove interleaved, to check that we grow/shrink the table
203317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington   * appropriately
203417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington   */
203517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  i = 0;
203617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  while (i < 1000)
203717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    {
203817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      char *key;
203917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      void *value;
204017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
204117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      key = _dbus_strdup (keys[i]);
204217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      if (key == NULL)
20439ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
204417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
204517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      value = _dbus_strdup ("Value!");
204617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      if (value == NULL)
20479ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
204817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
204917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      if (!_dbus_hash_table_insert_string (table1,
205017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington                                           key, value))
20519ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
205217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
205317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      ++i;
205417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    }
205517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
205617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  --i;
205717fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  while (i >= 0)
205817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    {
205917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      char *key;
206017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      void *value;
206117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
206217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      key = _dbus_strdup (keys[i]);
206317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      if (key == NULL)
20649ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
206517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      value = _dbus_strdup ("Value!");
206617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      if (value == NULL)
20679ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
206817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
206917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      if (!_dbus_hash_table_remove_string (table1, keys[i]))
20709ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
207117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
207217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      if (!_dbus_hash_table_insert_string (table1,
207317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington                                           key, value))
20749ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
207517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
207617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      if (!_dbus_hash_table_remove_string (table1, keys[i]))
20779ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
207817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
207917fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      _dbus_assert (_dbus_hash_table_get_n_entries (table1) == i);
208017fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
208117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      --i;
208217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington    }
208317fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
208417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  /* nuke these tables */
20851428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_table_unref (table1);
20861428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_table_unref (table2);
20871428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
20881428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
20891428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  /* Now do a bunch of things again using _dbus_hash_iter_lookup() to
20901428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington   * be sure that interface works.
2091ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington   */
20921428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
20931428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                 dbus_free, dbus_free);
20941428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (table1 == NULL)
20959ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw    goto out;
20961428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
20971428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  table2 = _dbus_hash_table_new (DBUS_HASH_INT,
20981428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                 NULL, dbus_free);
20991428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  if (table2 == NULL)
21009ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw    goto out;
21011428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21021428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  i = 0;
21031428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  while (i < 3000)
21041428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
21051428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      void *value;
21061428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      char *key;
21071428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
210817fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      key = _dbus_strdup (keys[i]);
21091428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (key == NULL)
21109ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
21111428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      value = _dbus_strdup ("Value!");
21121428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (value == NULL)
21139ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
21141428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21151428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (!_dbus_hash_iter_lookup (table1,
21161428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                   key, TRUE, &iter))
21179ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
21181428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
21191428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_hash_iter_set_value (&iter, value);
21201428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
212117fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      value = _dbus_strdup (keys[i]);
21221428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (value == NULL)
21239ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
21241428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21251428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (!_dbus_hash_iter_lookup (table2,
21261428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington                                   _DBUS_INT_TO_POINTER (i), TRUE, &iter))
21279ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
21281428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
21291428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_hash_iter_set_value (&iter, value);
21301428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21311428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (count_entries (table1) == i + 1);
21321428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (count_entries (table2) == i + 1);
21331428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
213417fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
21359ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
21361428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21371428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      value = _dbus_hash_iter_get_value (&iter);
21381428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (value != NULL);
21391428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (strcmp (value, "Value!") == 0);
21401428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21411428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      /* Iterate just to be sure it works, though
21421428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington       * it's a stupid thing to do
21431428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington       */
21441428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      while (_dbus_hash_iter_next (&iter))
21451428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        ;
21461428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21471428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
21489ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw        goto out;
21491428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21501428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      value = _dbus_hash_iter_get_value (&iter);
21511428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (value != NULL);
215217fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      _dbus_assert (strcmp (value, keys[i]) == 0);
21531428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21541428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      /* Iterate just to be sure it works, though
21551428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington       * it's a stupid thing to do
21561428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington       */
21571428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      while (_dbus_hash_iter_next (&iter))
21581428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        ;
21591428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21601428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      ++i;
21611428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    }
21621428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21631428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  --i;
21641428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  while (i >= 0)
21651428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    {
216617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington      if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
21671428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        _dbus_assert_not_reached ("hash entry should have existed");
21681428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_hash_iter_remove_entry (&iter);
21691428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21701428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
21711428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington        _dbus_assert_not_reached ("hash entry should have existed");
21721428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_hash_iter_remove_entry (&iter);
21731428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21741428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (count_entries (table1) == i);
21751428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      _dbus_assert (count_entries (table2) == i);
21761428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21771428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington      --i;
21781428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington    }
21791428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21801428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_table_unref (table1);
21811428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington  _dbus_hash_table_unref (table2);
2182ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
21839ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw  ret = TRUE;
21849ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw
21859ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw out:
21869ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw  for (i = 0; i < N_HASH_KEYS; i++)
21879ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw    dbus_free (keys[i]);
21889ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw
21899ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw  dbus_free (keys);
21901428c65e7c46fd9f52e43b7424c56552ec2686e8Havoc Pennington
21919ada6e2cad0d623fb578f349790a0c62297d2394Joe Shaw  return ret;
2192ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington}
2193ca8603a9eaa0d639ecf96526ac58c534314c9f23Havoc Pennington
2194d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#endif /* DBUS_BUILD_TESTS */
2195