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 */