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