Coverage report for dbus/dbus-hash.c.gcov
-: 0:Source:dbus-hash.c
-: 0:Graph:.libs/dbus-hash.gcno
-: 0:Data:.libs/dbus-hash.gcda
-: 0:Runs:11817
-: 0:Programs:5
-: 1:/* -*- mode: C; c-file-style: "gnu" -*- */
-: 2:/* dbus-hash.c Generic hash table utility (internal to D-BUS implementation)
-: 3: *
-: 4: * Copyright (C) 2002 Red Hat, Inc.
-: 5: * Copyright (c) 1991-1993 The Regents of the University of California.
-: 6: * Copyright (c) 1994 Sun Microsystems, Inc.
-: 7: *
-: 8: * Hash table implementation based on generic/tclHash.c from the Tcl
-: 9: * source code. The original Tcl license applies to portions of the
-: 10: * code from tclHash.c; the Tcl license follows this standad D-BUS
-: 11: * license information.
-: 12: *
-: 13: * Licensed under the Academic Free License version 2.1
-: 14: *
-: 15: * This program is free software; you can redistribute it and/or modify
-: 16: * it under the terms of the GNU General Public License as published by
-: 17: * the Free Software Foundation; either version 2 of the License, or
-: 18: * (at your option) any later version.
-: 19: *
-: 20: * This program is distributed in the hope that it will be useful,
-: 21: * but WITHOUT ANY WARRANTY; without even the implied warranty of
-: 22: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-: 23: * GNU General Public License for more details.
-: 24: *
-: 25: * You should have received a copy of the GNU General Public License
-: 26: * along with this program; if not, write to the Free Software
-: 27: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-: 28: *
-: 29: */
-: 30:/*
-: 31: * The following copyright applies to code from the Tcl distribution.
-: 32: *
-: 33: * Copyright (c) 1991-1993 The Regents of the University of California.
-: 34: * Copyright (c) 1994 Sun Microsystems, Inc.
-: 35: *
-: 36: * This software is copyrighted by the Regents of the University of
-: 37: * California, Sun Microsystems, Inc., Scriptics Corporation, and
-: 38: * other parties. The following terms apply to all files associated
-: 39: * with the software unless explicitly disclaimed in individual files.
-: 40: *
-: 41: * The authors hereby grant permission to use, copy, modify,
-: 42: * distribute, and license this software and its documentation for any
-: 43: * purpose, provided that existing copyright notices are retained in
-: 44: * all copies and that this notice is included verbatim in any
-: 45: * distributions. No written agreement, license, or royalty fee is
-: 46: * required for any of the authorized uses. Modifications to this
-: 47: * software may be copyrighted by their authors and need not follow
-: 48: * the licensing terms described here, provided that the new terms are
-: 49: * clearly indicated on the first page of each file where they apply.
-: 50: *
-: 51: * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
-: 52: * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
-: 53: * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
-: 54: * OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
-: 55: * OF THE POSSIBILITY OF SUCH DAMAGE.
-: 56: *
-: 57: * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
-: 58: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-: 59: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
-: 60: * NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
-: 61: * AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
-: 62: * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-: 63: *
-: 64: * GOVERNMENT USE: If you are acquiring this software on behalf of the
-: 65: * U.S. government, the Government shall have only "Restricted Rights"
-: 66: * in the software and related documentation as defined in the Federal
-: 67: * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
-: 68: * are acquiring the software on behalf of the Department of Defense,
-: 69: * the software shall be classified as "Commercial Computer Software"
-: 70: * and the Government shall have only "Restricted Rights" as defined
-: 71: * in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the
-: 72: * foregoing, the authors grant the U.S. Government and others acting
-: 73: * in its behalf permission to use and distribute the software in
-: 74: * accordance with the terms specified in this license.
-: 75: */
-: 76:
-: 77:#include "dbus-hash.h"
-: 78:#include "dbus-internals.h"
-: 79:#include "dbus-mempool.h"
-: 80:
-: 81:/**
-: 82: * @defgroup DBusHashTable Hash table
-: 83: * @ingroup DBusInternals
-: 84: * @brief DBusHashTable data structure
-: 85: *
-: 86: * Types and functions related to DBusHashTable.
-: 87: */
-: 88:
-: 89:/**
-: 90: * @defgroup DBusHashTableInternals Hash table implementation details
-: 91: * @ingroup DBusInternals
-: 92: * @brief DBusHashTable implementation details
-: 93: *
-: 94: * The guts of DBusHashTable.
-: 95: *
-: 96: * @{
-: 97: */
-: 98:
-: 99:/**
-: 100: * When there are this many entries per bucket, on average, rebuild
-: 101: * the hash table to make it larger.
-: 102: */
-: 103:#define REBUILD_MULTIPLIER 3
-: 104:
-: 105:/**
-: 106: * Takes a preliminary integer hash value and produces an index into a
-: 107: * hash tables bucket list. The idea is to make it so that
-: 108: * preliminary values that are arbitrarily similar will end up in
-: 109: * different buckets. The hash function was taken from a
-: 110: * random-number generator. (This is used to hash integers.)
-: 111: *
-: 112: * The down_shift drops off the high bits of the hash index, and
-: 113: * decreases as we increase the number of hash buckets (to keep more
-: 114: * range in the hash index). The mask also strips high bits and strips
-: 115: * fewer high bits as the number of hash buckets increases.
-: 116: * I don't understand two things: why is the initial downshift 28
-: 117: * to keep 4 bits when the initial mask is 011 to keep 2 bits,
-: 118: * and why do we have both a mask and a downshift?
-: 119: *
-: 120: */
-: 121:#define RANDOM_INDEX(table, i) \
-: 122: (((((long) (i))*1103515245) >> (table)->down_shift) & (table)->mask)
-: 123:
-: 124:/**
-: 125: * Initial number of buckets in hash table (hash table statically
-: 126: * allocates its buckets for this size and below).
-: 127: * The initial mask has to be synced to this.
-: 128: */
-: 129:#define DBUS_SMALL_HASH_TABLE 4
-: 130:
-: 131:/**
-: 132: * Typedef for DBusHashEntry
-: 133: */
-: 134:typedef struct DBusHashEntry DBusHashEntry;
-: 135:
-: 136:/**
-: 137: * @brief Internal representation of a hash entry.
-: 138: *
-: 139: * A single entry (key-value pair) in the hash table.
-: 140: * Internal to hash table implementation.
-: 141: */
-: 142:struct DBusHashEntry
-: 143:{
-: 144: DBusHashEntry *next; /**< Pointer to next entry in this
-: 145: * hash bucket, or #NULL for end of
-: 146: * chain.
-: 147: */
-: 148: void *key; /**< Hash key */
-: 149: void *value; /**< Hash value */
-: 150:};
-: 151:
-: 152:/**
-: 153: * Function used to find and optionally create a hash entry.
-: 154: */
-: 155:typedef DBusHashEntry* (* DBusFindEntryFunction) (DBusHashTable *table,
-: 156: void *key,
-: 157: dbus_bool_t create_if_not_found,
-: 158: DBusHashEntry ***bucket,
-: 159: DBusPreallocatedHash *preallocated);
-: 160:
-: 161:/**
-: 162: * @brief Internals of DBusHashTable.
-: 163: *
-: 164: * Hash table internals. Hash tables are opaque objects, they must be
-: 165: * used via accessor functions.
-: 166: */
-: 167:struct DBusHashTable {
-: 168: int refcount; /**< Reference count */
-: 169:
-: 170: DBusHashEntry **buckets; /**< Pointer to bucket array. Each
-: 171: * element points to first entry in
-: 172: * bucket's hash chain, or #NULL.
-: 173: */
-: 174: DBusHashEntry *static_buckets[DBUS_SMALL_HASH_TABLE];
-: 175: /**< Bucket array used for small tables
-: 176: * (to avoid mallocs and frees).
-: 177: */
-: 178: int n_buckets; /**< Total number of buckets allocated
-: 179: * at **buckets.
-: 180: */
-: 181: int n_entries; /**< Total number of entries present
-: 182: * in table.
-: 183: */
-: 184: int hi_rebuild_size; /**< Enlarge table when n_entries gets
-: 185: * to be this large.
-: 186: */
-: 187: int lo_rebuild_size; /**< Shrink table when n_entries gets
-: 188: * below this.
-: 189: */
-: 190: int down_shift; /**< Shift count used in hashing
-: 191: * function. Designed to use high-
-: 192: * order bits of randomized keys.
-: 193: */
-: 194: int mask; /**< Mask value used in hashing
-: 195: * function.
-: 196: */
-: 197: DBusHashType key_type; /**< Type of keys used in this table */
-: 198:
-: 199:
-: 200: DBusFindEntryFunction find_function; /**< Function for finding entries */
-: 201:
-: 202: DBusFreeFunction free_key_function; /**< Function to free keys */
-: 203: DBusFreeFunction free_value_function; /**< Function to free values */
-: 204:
-: 205: DBusMemPool *entry_pool; /**< Memory pool for hash entries */
-: 206:};
-: 207:
-: 208:/**
-: 209: * @brief Internals of DBusHashIter.
-: 210: */
-: 211:typedef struct
-: 212:{
-: 213: DBusHashTable *table; /**< Pointer to table containing entry. */
-: 214: DBusHashEntry **bucket; /**< Pointer to bucket that points to
-: 215: * first entry in this entry's chain:
-: 216: * used for deleting the entry.
-: 217: */
-: 218: DBusHashEntry *entry; /**< Current hash entry */
-: 219: DBusHashEntry *next_entry; /**< Next entry to be iterated onto in current bucket */
-: 220: int next_bucket; /**< index of next bucket */
-: 221: int n_entries_on_init; /**< used to detect table resize since initialization */
-: 222:} DBusRealHashIter;
-: 223:
-: 224:static DBusHashEntry* find_direct_function (DBusHashTable *table,
-: 225: void *key,
-: 226: dbus_bool_t create_if_not_found,
-: 227: DBusHashEntry ***bucket,
-: 228: DBusPreallocatedHash *preallocated);
-: 229:static DBusHashEntry* find_string_function (DBusHashTable *table,
-: 230: void *key,
-: 231: dbus_bool_t create_if_not_found,
-: 232: DBusHashEntry ***bucket,
-: 233: DBusPreallocatedHash *preallocated);
-: 234:#ifdef DBUS_BUILD_TESTS
-: 235:static DBusHashEntry* find_two_strings_function (DBusHashTable *table,
-: 236: void *key,
-: 237: dbus_bool_t create_if_not_found,
-: 238: DBusHashEntry ***bucket,
-: 239: DBusPreallocatedHash *preallocated);
-: 240:#endif
-: 241:static unsigned int string_hash (const char *str);
-: 242:#ifdef DBUS_BUILD_TESTS
-: 243:static unsigned int two_strings_hash (const char *str);
-: 244:#endif
-: 245:static void rebuild_table (DBusHashTable *table);
-: 246:static DBusHashEntry* alloc_entry (DBusHashTable *table);
-: 247:static void remove_entry (DBusHashTable *table,
-: 248: DBusHashEntry **bucket,
-: 249: DBusHashEntry *entry);
-: 250:static void free_entry (DBusHashTable *table,
-: 251: DBusHashEntry *entry);
-: 252:static void free_entry_data (DBusHashTable *table,
-: 253: DBusHashEntry *entry);
-: 254:
-: 255:
-: 256:/** @} */
-: 257:
-: 258:/**
-: 259: * @addtogroup DBusHashTable
-: 260: * @{
-: 261: */
-: 262:
-: 263:/**
-: 264: * @typedef DBusHashIter
-: 265: *
-: 266: * Public opaque hash table iterator object.
-: 267: */
-: 268:
-: 269:/**
-: 270: * @typedef DBusHashTable
-: 271: *
-: 272: * Public opaque hash table object.
-: 273: */
-: 274:
-: 275:/**
-: 276: * @typedef DBusHashType
-: 277: *
-: 278: * Indicates the type of a key in the hash table.
-: 279: */
-: 280:
-: 281:/**
-: 282: * Constructs a new hash table. Should be freed with
-: 283: * _dbus_hash_table_unref(). If memory cannot be
-: 284: * allocated for the hash table, returns #NULL.
-: 285: *
-: 286: * @param type the type of hash key to use.
-: 287: * @param key_free_function function to free hash keys.
-: 288: * @param value_free_function function to free hash values.
-: 289: * @returns a new DBusHashTable or #NULL if no memory.
-: 290: */
-: 291:DBusHashTable*
-: 292:_dbus_hash_table_new (DBusHashType type,
-: 293: DBusFreeFunction key_free_function,
-: 294: DBusFreeFunction value_free_function)
function _dbus_hash_table_new called 15542 returned 100% blocks executed 94%
15542: 295:{
-: 296: DBusHashTable *table;
-: 297: DBusMemPool *entry_pool;
-: 298:
15542: 299: table = dbus_new0 (DBusHashTable, 1);
call 0 returned 100%
15542: 300: if (table == NULL)
branch 0 taken 1% (fallthrough)
branch 1 taken 99%
15: 301: return NULL;
-: 302:
15527: 303: entry_pool = _dbus_mem_pool_new (sizeof (DBusHashEntry), TRUE);
call 0 returned 100%
15527: 304: if (entry_pool == NULL)
branch 0 taken 1% (fallthrough)
branch 1 taken 99%
-: 305: {
15: 306: dbus_free (table);
call 0 returned 100%
15: 307: return NULL;
-: 308: }
-: 309:
15512: 310: table->refcount = 1;
15512: 311: table->entry_pool = entry_pool;
-: 312:
15512: 313: _dbus_assert (DBUS_SMALL_HASH_TABLE == _DBUS_N_ELEMENTS (table->static_buckets));
call 0 returned 100%
-: 314:
15512: 315: table->buckets = table->static_buckets;
15512: 316: table->n_buckets = DBUS_SMALL_HASH_TABLE;
15512: 317: table->n_entries = 0;
15512: 318: table->hi_rebuild_size = DBUS_SMALL_HASH_TABLE * REBUILD_MULTIPLIER;
15512: 319: table->lo_rebuild_size = 0;
15512: 320: table->down_shift = 28;
15512: 321: table->mask = 3;
15512: 322: table->key_type = type;
-: 323:
15512: 324: _dbus_assert (table->mask < table->n_buckets);
call 0 returned 100%
-: 325:
15512: 326: switch (table->key_type)
branch 0 taken 93%
branch 1 taken 7%
branch 2 taken 1%
branch 3 taken 0%
-: 327: {
-: 328: case DBUS_HASH_INT:
-: 329: case DBUS_HASH_POINTER:
-: 330: case DBUS_HASH_ULONG:
14484: 331: table->find_function = find_direct_function;
14484: 332: break;
-: 333: case DBUS_HASH_STRING:
1027: 334: table->find_function = find_string_function;
1027: 335: break;
-: 336: case DBUS_HASH_TWO_STRINGS:
-: 337:#ifdef DBUS_BUILD_TESTS
1: 338: table->find_function = find_two_strings_function;
-: 339:#endif
1: 340: break;
-: 341: default:
#####: 342: _dbus_assert_not_reached ("Unknown hash table type");
call 0 never executed
-: 343: break;
-: 344: }
-: 345:
15512: 346: table->free_key_function = key_free_function;
15512: 347: table->free_value_function = value_free_function;
-: 348:
15512: 349: return table;
-: 350:}
-: 351:
-: 352:
-: 353:/**
-: 354: * Increments the reference count for a hash table.
-: 355: *
-: 356: * @param table the hash table to add a reference to.
-: 357: * @returns the hash table.
-: 358: */
-: 359:DBusHashTable *
-: 360:_dbus_hash_table_ref (DBusHashTable *table)
function _dbus_hash_table_ref called 4 returned 100% blocks executed 100%
4: 361:{
4: 362: table->refcount += 1;
-: 363:
4: 364: return table;
-: 365:}
-: 366:
-: 367:/**
-: 368: * Decrements the reference count for a hash table,
-: 369: * freeing the hash table if the count reaches zero.
-: 370: *
-: 371: * @param table the hash table to remove a reference from.
-: 372: */
-: 373:void
-: 374:_dbus_hash_table_unref (DBusHashTable *table)
function _dbus_hash_table_unref called 14166 returned 100% blocks executed 100%
14166: 375:{
14166: 376: table->refcount -= 1;
-: 377:
14166: 378: if (table->refcount == 0)
branch 0 taken 99% (fallthrough)
branch 1 taken 1%
-: 379: {
-: 380:#if 0
-: 381: DBusHashEntry *entry;
-: 382: DBusHashEntry *next;
-: 383: int i;
-: 384:
-: 385: /* Free the entries in the table. */
-: 386: for (i = 0; i < table->n_buckets; i++)
-: 387: {
-: 388: entry = table->buckets[i];
-: 389: while (entry != NULL)
-: 390: {
-: 391: next = entry->next;
-: 392:
-: 393: free_entry (table, entry);
-: 394:
-: 395: entry = next;
-: 396: }
-: 397: }
-: 398:#else
-: 399: DBusHashEntry *entry;
-: 400: int i;
-: 401:
-: 402: /* Free the entries in the table. */
81022: 403: for (i = 0; i < table->n_buckets; i++)
branch 0 taken 83%
branch 1 taken 17% (fallthrough)
-: 404: {
66860: 405: entry = table->buckets[i];
133795: 406: while (entry != NULL)
branch 0 taken 1%
branch 1 taken 99% (fallthrough)
-: 407: {
75: 408: free_entry_data (table, entry);
call 0 returned 100%
-: 409:
75: 410: entry = entry->next;
-: 411: }
-: 412: }
-: 413: /* We can do this very quickly with memory pools ;-) */
14162: 414: _dbus_mem_pool_free (table->entry_pool);
call 0 returned 100%
-: 415:#endif
-: 416:
-: 417: /* Free the bucket array, if it was dynamically allocated. */
14162: 418: if (table->buckets != table->static_buckets)
branch 0 taken 1% (fallthrough)
branch 1 taken 99%
8: 419: dbus_free (table->buckets);
call 0 returned 100%
-: 420:
14162: 421: dbus_free (table);
call 0 returned 100%
-: 422: }
14166: 423:}
-: 424:
-: 425:/**
-: 426: * Removed all entries from a hash table.
-: 427: *
-: 428: * @param table the hash table to remove all entries from.
-: 429: */
-: 430:void
-: 431:_dbus_hash_table_remove_all (DBusHashTable *table)
function _dbus_hash_table_remove_all called 0 returned 0% blocks executed 0%
#####: 432:{
-: 433: DBusHashIter iter;
#####: 434: _dbus_hash_iter_init (table, &iter);
call 0 never executed
#####: 435: while (_dbus_hash_iter_next (&iter))
call 0 never executed
branch 1 never executed
branch 2 never executed
-: 436: {
#####: 437: _dbus_hash_iter_remove_entry(&iter);
call 0 never executed
-: 438: }
#####: 439:}
-: 440:
-: 441:static DBusHashEntry*
-: 442:alloc_entry (DBusHashTable *table)
function alloc_entry called 52387 returned 100% blocks executed 100%
52387: 443:{
-: 444: DBusHashEntry *entry;
-: 445:
52387: 446: entry = _dbus_mem_pool_alloc (table->entry_pool);
call 0 returned 100%
-: 447:
52387: 448: return entry;
-: 449:}
-: 450:
-: 451:static void
-: 452:free_entry_data (DBusHashTable *table,
-: 453: DBusHashEntry *entry)
function free_entry_data called 43521 returned 100% blocks executed 100%
43521: 454:{
43521: 455: if (table->free_key_function)
branch 0 taken 38% (fallthrough)
branch 1 taken 62%
16514: 456: (* table->free_key_function) (entry->key);
call 0 returned 100%
43521: 457: if (table->free_value_function)
branch 0 taken 83% (fallthrough)
branch 1 taken 17%
36015: 458: (* table->free_value_function) (entry->value);
call 0 returned 100%
43521: 459:}
-: 460:
-: 461:static void
-: 462:free_entry (DBusHashTable *table,
-: 463: DBusHashEntry *entry)
function free_entry called 43446 returned 100% blocks executed 100%
43446: 464:{
43446: 465: free_entry_data (table, entry);
call 0 returned 100%
43446: 466: _dbus_mem_pool_dealloc (table->entry_pool, entry);
call 0 returned 100%
43446: 467:}
-: 468:
-: 469:static void
-: 470:remove_entry (DBusHashTable *table,
-: 471: DBusHashEntry **bucket,
-: 472: DBusHashEntry *entry)
function remove_entry called 43446 returned 100% blocks executed 100%
43446: 473:{
43446: 474: _dbus_assert (table != NULL);
call 0 returned 100%
43446: 475: _dbus_assert (bucket != NULL);
call 0 returned 100%
43446: 476: _dbus_assert (*bucket != NULL);
call 0 returned 100%
43446: 477: _dbus_assert (entry != NULL);
call 0 returned 100%
-: 478:
43446: 479: if (*bucket == entry)
branch 0 taken 96% (fallthrough)
branch 1 taken 4%
41712: 480: *bucket = entry->next;
-: 481: else
-: 482: {
-: 483: DBusHashEntry *prev;
1734: 484: prev = *bucket;
-: 485:
4796: 486: while (prev->next != entry)
branch 0 taken 43%
branch 1 taken 57% (fallthrough)
1328: 487: prev = prev->next;
-: 488:
1734: 489: _dbus_assert (prev != NULL);
call 0 returned 100%
-: 490:
1734: 491: prev->next = entry->next;
-: 492: }
-: 493:
43446: 494: table->n_entries -= 1;
43446: 495: free_entry (table, entry);
call 0 returned 100%
43446: 496:}
-: 497:
-: 498:/**
-: 499: * Initializes a hash table iterator. To iterate over all entries in a
-: 500: * hash table, use the following code (the printf assumes a hash
-: 501: * from strings to strings obviously):
-: 502: *
-: 503: * @code
-: 504: * DBusHashIter iter;
-: 505: *
-: 506: * _dbus_hash_iter_init (table, &iter);
-: 507: * while (_dbus_hash_iter_next (&iter))
-: 508: * {
-: 509: * printf ("The first key is %s and value is %s\n",
-: 510: * _dbus_hash_iter_get_string_key (&iter),
-: 511: * _dbus_hash_iter_get_value (&iter));
-: 512: * }
-: 513: *
-: 514: *
-: 515: * @endcode
-: 516: *
-: 517: * The iterator is initialized pointing "one before" the first hash
-: 518: * entry. The first call to _dbus_hash_iter_next() moves it onto
-: 519: * the first valid entry or returns #FALSE if the hash table is
-: 520: * empty. Subsequent calls move to the next valid entry or return
-: 521: * #FALSE if there are no more entries.
-: 522: *
-: 523: * Note that it is guaranteed to be safe to remove a hash entry during
-: 524: * iteration, but it is not safe to add a hash entry.
-: 525: *
-: 526: * @param table the hash table to iterate over.
-: 527: * @param iter the iterator to initialize.
-: 528: */
-: 529:void
-: 530:_dbus_hash_iter_init (DBusHashTable *table,
-: 531: DBusHashIter *iter)
function _dbus_hash_iter_init called 62668 returned 100% blocks executed 100%
62668: 532:{
-: 533: DBusRealHashIter *real;
-: 534:
62668: 535: _dbus_assert (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
call 0 returned 100%
-: 536:
62668: 537: real = (DBusRealHashIter*) iter;
-: 538:
62668: 539: real->table = table;
62668: 540: real->bucket = NULL;
62668: 541: real->entry = NULL;
62668: 542: real->next_entry = NULL;
62668: 543: real->next_bucket = 0;
62668: 544: real->n_entries_on_init = table->n_entries;
62668: 545:}
-: 546:
-: 547:/**
-: 548: * Move the hash iterator forward one step, to the next hash entry.
-: 549: * The documentation for _dbus_hash_iter_init() explains in more
-: 550: * detail.
-: 551: *
-: 552: * @param iter the iterator to move forward.
-: 553: * @returns #FALSE if there are no more entries to move to.
-: 554: */
-: 555:dbus_bool_t
-: 556:_dbus_hash_iter_next (DBusHashIter *iter)
function _dbus_hash_iter_next called 108655651 returned 100% blocks executed 100%
108655651: 557:{
-: 558: DBusRealHashIter *real;
-: 559:
108655651: 560: _dbus_assert (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
call 0 returned 100%
-: 561:
108655651: 562: real = (DBusRealHashIter*) iter;
-: 563:
-: 564: /* if this assertion failed someone probably added hash entries
-: 565: * during iteration, which is bad.
-: 566: */
108655651: 567: _dbus_assert (real->n_entries_on_init >= real->table->n_entries);
call 0 returned 100%
-: 568:
-: 569: /* Remember that real->entry may have been deleted */
-: 570:
314584183: 571: while (real->next_entry == NULL)
branch 0 taken 47%
branch 1 taken 53% (fallthrough)
-: 572: {
97341301: 573: if (real->next_bucket >= real->table->n_buckets)
branch 0 taken 1% (fallthrough)
branch 1 taken 99%
-: 574: {
-: 575: /* invalidate iter and return false */
68420: 576: real->entry = NULL;
68420: 577: real->table = NULL;
68420: 578: real->bucket = NULL;
68420: 579: return FALSE;
-: 580: }
-: 581:
97272881: 582: real->bucket = &(real->table->buckets[real->next_bucket]);
97272881: 583: real->next_entry = *(real->bucket);
97272881: 584: real->next_bucket += 1;
-: 585: }
-: 586:
108587231: 587: _dbus_assert (real->next_entry != NULL);
call 0 returned 100%
108587231: 588: _dbus_assert (real->bucket != NULL);
call 0 returned 100%
-: 589:
108587231: 590: real->entry = real->next_entry;
108587231: 591: real->next_entry = real->entry->next;
-: 592:
108587231: 593: return TRUE;
-: 594:}
-: 595:
-: 596:/**
-: 597: * Removes the current entry from the hash table.
-: 598: * If a key_free_function or value_free_function
-: 599: * was provided to _dbus_hash_table_new(),
-: 600: * frees the key and/or value for this entry.
-: 601: *
-: 602: * @param iter the hash table iterator.
-: 603: */
-: 604:void
-: 605:_dbus_hash_iter_remove_entry (DBusHashIter *iter)
function _dbus_hash_iter_remove_entry called 16000 returned 100% blocks executed 100%
16000: 606:{
-: 607: DBusRealHashIter *real;
-: 608:
16000: 609: real = (DBusRealHashIter*) iter;
-: 610:
16000: 611: _dbus_assert (real->table != NULL);
call 0 returned 100%
16000: 612: _dbus_assert (real->entry != NULL);
call 0 returned 100%
16000: 613: _dbus_assert (real->bucket != NULL);
call 0 returned 100%
-: 614:
16000: 615: remove_entry (real->table, real->bucket, real->entry);
call 0 returned 100%
-: 616:
16000: 617: real->entry = NULL; /* make it crash if you try to use this entry */
16000: 618:}
-: 619:
-: 620:/**
-: 621: * Gets the value of the current entry.
-: 622: *
-: 623: * @param iter the hash table iterator.
-: 624: */
-: 625:void*
-: 626:_dbus_hash_iter_get_value (DBusHashIter *iter)
function _dbus_hash_iter_get_value called 24134 returned 100% blocks executed 100%
24134: 627:{
-: 628: DBusRealHashIter *real;
-: 629:
24134: 630: real = (DBusRealHashIter*) iter;
-: 631:
24134: 632: _dbus_assert (real->table != NULL);
call 0 returned 100%
24134: 633: _dbus_assert (real->entry != NULL);
call 0 returned 100%
-: 634:
24134: 635: return real->entry->value;
-: 636:}
-: 637:
-: 638:/**
-: 639: * Sets the value of the current entry.
-: 640: * If the hash table has a value_free_function
-: 641: * it will be used to free the previous value.
-: 642: * The hash table will own the passed-in value
-: 643: * (it will not be copied).
-: 644: *
-: 645: * @param iter the hash table iterator.
-: 646: * @param value the new value.
-: 647: */
-: 648:void
-: 649:_dbus_hash_iter_set_value (DBusHashIter *iter,
-: 650: void *value)
function _dbus_hash_iter_set_value called 16000 returned 100% blocks executed 100%
16000: 651:{
-: 652: DBusRealHashIter *real;
-: 653:
16000: 654: real = (DBusRealHashIter*) iter;
-: 655:
16000: 656: _dbus_assert (real->table != NULL);
call 0 returned 100%
16000: 657: _dbus_assert (real->entry != NULL);
call 0 returned 100%
-: 658:
16000: 659: if (real->table->free_value_function && value != real->entry->value)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
branch 2 taken 100% (fallthrough)
branch 3 taken 0%
16000: 660: (* real->table->free_value_function) (real->entry->value);
call 0 returned 100%
-: 661:
16000: 662: real->entry->value = value;
16000: 663:}
-: 664:
-: 665:/**
-: 666: * Gets the key for the current entry.
-: 667: * Only works for hash tables of type #DBUS_HASH_INT.
-: 668: *
-: 669: * @param iter the hash table iterator.
-: 670: */
-: 671:int
-: 672:_dbus_hash_iter_get_int_key (DBusHashIter *iter)
function _dbus_hash_iter_get_int_key called 5000 returned 100% blocks executed 100%
5000: 673:{
-: 674: DBusRealHashIter *real;
-: 675:
5000: 676: real = (DBusRealHashIter*) iter;
-: 677:
5000: 678: _dbus_assert (real->table != NULL);
call 0 returned 100%
5000: 679: _dbus_assert (real->entry != NULL);
call 0 returned 100%
-: 680:
5000: 681: return _DBUS_POINTER_TO_INT (real->entry->key);
-: 682:}
-: 683:
-: 684:/**
-: 685: * Gets the key for the current entry.
-: 686: * Only works for hash tables of type #DBUS_HASH_ULONG.
-: 687: *
-: 688: * @param iter the hash table iterator.
-: 689: */
-: 690:unsigned long
-: 691:_dbus_hash_iter_get_ulong_key (DBusHashIter *iter)
function _dbus_hash_iter_get_ulong_key called 1 returned 100% blocks executed 100%
1: 692:{
-: 693: DBusRealHashIter *real;
-: 694:
1: 695: real = (DBusRealHashIter*) iter;
-: 696:
1: 697: _dbus_assert (real->table != NULL);
call 0 returned 100%
1: 698: _dbus_assert (real->entry != NULL);
call 0 returned 100%
-: 699:
1: 700: return (unsigned long) real->entry->key;
-: 701:}
-: 702:
-: 703:/**
-: 704: * Gets the key for the current entry.
-: 705: * Only works for hash tables of type #DBUS_HASH_STRING
-: 706: * @param iter the hash table iterator.
-: 707: */
-: 708:const char*
-: 709:_dbus_hash_iter_get_string_key (DBusHashIter *iter)
function _dbus_hash_iter_get_string_key called 5000 returned 100% blocks executed 100%
5000: 710:{
-: 711: DBusRealHashIter *real;
-: 712:
5000: 713: real = (DBusRealHashIter*) iter;
-: 714:
5000: 715: _dbus_assert (real->table != NULL);
call 0 returned 100%
5000: 716: _dbus_assert (real->entry != NULL);
call 0 returned 100%
-: 717:
5000: 718: return real->entry->key;
-: 719:}
-: 720:
-: 721:#ifdef DBUS_BUILD_TESTS
-: 722:/**
-: 723: * Gets the key for the current entry.
-: 724: * Only works for hash tables of type #DBUS_HASH_TWO_STRINGS
-: 725: * @param iter the hash table iterator.
-: 726: */
-: 727:const char*
-: 728:_dbus_hash_iter_get_two_strings_key (DBusHashIter *iter)
function _dbus_hash_iter_get_two_strings_key called 0 returned 0% blocks executed 0%
#####: 729:{
-: 730: DBusRealHashIter *real;
-: 731:
#####: 732: real = (DBusRealHashIter*) iter;
-: 733:
#####: 734: _dbus_assert (real->table != NULL);
call 0 never executed
#####: 735: _dbus_assert (real->entry != NULL);
call 0 never executed
-: 736:
#####: 737: return real->entry->key;
-: 738:}
-: 739:#endif /* DBUS_BUILD_TESTS */
-: 740:
-: 741:/**
-: 742: * A low-level but efficient interface for manipulating the hash
-: 743: * table. It's efficient because you can get, set, and optionally
-: 744: * create the hash entry while only running the hash function one
-: 745: * time.
-: 746: *
-: 747: * Note that while calling _dbus_hash_iter_next() on the iterator
-: 748: * filled in by this function may work, it's completely
-: 749: * undefined which entries are after this iter and which
-: 750: * are before it. So it would be silly to iterate using this
-: 751: * iterator.
-: 752: *
-: 753: * If the hash entry is created, its value will be initialized
-: 754: * to all bits zero.
-: 755: *
-: 756: * #FALSE may be returned due to memory allocation failure, or
-: 757: * because create_if_not_found was #FALSE and the entry
-: 758: * did not exist.
-: 759: *
-: 760: * If create_if_not_found is #TRUE and the entry is created, the hash
-: 761: * table takes ownership of the key that's passed in.
-: 762: *
-: 763: * For a hash table of type #DBUS_HASH_INT, cast the int
-: 764: * key to the key parameter using #_DBUS_INT_TO_POINTER().
-: 765: *
-: 766: * @param table the hash table.
-: 767: * @param key the hash key.
-: 768: * @param create_if_not_found if #TRUE, create the entry if it didn't exist.
-: 769: * @param iter the iterator to initialize.
-: 770: * @returns #TRUE if the hash entry now exists (and the iterator is thus valid).
-: 771: */
-: 772:dbus_bool_t
-: 773:_dbus_hash_iter_lookup (DBusHashTable *table,
-: 774: void *key,
-: 775: dbus_bool_t create_if_not_found,
-: 776: DBusHashIter *iter)
function _dbus_hash_iter_lookup called 18000 returned 100% blocks executed 86%
18000: 777:{
-: 778: DBusRealHashIter *real;
-: 779: DBusHashEntry *entry;
-: 780: DBusHashEntry **bucket;
-: 781:
18000: 782: _dbus_assert (sizeof (DBusHashIter) == sizeof (DBusRealHashIter));
call 0 returned 100%
-: 783:
18000: 784: real = (DBusRealHashIter*) iter;
-: 785:
18000: 786: entry = (* table->find_function) (table, key, create_if_not_found, &bucket, NULL);
call 0 returned 100%
-: 787:
18000: 788: if (entry == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 789: return FALSE;
-: 790:
18000: 791: real->table = table;
18000: 792: real->bucket = bucket;
18000: 793: real->entry = entry;
18000: 794: real->next_entry = entry->next;
18000: 795: real->next_bucket = (bucket - table->buckets) + 1;
18000: 796: real->n_entries_on_init = table->n_entries;
-: 797:
18000: 798: _dbus_assert (&(table->buckets[real->next_bucket-1]) == real->bucket);
call 0 returned 100%
-: 799:
18000: 800: return TRUE;
-: 801:}
-: 802:
-: 803:static void
-: 804:add_allocated_entry (DBusHashTable *table,
-: 805: DBusHashEntry *entry,
-: 806: unsigned int idx,
-: 807: void *key,
-: 808: DBusHashEntry ***bucket)
function add_allocated_entry called 43940 returned 100% blocks executed 100%
43940: 809:{
-: 810: DBusHashEntry **b;
-: 811:
43940: 812: entry->key = key;
-: 813:
43940: 814: b = &(table->buckets[idx]);
43940: 815: entry->next = *b;
43940: 816: *b = entry;
-: 817:
43940: 818: if (bucket)
branch 0 taken 14% (fallthrough)
branch 1 taken 86%
6000: 819: *bucket = b;
-: 820:
43940: 821: table->n_entries += 1;
-: 822:
-: 823: /* note we ONLY rebuild when ADDING - because you can iterate over a
-: 824: * table and remove entries safely.
-: 825: */
43940: 826: if (table->n_entries >= table->hi_rebuild_size ||
branch 0 taken 99% (fallthrough)
branch 1 taken 1%
branch 2 taken 1% (fallthrough)
branch 3 taken 99%
-: 827: table->n_entries < table->lo_rebuild_size)
49: 828: rebuild_table (table);
call 0 returned 100%
43940: 829:}
-: 830:
-: 831:static DBusHashEntry*
-: 832:add_entry (DBusHashTable *table,
-: 833: unsigned int idx,
-: 834: void *key,
-: 835: DBusHashEntry ***bucket,
-: 836: DBusPreallocatedHash *preallocated)
function add_entry called 43940 returned 100% blocks executed 73%
43940: 837:{
-: 838: DBusHashEntry *entry;
-: 839:
43940: 840: if (preallocated == NULL)
branch 0 taken 49% (fallthrough)
branch 1 taken 51%
-: 841: {
21362: 842: entry = alloc_entry (table);
call 0 returned 100%
21362: 843: if (entry == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 844: {
#####: 845: if (bucket)
branch 0 never executed
branch 1 never executed
#####: 846: *bucket = NULL;
#####: 847: return NULL;
-: 848: }
-: 849: }
-: 850: else
-: 851: {
22578: 852: entry = (DBusHashEntry*) preallocated;
-: 853: }
-: 854:
43940: 855: add_allocated_entry (table, entry, idx, key, bucket);
call 0 returned 100%
-: 856:
43940: 857: return entry;
-: 858:}
-: 859:
-: 860:/* This is g_str_hash from GLib which was
-: 861: * extensively discussed/tested/profiled
-: 862: */
-: 863:static unsigned int
-: 864:string_hash (const char *str)
function string_hash called 130665 returned 100% blocks executed 100%
130665: 865:{
130665: 866: const char *p = str;
130665: 867: unsigned int h = *p;
-: 868:
130665: 869: if (h)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
2635161: 870: for (p += 1; *p != '\0'; p++)
branch 0 taken 95%
branch 1 taken 5% (fallthrough)
2504496: 871: h = (h << 5) - h + *p;
-: 872:
130665: 873: return h;
-: 874:}
-: 875:
-: 876:#ifdef DBUS_BUILD_TESTS
-: 877:/* This hashes a memory block with two nul-terminated strings
-: 878: * in it, used in dbus-object-registry.c at the moment.
-: 879: */
-: 880:static unsigned int
-: 881:two_strings_hash (const char *str)
function two_strings_hash called 10020 returned 100% blocks executed 100%
10020: 882:{
10020: 883: const char *p = str;
10020: 884: unsigned int h = *p;
-: 885:
10020: 886: if (h)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
125610: 887: for (p += 1; *p != '\0'; p++)
branch 0 taken 92%
branch 1 taken 8% (fallthrough)
115590: 888: h = (h << 5) - h + *p;
-: 889:
155670: 890: for (p += 1; *p != '\0'; p++)
branch 0 taken 94%
branch 1 taken 6% (fallthrough)
145650: 891: h = (h << 5) - h + *p;
-: 892:
10020: 893: return h;
-: 894:}
-: 895:#endif /* DBUS_BUILD_TESTS */
-: 896:
-: 897:/** Key comparison function */
-: 898:typedef int (* KeyCompareFunc) (const void *key_a, const void *key_b);
-: 899:
-: 900:static DBusHashEntry*
-: 901:find_generic_function (DBusHashTable *table,
-: 902: void *key,
-: 903: unsigned int idx,
-: 904: KeyCompareFunc compare_func,
-: 905: dbus_bool_t create_if_not_found,
-: 906: DBusHashEntry ***bucket,
-: 907: DBusPreallocatedHash *preallocated)
function find_generic_function called 320022 returned 100% blocks executed 91%
320022: 908:{
-: 909: DBusHashEntry *entry;
-: 910:
320022: 911: if (bucket)
branch 0 taken 15% (fallthrough)
branch 1 taken 85%
46834: 912: *bucket = NULL;
-: 913:
-: 914: /* Search all of the entries in this bucket. */
320022: 915: entry = table->buckets[idx];
866339: 916: while (entry != NULL)
branch 0 taken 67%
branch 1 taken 33% (fallthrough)
-: 917: {
368707: 918: if ((compare_func == NULL && key == entry->key) ||
branch 0 taken 27% (fallthrough)
branch 1 taken 73%
branch 2 taken 26% (fallthrough)
branch 3 taken 74%
branch 4 taken 91% (fallthrough)
branch 5 taken 9%
call 6 returned 100%
branch 7 taken 26% (fallthrough)
branch 8 taken 74%
-: 919: (compare_func != NULL && (* compare_func) (key, entry->key) == 0))
-: 920: {
142412: 921: if (bucket)
branch 0 taken 28% (fallthrough)
branch 1 taken 72%
39446: 922: *bucket = &(table->buckets[idx]);
-: 923:
142412: 924: if (preallocated)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 925: _dbus_hash_table_free_preallocated_entry (table, preallocated);
call 0 never executed
-: 926:
142412: 927: return entry;
-: 928: }
-: 929:
226295: 930: entry = entry->next;
-: 931: }
-: 932:
177610: 933: if (create_if_not_found)
branch 0 taken 25% (fallthrough)
branch 1 taken 75%
43940: 934: entry = add_entry (table, idx, key, bucket, preallocated);
call 0 returned 100%
133670: 935: else if (preallocated)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 936: _dbus_hash_table_free_preallocated_entry (table, preallocated);
call 0 never executed
-: 937:
177610: 938: return entry;
-: 939:}
-: 940:
-: 941:static DBusHashEntry*
-: 942:find_string_function (DBusHashTable *table,
-: 943: void *key,
-: 944: dbus_bool_t create_if_not_found,
-: 945: DBusHashEntry ***bucket,
-: 946: DBusPreallocatedHash *preallocated)
function find_string_function called 122482 returned 100% blocks executed 100%
122482: 947:{
-: 948: unsigned int idx;
-: 949:
122482: 950: idx = string_hash (key) & table->mask;
call 0 returned 100%
-: 951:
122482: 952: return find_generic_function (table, key, idx,
call 0 returned 100%
-: 953: (KeyCompareFunc) strcmp, create_if_not_found, bucket,
-: 954: preallocated);
-: 955:}
-: 956:
-: 957:#ifdef DBUS_BUILD_TESTS
-: 958:static int
-: 959:two_strings_cmp (const char *a,
-: 960: const char *b)
function two_strings_cmp called 131554 returned 100% blocks executed 100%
131554: 961:{
-: 962: size_t len_a;
-: 963: size_t len_b;
-: 964: int res;
-: 965:
131554: 966: res = strcmp (a, b);
call 0 returned 100%
131554: 967: if (res != 0)
branch 0 taken 95% (fallthrough)
branch 1 taken 5%
125554: 968: return res;
-: 969:
6000: 970: len_a = strlen (a);
call 0 returned 100%
6000: 971: len_b = strlen (b);
call 0 returned 100%
-: 972:
6000: 973: return strcmp (a + len_a + 1, b + len_b + 1);
call 0 returned 100%
-: 974:}
-: 975:#endif
-: 976:
-: 977:#ifdef DBUS_BUILD_TESTS
-: 978:static DBusHashEntry*
-: 979:find_two_strings_function (DBusHashTable *table,
-: 980: void *key,
-: 981: dbus_bool_t create_if_not_found,
-: 982: DBusHashEntry ***bucket,
-: 983: DBusPreallocatedHash *preallocated)
function find_two_strings_function called 9000 returned 100% blocks executed 100%
9000: 984:{
-: 985: unsigned int idx;
-: 986:
9000: 987: idx = two_strings_hash (key) & table->mask;
call 0 returned 100%
-: 988:
9000: 989: return find_generic_function (table, key, idx,
call 0 returned 100%
-: 990: (KeyCompareFunc) two_strings_cmp, create_if_not_found, bucket,
-: 991: preallocated);
-: 992:}
-: 993:#endif /* DBUS_BUILD_TESTS */
-: 994:
-: 995:static DBusHashEntry*
-: 996:find_direct_function (DBusHashTable *table,
-: 997: void *key,
-: 998: dbus_bool_t create_if_not_found,
-: 999: DBusHashEntry ***bucket,
-: 1000: DBusPreallocatedHash *preallocated)
function find_direct_function called 188540 returned 100% blocks executed 100%
188540: 1001:{
-: 1002: unsigned int idx;
-: 1003:
188540: 1004: idx = RANDOM_INDEX (table, key) & table->mask;
-: 1005:
-: 1006:
188540: 1007: return find_generic_function (table, key, idx,
call 0 returned 100%
-: 1008: NULL, create_if_not_found, bucket,
-: 1009: preallocated);
-: 1010:}
-: 1011:
-: 1012:static void
-: 1013:rebuild_table (DBusHashTable *table)
function rebuild_table called 49 returned 100% blocks executed 91%
49: 1014:{
-: 1015: int old_size;
-: 1016: int new_buckets;
-: 1017: DBusHashEntry **old_buckets;
-: 1018: DBusHashEntry **old_chain;
-: 1019: DBusHashEntry *entry;
-: 1020: dbus_bool_t growing;
-: 1021:
-: 1022: /*
-: 1023: * Allocate and initialize the new bucket array, and set up
-: 1024: * hashing constants for new array size.
-: 1025: */
-: 1026:
49: 1027: growing = table->n_entries >= table->hi_rebuild_size;
-: 1028:
49: 1029: old_size = table->n_buckets;
49: 1030: old_buckets = table->buckets;
-: 1031:
49: 1032: if (growing)
branch 0 taken 78% (fallthrough)
branch 1 taken 22%
-: 1033: {
-: 1034: /* overflow paranoia */
38: 1035: if (table->n_buckets < _DBUS_INT_MAX / 4 &&
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
branch 2 taken 100% (fallthrough)
branch 3 taken 0%
-: 1036: table->down_shift >= 0)
38: 1037: new_buckets = table->n_buckets * 4;
-: 1038: else
#####: 1039: return; /* can't grow anymore */
-: 1040: }
-: 1041: else
-: 1042: {
11: 1043: new_buckets = table->n_buckets / 4;
11: 1044: if (new_buckets < DBUS_SMALL_HASH_TABLE)
branch 0 taken 18% (fallthrough)
branch 1 taken 82%
2: 1045: return; /* don't bother shrinking this far */
-: 1046: }
-: 1047:
47: 1048: table->buckets = dbus_new0 (DBusHashEntry*, new_buckets);
call 0 returned 100%
47: 1049: if (table->buckets == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
-: 1050: {
-: 1051: /* out of memory, yay - just don't reallocate, the table will
-: 1052: * still work, albeit more slowly.
-: 1053: */
#####: 1054: table->buckets = old_buckets;
#####: 1055: return;
-: 1056: }
-: 1057:
47: 1058: table->n_buckets = new_buckets;
-: 1059:
47: 1060: if (growing)
branch 0 taken 81% (fallthrough)
branch 1 taken 19%
-: 1061: {
38: 1062: table->lo_rebuild_size = table->hi_rebuild_size;
38: 1063: table->hi_rebuild_size *= 4;
-: 1064:
38: 1065: table->down_shift -= 2; /* keep 2 more high bits */
38: 1066: table->mask = (table->mask << 2) + 3; /* keep 2 more high bits */
-: 1067: }
-: 1068: else
-: 1069: {
9: 1070: table->hi_rebuild_size = table->lo_rebuild_size;
9: 1071: table->lo_rebuild_size /= 4;
-: 1072:
9: 1073: table->down_shift += 2; /* keep 2 fewer high bits */
9: 1074: table->mask = table->mask >> 2; /* keep 2 fewer high bits */
-: 1075: }
-: 1076:
-: 1077:#if 0
-: 1078: printf ("%s table to lo = %d hi = %d downshift = %d mask = 0x%x\n",
-: 1079: growing ? "GROW" : "SHRINK",
-: 1080: table->lo_rebuild_size,
-: 1081: table->hi_rebuild_size,
-: 1082: table->down_shift,
-: 1083: table->mask);
-: 1084:#endif
-: 1085:
47: 1086: _dbus_assert (table->lo_rebuild_size >= 0);
call 0 returned 100%
47: 1087: _dbus_assert (table->hi_rebuild_size > table->lo_rebuild_size);
call 0 returned 100%
47: 1088: _dbus_assert (table->mask != 0);
call 0 returned 100%
-: 1089: /* the mask is essentially the max index */
47: 1090: _dbus_assert (table->mask < table->n_buckets);
call 0 returned 100%
-: 1091:
-: 1092: /*
-: 1093: * Rehash all of the existing entries into the new bucket array.
-: 1094: */
-: 1095:
11971: 1096: for (old_chain = old_buckets; old_size > 0; old_size--, old_chain++)
branch 0 taken 99%
branch 1 taken 1% (fallthrough)
-: 1097: {
28279: 1098: for (entry = *old_chain; entry != NULL; entry = *old_chain)
branch 0 taken 58%
branch 1 taken 42% (fallthrough)
-: 1099: {
-: 1100: unsigned int idx;
-: 1101: DBusHashEntry **bucket;
-: 1102:
16355: 1103: *old_chain = entry->next;
16355: 1104: switch (table->key_type)
branch 0 taken 50%
branch 1 taken 6%
branch 2 taken 44%
branch 3 taken 0%
-: 1105: {
-: 1106: case DBUS_HASH_STRING:
8183: 1107: idx = string_hash (entry->key) & table->mask;
call 0 returned 100%
8183: 1108: break;
-: 1109: case DBUS_HASH_TWO_STRINGS:
-: 1110:#ifdef DBUS_BUILD_TESTS
1020: 1111: idx = two_strings_hash (entry->key) & table->mask;
call 0 returned 100%
-: 1112:#else
-: 1113: idx = 0;
-: 1114: _dbus_assert_not_reached ("two-strings is not enabled");
-: 1115:#endif
1020: 1116: break;
-: 1117: case DBUS_HASH_INT:
-: 1118: case DBUS_HASH_ULONG:
-: 1119: case DBUS_HASH_POINTER:
7152: 1120: idx = RANDOM_INDEX (table, entry->key);
7152: 1121: break;
-: 1122: default:
#####: 1123: idx = 0;
#####: 1124: _dbus_assert_not_reached ("Unknown hash table type");
call 0 never executed
-: 1125: break;
-: 1126: }
-: 1127:
16355: 1128: bucket = &(table->buckets[idx]);
16355: 1129: entry->next = *bucket;
16355: 1130: *bucket = entry;
-: 1131: }
-: 1132: }
-: 1133:
-: 1134: /* Free the old bucket array, if it was dynamically allocated. */
-: 1135:
47: 1136: if (old_buckets != table->static_buckets)
branch 0 taken 83% (fallthrough)
branch 1 taken 17%
39: 1137: dbus_free (old_buckets);
call 0 returned 100%
-: 1138:}
-: 1139:
-: 1140:/**
-: 1141: * Looks up the value for a given string in a hash table
-: 1142: * of type #DBUS_HASH_STRING. Returns %NULL if the value
-: 1143: * is not present. (A not-present entry is indistinguishable
-: 1144: * from an entry with a value of %NULL.)
-: 1145: * @param table the hash table.
-: 1146: * @param key the string to look up.
-: 1147: * @returns the value of the hash entry.
-: 1148: */
-: 1149:void*
-: 1150:_dbus_hash_table_lookup_string (DBusHashTable *table,
-: 1151: const char *key)
function _dbus_hash_table_lookup_string called 72419 returned 100% blocks executed 100%
72419: 1152:{
-: 1153: DBusHashEntry *entry;
-: 1154:
72419: 1155: _dbus_assert (table->key_type == DBUS_HASH_STRING);
call 0 returned 100%
-: 1156:
72419: 1157: entry = (* table->find_function) (table, (char*) key, FALSE, NULL, NULL);
call 0 returned 100%
-: 1158:
72419: 1159: if (entry)
branch 0 taken 55% (fallthrough)
branch 1 taken 45%
39855: 1160: return entry->value;
-: 1161: else
32564: 1162: return NULL;
-: 1163:}
-: 1164:
-: 1165:#ifdef DBUS_BUILD_TESTS
-: 1166:/**
-: 1167: * Looks up the value for a given string in a hash table
-: 1168: * of type #DBUS_HASH_TWO_STRINGS. Returns %NULL if the value
-: 1169: * is not present. (A not-present entry is indistinguishable
-: 1170: * from an entry with a value of %NULL.)
-: 1171: * @param table the hash table.
-: 1172: * @param key the string to look up.
-: 1173: * @returns the value of the hash entry.
-: 1174: */
-: 1175:void*
-: 1176:_dbus_hash_table_lookup_two_strings (DBusHashTable *table,
-: 1177: const char *key)
function _dbus_hash_table_lookup_two_strings called 3000 returned 100% blocks executed 83%
3000: 1178:{
-: 1179: DBusHashEntry *entry;
-: 1180:
3000: 1181: _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
call 0 returned 100%
-: 1182:
3000: 1183: entry = (* table->find_function) (table, (char*) key, FALSE, NULL, NULL);
call 0 returned 100%
-: 1184:
3000: 1185: if (entry)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
3000: 1186: return entry->value;
-: 1187: else
#####: 1188: return NULL;
-: 1189:}
-: 1190:#endif /* DBUS_BUILD_TESTS */
-: 1191:
-: 1192:/**
-: 1193: * Looks up the value for a given integer in a hash table
-: 1194: * of type #DBUS_HASH_INT. Returns %NULL if the value
-: 1195: * is not present. (A not-present entry is indistinguishable
-: 1196: * from an entry with a value of %NULL.)
-: 1197: * @param table the hash table.
-: 1198: * @param key the integer to look up.
-: 1199: * @returns the value of the hash entry.
-: 1200: */
-: 1201:void*
-: 1202:_dbus_hash_table_lookup_int (DBusHashTable *table,
-: 1203: int key)
function _dbus_hash_table_lookup_int called 113930 returned 100% blocks executed 100%
113930: 1204:{
-: 1205: DBusHashEntry *entry;
-: 1206:
113930: 1207: _dbus_assert (table->key_type == DBUS_HASH_INT);
call 0 returned 100%
-: 1208:
113930: 1209: entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, NULL, NULL);
call 0 returned 100%
-: 1210:
113930: 1211: if (entry)
branch 0 taken 12% (fallthrough)
branch 1 taken 88%
14230: 1212: return entry->value;
-: 1213: else
99700: 1214: return NULL;
-: 1215:}
-: 1216:
-: 1217:#ifdef DBUS_BUILD_TESTS
-: 1218:/* disabled since it's only used for testing */
-: 1219:/**
-: 1220: * Looks up the value for a given integer in a hash table
-: 1221: * of type #DBUS_HASH_POINTER. Returns %NULL if the value
-: 1222: * is not present. (A not-present entry is indistinguishable
-: 1223: * from an entry with a value of %NULL.)
-: 1224: * @param table the hash table.
-: 1225: * @param key the integer to look up.
-: 1226: * @returns the value of the hash entry.
-: 1227: */
-: 1228:void*
-: 1229:_dbus_hash_table_lookup_pointer (DBusHashTable *table,
-: 1230: void *key)
function _dbus_hash_table_lookup_pointer called 0 returned 0% blocks executed 0%
#####: 1231:{
-: 1232: DBusHashEntry *entry;
-: 1233:
#####: 1234: _dbus_assert (table->key_type == DBUS_HASH_POINTER);
call 0 never executed
-: 1235:
#####: 1236: entry = (* table->find_function) (table, key, FALSE, NULL, NULL);
call 0 never executed
-: 1237:
#####: 1238: if (entry)
branch 0 never executed
branch 1 never executed
#####: 1239: return entry->value;
-: 1240: else
#####: 1241: return NULL;
-: 1242:}
-: 1243:#endif /* DBUS_BUILD_TESTS */
-: 1244:
-: 1245:/**
-: 1246: * Looks up the value for a given integer in a hash table
-: 1247: * of type #DBUS_HASH_ULONG. Returns %NULL if the value
-: 1248: * is not present. (A not-present entry is indistinguishable
-: 1249: * from an entry with a value of %NULL.)
-: 1250: * @param table the hash table.
-: 1251: * @param key the integer to look up.
-: 1252: * @returns the value of the hash entry.
-: 1253: */
-: 1254:void*
-: 1255:_dbus_hash_table_lookup_ulong (DBusHashTable *table,
-: 1256: unsigned long key)
function _dbus_hash_table_lookup_ulong called 33713 returned 100% blocks executed 100%
33713: 1257:{
-: 1258: DBusHashEntry *entry;
-: 1259:
33713: 1260: _dbus_assert (table->key_type == DBUS_HASH_ULONG);
call 0 returned 100%
-: 1261:
33713: 1262: entry = (* table->find_function) (table, (void*) key, FALSE, NULL, NULL);
call 0 returned 100%
-: 1263:
33713: 1264: if (entry)
branch 0 taken 99% (fallthrough)
branch 1 taken 1%
33695: 1265: return entry->value;
-: 1266: else
18: 1267: return NULL;
-: 1268:}
-: 1269:
-: 1270:/**
-: 1271: * Removes the hash entry for the given key. If no hash entry
-: 1272: * for the key exists, does nothing.
-: 1273: *
-: 1274: * @param table the hash table.
-: 1275: * @param key the hash key.
-: 1276: * @returns #TRUE if the entry existed
-: 1277: */
-: 1278:dbus_bool_t
-: 1279:_dbus_hash_table_remove_string (DBusHashTable *table,
-: 1280: const char *key)
function _dbus_hash_table_remove_string called 18485 returned 100% blocks executed 100%
18485: 1281:{
-: 1282: DBusHashEntry *entry;
-: 1283: DBusHashEntry **bucket;
-: 1284:
18485: 1285: _dbus_assert (table->key_type == DBUS_HASH_STRING);
call 0 returned 100%
-: 1286:
18485: 1287: entry = (* table->find_function) (table, (char*) key, FALSE, &bucket, NULL);
call 0 returned 100%
-: 1288:
18485: 1289: if (entry)
branch 0 taken 92% (fallthrough)
branch 1 taken 8%
-: 1290: {
17097: 1291: remove_entry (table, bucket, entry);
call 0 returned 100%
17097: 1292: return TRUE;
-: 1293: }
-: 1294: else
1388: 1295: return FALSE;
-: 1296:}
-: 1297:
-: 1298:#ifdef DBUS_BUILD_TESTS
-: 1299:/**
-: 1300: * Removes the hash entry for the given key. If no hash entry
-: 1301: * for the key exists, does nothing.
-: 1302: *
-: 1303: * @param table the hash table.
-: 1304: * @param key the hash key.
-: 1305: * @returns #TRUE if the entry existed
-: 1306: */
-: 1307:dbus_bool_t
-: 1308:_dbus_hash_table_remove_two_strings (DBusHashTable *table,
-: 1309: const char *key)
function _dbus_hash_table_remove_two_strings called 3000 returned 100% blocks executed 86%
3000: 1310:{
-: 1311: DBusHashEntry *entry;
-: 1312: DBusHashEntry **bucket;
-: 1313:
3000: 1314: _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
call 0 returned 100%
-: 1315:
3000: 1316: entry = (* table->find_function) (table, (char*) key, FALSE, &bucket, NULL);
call 0 returned 100%
-: 1317:
3000: 1318: if (entry)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
-: 1319: {
3000: 1320: remove_entry (table, bucket, entry);
call 0 returned 100%
3000: 1321: return TRUE;
-: 1322: }
-: 1323: else
#####: 1324: return FALSE;
-: 1325:}
-: 1326:#endif /* DBUS_BUILD_TESTS */
-: 1327:
-: 1328:/**
-: 1329: * Removes the hash entry for the given key. If no hash entry
-: 1330: * for the key exists, does nothing.
-: 1331: *
-: 1332: * @param table the hash table.
-: 1333: * @param key the hash key.
-: 1334: * @returns #TRUE if the entry existed
-: 1335: */
-: 1336:dbus_bool_t
-: 1337:_dbus_hash_table_remove_int (DBusHashTable *table,
-: 1338: int key)
function _dbus_hash_table_remove_int called 4346 returned 100% blocks executed 86%
4346: 1339:{
-: 1340: DBusHashEntry *entry;
-: 1341: DBusHashEntry **bucket;
-: 1342:
4346: 1343: _dbus_assert (table->key_type == DBUS_HASH_INT);
call 0 returned 100%
-: 1344:
4346: 1345: entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), FALSE, &bucket, NULL);
call 0 returned 100%
-: 1346:
4346: 1347: if (entry)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
-: 1348: {
4346: 1349: remove_entry (table, bucket, entry);
call 0 returned 100%
4346: 1350: return TRUE;
-: 1351: }
-: 1352: else
#####: 1353: return FALSE;
-: 1354:}
-: 1355:
-: 1356:#ifdef DBUS_BUILD_TESTS
-: 1357:/* disabled since it's only used for testing */
-: 1358:/**
-: 1359: * Removes the hash entry for the given key. If no hash entry
-: 1360: * for the key exists, does nothing.
-: 1361: *
-: 1362: * @param table the hash table.
-: 1363: * @param key the hash key.
-: 1364: * @returns #TRUE if the entry existed
-: 1365: */
-: 1366:dbus_bool_t
-: 1367:_dbus_hash_table_remove_pointer (DBusHashTable *table,
-: 1368: void *key)
function _dbus_hash_table_remove_pointer called 0 returned 0% blocks executed 0%
#####: 1369:{
-: 1370: DBusHashEntry *entry;
-: 1371: DBusHashEntry **bucket;
-: 1372:
#####: 1373: _dbus_assert (table->key_type == DBUS_HASH_POINTER);
call 0 never executed
-: 1374:
#####: 1375: entry = (* table->find_function) (table, key, FALSE, &bucket, NULL);
call 0 never executed
-: 1376:
#####: 1377: if (entry)
branch 0 never executed
branch 1 never executed
-: 1378: {
#####: 1379: remove_entry (table, bucket, entry);
call 0 never executed
#####: 1380: return TRUE;
-: 1381: }
-: 1382: else
#####: 1383: return FALSE;
-: 1384:}
-: 1385:#endif /* DBUS_BUILD_TESTS */
-: 1386:
-: 1387:/**
-: 1388: * Removes the hash entry for the given key. If no hash entry
-: 1389: * for the key exists, does nothing.
-: 1390: *
-: 1391: * @param table the hash table.
-: 1392: * @param key the hash key.
-: 1393: * @returns #TRUE if the entry existed
-: 1394: */
-: 1395:dbus_bool_t
-: 1396:_dbus_hash_table_remove_ulong (DBusHashTable *table,
-: 1397: unsigned long key)
function _dbus_hash_table_remove_ulong called 3003 returned 100% blocks executed 86%
3003: 1398:{
-: 1399: DBusHashEntry *entry;
-: 1400: DBusHashEntry **bucket;
-: 1401:
3003: 1402: _dbus_assert (table->key_type == DBUS_HASH_ULONG);
call 0 returned 100%
-: 1403:
3003: 1404: entry = (* table->find_function) (table, (void*) key, FALSE, &bucket, NULL);
call 0 returned 100%
-: 1405:
3003: 1406: if (entry)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
-: 1407: {
3003: 1408: remove_entry (table, bucket, entry);
call 0 returned 100%
3003: 1409: return TRUE;
-: 1410: }
-: 1411: else
#####: 1412: return FALSE;
-: 1413:}
-: 1414:
-: 1415:/**
-: 1416: * Creates a hash entry with the given key and value.
-: 1417: * The key and value are not copied; they are stored
-: 1418: * in the hash table by reference. If an entry with the
-: 1419: * given key already exists, the previous key and value
-: 1420: * are overwritten (and freed if the hash table has
-: 1421: * a key_free_function and/or value_free_function).
-: 1422: *
-: 1423: * Returns #FALSE if memory for the new hash entry
-: 1424: * can't be allocated.
-: 1425: *
-: 1426: * @param table the hash table.
-: 1427: * @param key the hash entry key.
-: 1428: * @param value the hash entry value.
-: 1429: */
-: 1430:dbus_bool_t
-: 1431:_dbus_hash_table_insert_string (DBusHashTable *table,
-: 1432: char *key,
-: 1433: void *value)
function _dbus_hash_table_insert_string called 22503 returned 100% blocks executed 100%
22503: 1434:{
-: 1435: DBusPreallocatedHash *preallocated;
-: 1436:
22503: 1437: _dbus_assert (table->key_type == DBUS_HASH_STRING);
call 0 returned 100%
-: 1438:
22503: 1439: preallocated = _dbus_hash_table_preallocate_entry (table);
call 0 returned 100%
22503: 1440: if (preallocated == NULL)
branch 0 taken 1% (fallthrough)
branch 1 taken 99%
23: 1441: return FALSE;
-: 1442:
22480: 1443: _dbus_hash_table_insert_string_preallocated (table, preallocated,
call 0 returned 100%
-: 1444: key, value);
-: 1445:
22480: 1446: return TRUE;
-: 1447:}
-: 1448:
-: 1449:#ifdef DBUS_BUILD_TESTS
-: 1450:/**
-: 1451: * Creates a hash entry with the given key and value.
-: 1452: * The key and value are not copied; they are stored
-: 1453: * in the hash table by reference. If an entry with the
-: 1454: * given key already exists, the previous key and value
-: 1455: * are overwritten (and freed if the hash table has
-: 1456: * a key_free_function and/or value_free_function).
-: 1457: *
-: 1458: * Returns #FALSE if memory for the new hash entry
-: 1459: * can't be allocated.
-: 1460: *
-: 1461: * @param table the hash table.
-: 1462: * @param key the hash entry key.
-: 1463: * @param value the hash entry value.
-: 1464: */
-: 1465:dbus_bool_t
-: 1466:_dbus_hash_table_insert_two_strings (DBusHashTable *table,
-: 1467: char *key,
-: 1468: void *value)
function _dbus_hash_table_insert_two_strings called 3000 returned 100% blocks executed 83%
3000: 1469:{
-: 1470: DBusHashEntry *entry;
-: 1471:
3000: 1472: _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
call 0 returned 100%
-: 1473:
3000: 1474: entry = (* table->find_function) (table, key, TRUE, NULL, NULL);
call 0 returned 100%
-: 1475:
3000: 1476: if (entry == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1477: return FALSE; /* no memory */
-: 1478:
3000: 1479: if (table->free_key_function && entry->key != key)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
branch 2 taken 0% (fallthrough)
branch 3 taken 100%
#####: 1480: (* table->free_key_function) (entry->key);
call 0 never executed
-: 1481:
3000: 1482: if (table->free_value_function && entry->value != value)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
branch 2 taken 100% (fallthrough)
branch 3 taken 0%
3000: 1483: (* table->free_value_function) (entry->value);
call 0 returned 100%
-: 1484:
3000: 1485: entry->key = key;
3000: 1486: entry->value = value;
-: 1487:
3000: 1488: return TRUE;
-: 1489:}
-: 1490:#endif /* DBUS_BUILD_TESTS */
-: 1491:
-: 1492:/**
-: 1493: * Creates a hash entry with the given key and value.
-: 1494: * The key and value are not copied; they are stored
-: 1495: * in the hash table by reference. If an entry with the
-: 1496: * given key already exists, the previous key and value
-: 1497: * are overwritten (and freed if the hash table has
-: 1498: * a key_free_function and/or value_free_function).
-: 1499: *
-: 1500: * Returns #FALSE if memory for the new hash entry
-: 1501: * can't be allocated.
-: 1502: *
-: 1503: * @param table the hash table.
-: 1504: * @param key the hash entry key.
-: 1505: * @param value the hash entry value.
-: 1506: */
-: 1507:dbus_bool_t
-: 1508:_dbus_hash_table_insert_int (DBusHashTable *table,
-: 1509: int key,
-: 1510: void *value)
function _dbus_hash_table_insert_int called 9346 returned 100% blocks executed 75%
9346: 1511:{
-: 1512: DBusHashEntry *entry;
-: 1513:
9346: 1514: _dbus_assert (table->key_type == DBUS_HASH_INT);
call 0 returned 100%
-: 1515:
9346: 1516: entry = (* table->find_function) (table, _DBUS_INT_TO_POINTER (key), TRUE, NULL, NULL);
call 0 returned 100%
-: 1517:
9346: 1518: if (entry == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1519: return FALSE; /* no memory */
-: 1520:
9346: 1521: if (table->free_key_function && entry->key != _DBUS_INT_TO_POINTER (key))
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
branch 2 never executed
branch 3 never executed
#####: 1522: (* table->free_key_function) (entry->key);
call 0 never executed
-: 1523:
9346: 1524: if (table->free_value_function && entry->value != value)
branch 0 taken 100% (fallthrough)
branch 1 taken 0%
branch 2 taken 100% (fallthrough)
branch 3 taken 0%
9346: 1525: (* table->free_value_function) (entry->value);
call 0 returned 100%
-: 1526:
9346: 1527: entry->key = _DBUS_INT_TO_POINTER (key);
9346: 1528: entry->value = value;
-: 1529:
9346: 1530: return TRUE;
-: 1531:}
-: 1532:
-: 1533:#ifdef DBUS_BUILD_TESTS
-: 1534:/* disabled since it's only used for testing */
-: 1535:/**
-: 1536: * Creates a hash entry with the given key and value.
-: 1537: * The key and value are not copied; they are stored
-: 1538: * in the hash table by reference. If an entry with the
-: 1539: * given key already exists, the previous key and value
-: 1540: * are overwritten (and freed if the hash table has
-: 1541: * a key_free_function and/or value_free_function).
-: 1542: *
-: 1543: * Returns #FALSE if memory for the new hash entry
-: 1544: * can't be allocated.
-: 1545: *
-: 1546: * @param table the hash table.
-: 1547: * @param key the hash entry key.
-: 1548: * @param value the hash entry value.
-: 1549: */
-: 1550:dbus_bool_t
-: 1551:_dbus_hash_table_insert_pointer (DBusHashTable *table,
-: 1552: void *key,
-: 1553: void *value)
function _dbus_hash_table_insert_pointer called 0 returned 0% blocks executed 0%
#####: 1554:{
-: 1555: DBusHashEntry *entry;
-: 1556:
#####: 1557: _dbus_assert (table->key_type == DBUS_HASH_POINTER);
call 0 never executed
-: 1558:
#####: 1559: entry = (* table->find_function) (table, key, TRUE, NULL, NULL);
call 0 never executed
-: 1560:
#####: 1561: if (entry == NULL)
branch 0 never executed
branch 1 never executed
#####: 1562: return FALSE; /* no memory */
-: 1563:
#####: 1564: if (table->free_key_function && entry->key != key)
branch 0 never executed
branch 1 never executed
branch 2 never executed
branch 3 never executed
#####: 1565: (* table->free_key_function) (entry->key);
call 0 never executed
-: 1566:
#####: 1567: if (table->free_value_function && entry->value != value)
branch 0 never executed
branch 1 never executed
branch 2 never executed
branch 3 never executed
#####: 1568: (* table->free_value_function) (entry->value);
call 0 never executed
-: 1569:
#####: 1570: entry->key = key;
#####: 1571: entry->value = value;
-: 1572:
#####: 1573: return TRUE;
-: 1574:}
-: 1575:#endif /* DBUS_BUILD_TESTS */
-: 1576:
-: 1577:/**
-: 1578: * Creates a hash entry with the given key and value.
-: 1579: * The key and value are not copied; they are stored
-: 1580: * in the hash table by reference. If an entry with the
-: 1581: * given key already exists, the previous key and value
-: 1582: * are overwritten (and freed if the hash table has
-: 1583: * a key_free_function and/or value_free_function).
-: 1584: *
-: 1585: * Returns #FALSE if memory for the new hash entry
-: 1586: * can't be allocated.
-: 1587: *
-: 1588: * @param table the hash table.
-: 1589: * @param key the hash entry key.
-: 1590: * @param value the hash entry value.
-: 1591: */
-: 1592:dbus_bool_t
-: 1593:_dbus_hash_table_insert_ulong (DBusHashTable *table,
-: 1594: unsigned long key,
-: 1595: void *value)
function _dbus_hash_table_insert_ulong called 15202 returned 100% blocks executed 75%
15202: 1596:{
-: 1597: DBusHashEntry *entry;
-: 1598:
15202: 1599: _dbus_assert (table->key_type == DBUS_HASH_ULONG);
call 0 returned 100%
-: 1600:
15202: 1601: entry = (* table->find_function) (table, (void*) key, TRUE, NULL, NULL);
call 0 returned 100%
-: 1602:
15202: 1603: if (entry == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1604: return FALSE; /* no memory */
-: 1605:
15202: 1606: if (table->free_key_function && entry->key != (void*) key)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
branch 2 never executed
branch 3 never executed
#####: 1607: (* table->free_key_function) (entry->key);
call 0 never executed
-: 1608:
15202: 1609: if (table->free_value_function && entry->value != value)
branch 0 taken 20% (fallthrough)
branch 1 taken 80%
branch 2 taken 100% (fallthrough)
branch 3 taken 0%
3013: 1610: (* table->free_value_function) (entry->value);
call 0 returned 100%
-: 1611:
15202: 1612: entry->key = (void*) key;
15202: 1613: entry->value = value;
-: 1614:
15202: 1615: return TRUE;
-: 1616:}
-: 1617:
-: 1618:/**
-: 1619: * Preallocate an opaque data blob that allows us to insert into the
-: 1620: * hash table at a later time without allocating any memory.
-: 1621: *
-: 1622: * @param table the hash table
-: 1623: * @returns the preallocated data, or #NULL if no memory
-: 1624: */
-: 1625:DBusPreallocatedHash*
-: 1626:_dbus_hash_table_preallocate_entry (DBusHashTable *table)
function _dbus_hash_table_preallocate_entry called 31025 returned 100% blocks executed 100%
31025: 1627:{
-: 1628: DBusHashEntry *entry;
-: 1629:
31025: 1630: entry = alloc_entry (table);
call 0 returned 100%
-: 1631:
31025: 1632: return (DBusPreallocatedHash*) entry;
-: 1633:}
-: 1634:
-: 1635:/**
-: 1636: * Frees an opaque DBusPreallocatedHash that was *not* used
-: 1637: * in order to insert into the hash table.
-: 1638: *
-: 1639: * @param table the hash table
-: 1640: * @param preallocated the preallocated data
-: 1641: */
-: 1642:void
-: 1643:_dbus_hash_table_free_preallocated_entry (DBusHashTable *table,
-: 1644: DBusPreallocatedHash *preallocated)
function _dbus_hash_table_free_preallocated_entry called 8410 returned 100% blocks executed 100%
8410: 1645:{
-: 1646: DBusHashEntry *entry;
-: 1647:
8410: 1648: _dbus_assert (preallocated != NULL);
call 0 returned 100%
-: 1649:
8410: 1650: entry = (DBusHashEntry*) preallocated;
-: 1651:
-: 1652: /* Don't use free_entry(), since this entry has no key/data */
8410: 1653: _dbus_mem_pool_dealloc (table->entry_pool, entry);
call 0 returned 100%
8410: 1654:}
-: 1655:
-: 1656:/**
-: 1657: * Inserts a string-keyed entry into the hash table, using a
-: 1658: * preallocated data block from
-: 1659: * _dbus_hash_table_preallocate_entry(). This function cannot fail due
-: 1660: * to lack of memory. The DBusPreallocatedHash object is consumed and
-: 1661: * should not be reused or freed. Otherwise this function works
-: 1662: * just like _dbus_hash_table_insert_string().
-: 1663: *
-: 1664: * @param table the hash table
-: 1665: * @param preallocated the preallocated data
-: 1666: * @param key the hash key
-: 1667: * @param value the value
-: 1668: */
-: 1669:void
-: 1670:_dbus_hash_table_insert_string_preallocated (DBusHashTable *table,
-: 1671: DBusPreallocatedHash *preallocated,
-: 1672: char *key,
-: 1673: void *value)
function _dbus_hash_table_insert_string_preallocated called 22578 returned 100% blocks executed 91%
22578: 1674:{
-: 1675: DBusHashEntry *entry;
-: 1676:
22578: 1677: _dbus_assert (table->key_type == DBUS_HASH_STRING);
call 0 returned 100%
22578: 1678: _dbus_assert (preallocated != NULL);
call 0 returned 100%
-: 1679:
22578: 1680: entry = (* table->find_function) (table, key, TRUE, NULL, preallocated);
call 0 returned 100%
-: 1681:
22578: 1682: _dbus_assert (entry != NULL);
call 0 returned 100%
-: 1683:
22578: 1684: if (table->free_key_function && entry->key != key)
branch 0 taken 48% (fallthrough)
branch 1 taken 52%
branch 2 taken 0% (fallthrough)
branch 3 taken 100%
#####: 1685: (* table->free_key_function) (entry->key);
call 0 never executed
-: 1686:
22578: 1687: if (table->free_value_function && entry->value != value)
branch 0 taken 65% (fallthrough)
branch 1 taken 35%
branch 2 taken 100% (fallthrough)
branch 3 taken 0%
14657: 1688: (* table->free_value_function) (entry->value);
call 0 returned 100%
-: 1689:
22578: 1690: entry->key = key;
22578: 1691: entry->value = value;
22578: 1692:}
-: 1693:
-: 1694:/**
-: 1695: * Gets the number of hash entries in a hash table.
-: 1696: *
-: 1697: * @param table the hash table.
-: 1698: * @returns the number of entries in the table.
-: 1699: */
-: 1700:int
-: 1701:_dbus_hash_table_get_n_entries (DBusHashTable *table)
function _dbus_hash_table_get_n_entries called 69237 returned 100% blocks executed 100%
69237: 1702:{
69237: 1703: return table->n_entries;
-: 1704:}
-: 1705:
-: 1706:/** @} */
-: 1707:
-: 1708:#ifdef DBUS_BUILD_TESTS
-: 1709:#include "dbus-test.h"
-: 1710:#include <stdio.h>
-: 1711:
-: 1712:/* If you're wondering why the hash table test takes
-: 1713: * forever to run, it's because we call this function
-: 1714: * in inner loops thus making things quadratic.
-: 1715: */
-: 1716:static int
-: 1717:count_entries (DBusHashTable *table)
function count_entries called 56001 returned 100% blocks executed 100%
56001: 1718:{
-: 1719: DBusHashIter iter;
-: 1720: int count;
-: 1721:
56001: 1722: count = 0;
56001: 1723: _dbus_hash_iter_init (table, &iter);
call 0 returned 100%
104117002: 1724: while (_dbus_hash_iter_next (&iter))
call 0 returned 100%
branch 1 taken 99%
branch 2 taken 1% (fallthrough)
104005000: 1725: ++count;
-: 1726:
56001: 1727: _dbus_assert (count == _dbus_hash_table_get_n_entries (table));
call 0 returned 100%
call 1 returned 100%
-: 1728:
56001: 1729: return count;
-: 1730:}
-: 1731:
-: 1732:/* Copy the foo\0bar\0 double string thing */
-: 1733:static char*
-: 1734:_dbus_strdup2 (const char *str)
function _dbus_strdup2 called 3000 returned 100% blocks executed 80%
3000: 1735:{
-: 1736: size_t len;
-: 1737: char *copy;
-: 1738:
3000: 1739: if (str == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1740: return NULL;
-: 1741:
3000: 1742: len = strlen (str);
call 0 returned 100%
3000: 1743: len += strlen ((str + len + 1));
call 0 returned 100%
-: 1744:
3000: 1745: copy = dbus_malloc (len + 2);
call 0 returned 100%
3000: 1746: if (copy == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1747: return NULL;
-: 1748:
3000: 1749: memcpy (copy, str, len + 2);
call 0 returned 100%
-: 1750:
3000: 1751: return copy;
-: 1752:}
-: 1753:
-: 1754:/**
-: 1755: * @ingroup DBusHashTableInternals
-: 1756: * Unit test for DBusHashTable
-: 1757: * @returns #TRUE on success.
-: 1758: */
-: 1759:dbus_bool_t
-: 1760:_dbus_hash_test (void)
function _dbus_hash_test called 1 returned 100% blocks executed 85%
1: 1761:{
-: 1762: int i;
-: 1763: DBusHashTable *table1;
-: 1764: DBusHashTable *table2;
-: 1765: DBusHashTable *table3;
-: 1766: DBusHashTable *table4;
-: 1767: DBusHashIter iter;
-: 1768:#define N_HASH_KEYS 5000
-: 1769: char **keys;
1: 1770: dbus_bool_t ret = FALSE;
-: 1771:
1: 1772: keys = dbus_new (char *, N_HASH_KEYS);
call 0 returned 100%
1: 1773: if (keys == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1774: _dbus_assert_not_reached ("no memory");
call 0 never executed
-: 1775:
5001: 1776: for (i = 0; i < N_HASH_KEYS; i++)
branch 0 taken 99%
branch 1 taken 1% (fallthrough)
-: 1777: {
5000: 1778: keys[i] = dbus_malloc (128);
call 0 returned 100%
-: 1779:
5000: 1780: if (keys[i] == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1781: _dbus_assert_not_reached ("no memory");
call 0 never executed
-: 1782: }
-: 1783:
1: 1784: printf ("Computing test hash keys...\n");
call 0 returned 100%
1: 1785: i = 0;
5002: 1786: while (i < N_HASH_KEYS)
branch 0 taken 99%
branch 1 taken 1% (fallthrough)
-: 1787: {
-: 1788: int len;
-: 1789:
-: 1790: /* all the hash keys are TWO_STRINGS, but
-: 1791: * then we can also use those as regular strings.
-: 1792: */
-: 1793:
5000: 1794: len = sprintf (keys[i], "Hash key %d", i);
call 0 returned 100%
5000: 1795: sprintf (keys[i] + len + 1, "Two string %d", i);
call 0 returned 100%
5000: 1796: _dbus_assert (*(keys[i] + len) == '\0');
call 0 returned 100%
5000: 1797: _dbus_assert (*(keys[i] + len + 1) != '\0');
call 0 returned 100%
5000: 1798: ++i;
-: 1799: }
1: 1800: printf ("... done.\n");
call 0 returned 100%
-: 1801:
1: 1802: table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
call 0 returned 100%
-: 1803: dbus_free, dbus_free);
1: 1804: if (table1 == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1805: goto out;
-: 1806:
1: 1807: table2 = _dbus_hash_table_new (DBUS_HASH_INT,
call 0 returned 100%
-: 1808: NULL, dbus_free);
1: 1809: if (table2 == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1810: goto out;
-: 1811:
1: 1812: table3 = _dbus_hash_table_new (DBUS_HASH_ULONG,
call 0 returned 100%
-: 1813: NULL, dbus_free);
1: 1814: if (table3 == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1815: goto out;
-: 1816:
1: 1817: table4 = _dbus_hash_table_new (DBUS_HASH_TWO_STRINGS,
call 0 returned 100%
-: 1818: dbus_free, dbus_free);
1: 1819: if (table4 == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1820: goto out;
-: 1821:
-: 1822:
-: 1823: /* Insert and remove a bunch of stuff, counting the table in between
-: 1824: * to be sure it's not broken and that iteration works
-: 1825: */
1: 1826: i = 0;
3002: 1827: while (i < 3000)
branch 0 taken 99%
branch 1 taken 1% (fallthrough)
-: 1828: {
-: 1829: void *value;
-: 1830: char *key;
-: 1831:
3000: 1832: key = _dbus_strdup (keys[i]);
call 0 returned 100%
3000: 1833: if (key == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1834: goto out;
3000: 1835: value = _dbus_strdup ("Value!");
call 0 returned 100%
3000: 1836: if (value == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1837: goto out;
-: 1838:
3000: 1839: if (!_dbus_hash_table_insert_string (table1,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 1840: key, value))
#####: 1841: goto out;
-: 1842:
3000: 1843: value = _dbus_strdup (keys[i]);
call 0 returned 100%
3000: 1844: if (value == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1845: goto out;
-: 1846:
3000: 1847: if (!_dbus_hash_table_insert_int (table2,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 1848: i, value))
#####: 1849: goto out;
-: 1850:
3000: 1851: value = _dbus_strdup (keys[i]);
call 0 returned 100%
3000: 1852: if (value == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1853: goto out;
-: 1854:
3000: 1855: if (!_dbus_hash_table_insert_ulong (table3,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 1856: i, value))
#####: 1857: goto out;
-: 1858:
3000: 1859: key = _dbus_strdup2 (keys[i]);
call 0 returned 100%
3000: 1860: if (key == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1861: goto out;
3000: 1862: value = _dbus_strdup ("Value!");
call 0 returned 100%
3000: 1863: if (value == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1864: goto out;
-: 1865:
3000: 1866: if (!_dbus_hash_table_insert_two_strings (table4,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 1867: key, value))
#####: 1868: goto out;
-: 1869:
3000: 1870: _dbus_assert (count_entries (table1) == i + 1);
call 0 returned 100%
call 1 returned 100%
3000: 1871: _dbus_assert (count_entries (table2) == i + 1);
call 0 returned 100%
call 1 returned 100%
3000: 1872: _dbus_assert (count_entries (table3) == i + 1);
call 0 returned 100%
call 1 returned 100%
3000: 1873: _dbus_assert (count_entries (table4) == i + 1);
call 0 returned 100%
call 1 returned 100%
-: 1874:
3000: 1875: value = _dbus_hash_table_lookup_string (table1, keys[i]);
call 0 returned 100%
3000: 1876: _dbus_assert (value != NULL);
call 0 returned 100%
3000: 1877: _dbus_assert (strcmp (value, "Value!") == 0);
call 0 returned 100%
call 1 returned 100%
-: 1878:
3000: 1879: value = _dbus_hash_table_lookup_int (table2, i);
call 0 returned 100%
3000: 1880: _dbus_assert (value != NULL);
call 0 returned 100%
3000: 1881: _dbus_assert (strcmp (value, keys[i]) == 0);
call 0 returned 100%
call 1 returned 100%
-: 1882:
3000: 1883: value = _dbus_hash_table_lookup_ulong (table3, i);
call 0 returned 100%
3000: 1884: _dbus_assert (value != NULL);
call 0 returned 100%
3000: 1885: _dbus_assert (strcmp (value, keys[i]) == 0);
call 0 returned 100%
call 1 returned 100%
-: 1886:
3000: 1887: value = _dbus_hash_table_lookup_two_strings (table4, keys[i]);
call 0 returned 100%
3000: 1888: _dbus_assert (value != NULL);
call 0 returned 100%
3000: 1889: _dbus_assert (strcmp (value, "Value!") == 0);
call 0 returned 100%
call 1 returned 100%
-: 1890:
3000: 1891: ++i;
-: 1892: }
-: 1893:
1: 1894: --i;
3002: 1895: while (i >= 0)
branch 0 taken 99%
branch 1 taken 1% (fallthrough)
-: 1896: {
3000: 1897: _dbus_hash_table_remove_string (table1,
call 0 returned 100%
-: 1898: keys[i]);
-: 1899:
3000: 1900: _dbus_hash_table_remove_int (table2, i);
call 0 returned 100%
-: 1901:
3000: 1902: _dbus_hash_table_remove_ulong (table3, i);
call 0 returned 100%
-: 1903:
3000: 1904: _dbus_hash_table_remove_two_strings (table4,
call 0 returned 100%
-: 1905: keys[i]);
-: 1906:
3000: 1907: _dbus_assert (count_entries (table1) == i);
call 0 returned 100%
call 1 returned 100%
3000: 1908: _dbus_assert (count_entries (table2) == i);
call 0 returned 100%
call 1 returned 100%
3000: 1909: _dbus_assert (count_entries (table3) == i);
call 0 returned 100%
call 1 returned 100%
3000: 1910: _dbus_assert (count_entries (table4) == i);
call 0 returned 100%
call 1 returned 100%
-: 1911:
3000: 1912: --i;
-: 1913: }
-: 1914:
1: 1915: _dbus_hash_table_ref (table1);
call 0 returned 100%
1: 1916: _dbus_hash_table_ref (table2);
call 0 returned 100%
1: 1917: _dbus_hash_table_ref (table3);
call 0 returned 100%
1: 1918: _dbus_hash_table_ref (table4);
call 0 returned 100%
1: 1919: _dbus_hash_table_unref (table1);
call 0 returned 100%
1: 1920: _dbus_hash_table_unref (table2);
call 0 returned 100%
1: 1921: _dbus_hash_table_unref (table3);
call 0 returned 100%
1: 1922: _dbus_hash_table_unref (table4);
call 0 returned 100%
1: 1923: _dbus_hash_table_unref (table1);
call 0 returned 100%
1: 1924: _dbus_hash_table_unref (table2);
call 0 returned 100%
1: 1925: _dbus_hash_table_unref (table3);
call 0 returned 100%
1: 1926: _dbus_hash_table_unref (table4);
call 0 returned 100%
1: 1927: table3 = NULL;
-: 1928:
-: 1929: /* Insert a bunch of stuff then check
-: 1930: * that iteration works correctly (finds the right
-: 1931: * values, iter_set_value works, etc.)
-: 1932: */
1: 1933: table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
call 0 returned 100%
-: 1934: dbus_free, dbus_free);
1: 1935: if (table1 == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1936: goto out;
-: 1937:
1: 1938: table2 = _dbus_hash_table_new (DBUS_HASH_INT,
call 0 returned 100%
-: 1939: NULL, dbus_free);
1: 1940: if (table2 == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1941: goto out;
-: 1942:
1: 1943: i = 0;
5002: 1944: while (i < 5000)
branch 0 taken 99%
branch 1 taken 1% (fallthrough)
-: 1945: {
-: 1946: char *key;
-: 1947: void *value;
-: 1948:
5000: 1949: key = _dbus_strdup (keys[i]);
call 0 returned 100%
5000: 1950: if (key == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1951: goto out;
5000: 1952: value = _dbus_strdup ("Value!");
call 0 returned 100%
5000: 1953: if (value == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1954: goto out;
-: 1955:
5000: 1956: if (!_dbus_hash_table_insert_string (table1,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 1957: key, value))
#####: 1958: goto out;
-: 1959:
5000: 1960: value = _dbus_strdup (keys[i]);
call 0 returned 100%
5000: 1961: if (value == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1962: goto out;
-: 1963:
5000: 1964: if (!_dbus_hash_table_insert_int (table2,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 1965: i, value))
#####: 1966: goto out;
-: 1967:
5000: 1968: _dbus_assert (count_entries (table1) == i + 1);
call 0 returned 100%
call 1 returned 100%
5000: 1969: _dbus_assert (count_entries (table2) == i + 1);
call 0 returned 100%
call 1 returned 100%
-: 1970:
5000: 1971: ++i;
-: 1972: }
-: 1973:
1: 1974: _dbus_hash_iter_init (table1, &iter);
call 0 returned 100%
5002: 1975: while (_dbus_hash_iter_next (&iter))
call 0 returned 100%
branch 1 taken 99%
branch 2 taken 1% (fallthrough)
-: 1976: {
-: 1977: const char *key;
-: 1978: void *value;
-: 1979:
5000: 1980: key = _dbus_hash_iter_get_string_key (&iter);
call 0 returned 100%
5000: 1981: value = _dbus_hash_iter_get_value (&iter);
call 0 returned 100%
-: 1982:
5000: 1983: _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
call 0 returned 100%
call 1 returned 100%
-: 1984:
5000: 1985: value = _dbus_strdup ("Different value!");
call 0 returned 100%
5000: 1986: if (value == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 1987: goto out;
-: 1988:
5000: 1989: _dbus_hash_iter_set_value (&iter, value);
call 0 returned 100%
-: 1990:
5000: 1991: _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
call 0 returned 100%
call 1 returned 100%
-: 1992: }
-: 1993:
1: 1994: _dbus_hash_iter_init (table1, &iter);
call 0 returned 100%
5002: 1995: while (_dbus_hash_iter_next (&iter))
call 0 returned 100%
branch 1 taken 99%
branch 2 taken 1% (fallthrough)
-: 1996: {
5000: 1997: _dbus_hash_iter_remove_entry (&iter);
call 0 returned 100%
5000: 1998: _dbus_assert (count_entries (table1) == i - 1);
call 0 returned 100%
call 1 returned 100%
5000: 1999: --i;
-: 2000: }
-: 2001:
1: 2002: _dbus_hash_iter_init (table2, &iter);
call 0 returned 100%
5002: 2003: while (_dbus_hash_iter_next (&iter))
call 0 returned 100%
branch 1 taken 99%
branch 2 taken 1% (fallthrough)
-: 2004: {
-: 2005: int key;
-: 2006: void *value;
-: 2007:
5000: 2008: key = _dbus_hash_iter_get_int_key (&iter);
call 0 returned 100%
5000: 2009: value = _dbus_hash_iter_get_value (&iter);
call 0 returned 100%
-: 2010:
5000: 2011: _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
call 0 returned 100%
call 1 returned 100%
-: 2012:
5000: 2013: value = _dbus_strdup ("Different value!");
call 0 returned 100%
5000: 2014: if (value == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 2015: goto out;
-: 2016:
5000: 2017: _dbus_hash_iter_set_value (&iter, value);
call 0 returned 100%
-: 2018:
5000: 2019: _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
call 0 returned 100%
call 1 returned 100%
-: 2020: }
-: 2021:
1: 2022: i = count_entries (table2);
call 0 returned 100%
1: 2023: _dbus_hash_iter_init (table2, &iter);
call 0 returned 100%
5002: 2024: while (_dbus_hash_iter_next (&iter))
call 0 returned 100%
branch 1 taken 99%
branch 2 taken 1% (fallthrough)
-: 2025: {
5000: 2026: _dbus_hash_iter_remove_entry (&iter);
call 0 returned 100%
5000: 2027: _dbus_assert (count_entries (table2) + 1 == i);
call 0 returned 100%
call 1 returned 100%
5000: 2028: --i;
-: 2029: }
-: 2030:
-: 2031: /* add/remove interleaved, to check that we grow/shrink the table
-: 2032: * appropriately
-: 2033: */
1: 2034: i = 0;
1002: 2035: while (i < 1000)
branch 0 taken 99%
branch 1 taken 1% (fallthrough)
-: 2036: {
-: 2037: char *key;
-: 2038: void *value;
-: 2039:
1000: 2040: key = _dbus_strdup (keys[i]);
call 0 returned 100%
1000: 2041: if (key == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 2042: goto out;
-: 2043:
1000: 2044: value = _dbus_strdup ("Value!");
call 0 returned 100%
1000: 2045: if (value == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 2046: goto out;
-: 2047:
1000: 2048: if (!_dbus_hash_table_insert_string (table1,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 2049: key, value))
#####: 2050: goto out;
-: 2051:
1000: 2052: ++i;
-: 2053: }
-: 2054:
1: 2055: --i;
1002: 2056: while (i >= 0)
branch 0 taken 99%
branch 1 taken 1% (fallthrough)
-: 2057: {
-: 2058: char *key;
-: 2059: void *value;
-: 2060:
1000: 2061: key = _dbus_strdup (keys[i]);
call 0 returned 100%
1000: 2062: if (key == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 2063: goto out;
1000: 2064: value = _dbus_strdup ("Value!");
call 0 returned 100%
1000: 2065: if (value == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 2066: goto out;
-: 2067:
1000: 2068: if (!_dbus_hash_table_remove_string (table1, keys[i]))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 2069: goto out;
-: 2070:
1000: 2071: if (!_dbus_hash_table_insert_string (table1,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 2072: key, value))
#####: 2073: goto out;
-: 2074:
1000: 2075: if (!_dbus_hash_table_remove_string (table1, keys[i]))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 2076: goto out;
-: 2077:
1000: 2078: _dbus_assert (_dbus_hash_table_get_n_entries (table1) == i);
call 0 returned 100%
call 1 returned 100%
-: 2079:
1000: 2080: --i;
-: 2081: }
-: 2082:
-: 2083: /* nuke these tables */
1: 2084: _dbus_hash_table_unref (table1);
call 0 returned 100%
1: 2085: _dbus_hash_table_unref (table2);
call 0 returned 100%
-: 2086:
-: 2087:
-: 2088: /* Now do a bunch of things again using _dbus_hash_iter_lookup() to
-: 2089: * be sure that interface works.
-: 2090: */
1: 2091: table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
call 0 returned 100%
-: 2092: dbus_free, dbus_free);
1: 2093: if (table1 == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 2094: goto out;
-: 2095:
1: 2096: table2 = _dbus_hash_table_new (DBUS_HASH_INT,
call 0 returned 100%
-: 2097: NULL, dbus_free);
1: 2098: if (table2 == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 2099: goto out;
-: 2100:
1: 2101: i = 0;
3002: 2102: while (i < 3000)
branch 0 taken 99%
branch 1 taken 1% (fallthrough)
-: 2103: {
-: 2104: void *value;
-: 2105: char *key;
-: 2106:
3000: 2107: key = _dbus_strdup (keys[i]);
call 0 returned 100%
3000: 2108: if (key == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 2109: goto out;
3000: 2110: value = _dbus_strdup ("Value!");
call 0 returned 100%
3000: 2111: if (value == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 2112: goto out;
-: 2113:
3000: 2114: if (!_dbus_hash_iter_lookup (table1,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 2115: key, TRUE, &iter))
#####: 2116: goto out;
3000: 2117: _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
call 0 returned 100%
call 1 returned 100%
3000: 2118: _dbus_hash_iter_set_value (&iter, value);
call 0 returned 100%
-: 2119:
3000: 2120: value = _dbus_strdup (keys[i]);
call 0 returned 100%
3000: 2121: if (value == NULL)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 2122: goto out;
-: 2123:
3000: 2124: if (!_dbus_hash_iter_lookup (table2,
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
-: 2125: _DBUS_INT_TO_POINTER (i), TRUE, &iter))
#####: 2126: goto out;
3000: 2127: _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL);
call 0 returned 100%
call 1 returned 100%
3000: 2128: _dbus_hash_iter_set_value (&iter, value);
call 0 returned 100%
-: 2129:
3000: 2130: _dbus_assert (count_entries (table1) == i + 1);
call 0 returned 100%
call 1 returned 100%
3000: 2131: _dbus_assert (count_entries (table2) == i + 1);
call 0 returned 100%
call 1 returned 100%
-: 2132:
3000: 2133: if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 2134: goto out;
-: 2135:
3000: 2136: value = _dbus_hash_iter_get_value (&iter);
call 0 returned 100%
3000: 2137: _dbus_assert (value != NULL);
call 0 returned 100%
3000: 2138: _dbus_assert (strcmp (value, "Value!") == 0);
call 0 returned 100%
call 1 returned 100%
-: 2139:
-: 2140: /* Iterate just to be sure it works, though
-: 2141: * it's a stupid thing to do
-: 2142: */
2325970: 2143: while (_dbus_hash_iter_next (&iter))
call 0 returned 100%
branch 1 taken 99%
branch 2 taken 1% (fallthrough)
-: 2144: ;
-: 2145:
3000: 2146: if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 2147: goto out;
-: 2148:
3000: 2149: value = _dbus_hash_iter_get_value (&iter);
call 0 returned 100%
3000: 2150: _dbus_assert (value != NULL);
call 0 returned 100%
3000: 2151: _dbus_assert (strcmp (value, keys[i]) == 0);
call 0 returned 100%
call 1 returned 100%
-: 2152:
-: 2153: /* Iterate just to be sure it works, though
-: 2154: * it's a stupid thing to do
-: 2155: */
2240127: 2156: while (_dbus_hash_iter_next (&iter))
call 0 returned 100%
branch 1 taken 99%
branch 2 taken 1% (fallthrough)
-: 2157: ;
-: 2158:
3000: 2159: ++i;
-: 2160: }
-: 2161:
1: 2162: --i;
3002: 2163: while (i >= 0)
branch 0 taken 99%
branch 1 taken 1% (fallthrough)
-: 2164: {
3000: 2165: if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 2166: _dbus_assert_not_reached ("hash entry should have existed");
call 0 never executed
3000: 2167: _dbus_hash_iter_remove_entry (&iter);
call 0 returned 100%
-: 2168:
3000: 2169: if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter))
call 0 returned 100%
branch 1 taken 0% (fallthrough)
branch 2 taken 100%
#####: 2170: _dbus_assert_not_reached ("hash entry should have existed");
call 0 never executed
3000: 2171: _dbus_hash_iter_remove_entry (&iter);
call 0 returned 100%
-: 2172:
3000: 2173: _dbus_assert (count_entries (table1) == i);
call 0 returned 100%
call 1 returned 100%
3000: 2174: _dbus_assert (count_entries (table2) == i);
call 0 returned 100%
call 1 returned 100%
-: 2175:
3000: 2176: --i;
-: 2177: }
-: 2178:
1: 2179: _dbus_hash_table_unref (table1);
call 0 returned 100%
1: 2180: _dbus_hash_table_unref (table2);
call 0 returned 100%
-: 2181:
1: 2182: ret = TRUE;
-: 2183:
1: 2184: out:
5001: 2185: for (i = 0; i < N_HASH_KEYS; i++)
branch 0 taken 99%
branch 1 taken 1% (fallthrough)
5000: 2186: dbus_free (keys[i]);
call 0 returned 100%
-: 2187:
1: 2188: dbus_free (keys);
call 0 returned 100%
-: 2189:
1: 2190: return ret;
-: 2191:}
-: 2192:
-: 2193:#endif /* DBUS_BUILD_TESTS */