Sophie

Sophie

distrib > Mandriva > 2007.0 > x86_64 > media > main-release > by-pkgid > 926d2d1e3111287cee1b0a4fad4fb4f6 > files > 82

lib64dbus-1_3-devel-0.92-6mdv2007.0.x86_64.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>dbus-hash.c Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.2.15 -->
<center>
<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; <a class="qindex" href="annotated.html">Data Structures</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Data Fields</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; </center>
<hr><h1>dbus-hash.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font>
00002 <font class="comment">/* dbus-hash.c Generic hash table utility (internal to D-BUS implementation)</font>
00003 <font class="comment"> * </font>
00004 <font class="comment"> * Copyright (C) 2002  Red Hat, Inc.</font>
00005 <font class="comment"> * Copyright (c) 1991-1993 The Regents of the University of California.</font>
00006 <font class="comment"> * Copyright (c) 1994 Sun Microsystems, Inc.</font>
00007 <font class="comment"> * </font>
00008 <font class="comment"> * Hash table implementation based on generic/tclHash.c from the Tcl</font>
00009 <font class="comment"> * source code. The original Tcl license applies to portions of the</font>
00010 <font class="comment"> * code from tclHash.c; the Tcl license follows this standad D-BUS</font>
00011 <font class="comment"> * license information.</font>
00012 <font class="comment"> *</font>
00013 <font class="comment"> * Licensed under the Academic Free License version 2.0</font>
00014 <font class="comment"> * </font>
00015 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font>
00016 <font class="comment"> * it under the terms of the GNU General Public License as published by</font>
00017 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font>
00018 <font class="comment"> * (at your option) any later version.</font>
00019 <font class="comment"> *</font>
00020 <font class="comment"> * This program is distributed in the hope that it will be useful,</font>
00021 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font>
00022 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</font>
00023 <font class="comment"> * GNU General Public License for more details.</font>
00024 <font class="comment"> * </font>
00025 <font class="comment"> * You should have received a copy of the GNU General Public License</font>
00026 <font class="comment"> * along with this program; if not, write to the Free Software</font>
00027 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</font>
00028 <font class="comment"> *</font>
00029 <font class="comment"> */</font>
00030 <font class="comment">/* </font>
00031 <font class="comment"> * The following copyright applies to code from the Tcl distribution.</font>
00032 <font class="comment"> *</font>
00033 <font class="comment"> * Copyright (c) 1991-1993 The Regents of the University of California.</font>
00034 <font class="comment"> * Copyright (c) 1994 Sun Microsystems, Inc.</font>
00035 <font class="comment"> *</font>
00036 <font class="comment"> * This software is copyrighted by the Regents of the University of</font>
00037 <font class="comment"> * California, Sun Microsystems, Inc., Scriptics Corporation, and</font>
00038 <font class="comment"> * other parties.  The following terms apply to all files associated</font>
00039 <font class="comment"> * with the software unless explicitly disclaimed in individual files.</font>
00040 <font class="comment"> * </font>
00041 <font class="comment"> * The authors hereby grant permission to use, copy, modify,</font>
00042 <font class="comment"> * distribute, and license this software and its documentation for any</font>
00043 <font class="comment"> * purpose, provided that existing copyright notices are retained in</font>
00044 <font class="comment"> * all copies and that this notice is included verbatim in any</font>
00045 <font class="comment"> * distributions. No written agreement, license, or royalty fee is</font>
00046 <font class="comment"> * required for any of the authorized uses.  Modifications to this</font>
00047 <font class="comment"> * software may be copyrighted by their authors and need not follow</font>
00048 <font class="comment"> * the licensing terms described here, provided that the new terms are</font>
00049 <font class="comment"> * clearly indicated on the first page of each file where they apply.</font>
00050 <font class="comment"> * </font>
00051 <font class="comment"> * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY</font>
00052 <font class="comment"> * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL</font>
00053 <font class="comment"> * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,</font>
00054 <font class="comment"> * OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED</font>
00055 <font class="comment"> * OF THE POSSIBILITY OF SUCH DAMAGE.</font>
00056 <font class="comment"> * </font>
00057 <font class="comment"> * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,</font>
00058 <font class="comment"> * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF</font>
00059 <font class="comment"> * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND</font>
00060 <font class="comment"> * NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,</font>
00061 <font class="comment"> * AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE</font>
00062 <font class="comment"> * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.</font>
00063 <font class="comment"> * </font>
00064 <font class="comment"> * GOVERNMENT USE: If you are acquiring this software on behalf of the</font>
00065 <font class="comment"> * U.S. government, the Government shall have only "Restricted Rights"</font>
00066 <font class="comment"> * in the software and related documentation as defined in the Federal</font>
00067 <font class="comment"> * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you</font>
00068 <font class="comment"> * are acquiring the software on behalf of the Department of Defense,</font>
00069 <font class="comment"> * the software shall be classified as "Commercial Computer Software"</font>
00070 <font class="comment"> * and the Government shall have only "Restricted Rights" as defined</font>
00071 <font class="comment"> * in Clause 252.227-7013 (c) (1) of DFARs.  Notwithstanding the</font>
00072 <font class="comment"> * foregoing, the authors grant the U.S. Government and others acting</font>
00073 <font class="comment"> * in its behalf permission to use and distribute the software in</font>
00074 <font class="comment"> * accordance with the terms specified in this license.</font>
00075 <font class="comment"> */</font>
00076 
00077 <font class="preprocessor">#include "dbus-hash.h"</font>
00078 <font class="preprocessor">#include "dbus-internals.h"</font>
00079 <font class="preprocessor">#include "dbus-mempool.h"</font>
00080 
<a name="l00103"></a><a class="code" href="group__DBusHashTableInternals.html#a13">00103</a> <font class="preprocessor">#define REBUILD_MULTIPLIER  3</font>
00104 <font class="preprocessor"></font>
<a name="l00121"></a><a class="code" href="group__DBusHashTableInternals.html#a14">00121</a> <font class="preprocessor">#define RANDOM_INDEX(table, i) \</font>
00122 <font class="preprocessor">    (((((long) (i))*1103515245) &gt;&gt; (table)-&gt;down_shift) &amp; (table)-&gt;mask)</font>
00123 <font class="preprocessor"></font>
<a name="l00129"></a><a class="code" href="group__DBusHashTableInternals.html#a15">00129</a> <font class="preprocessor">#define DBUS_SMALL_HASH_TABLE 4</font>
00130 <font class="preprocessor"></font>
<a name="l00134"></a><a class="code" href="group__DBusHashTableInternals.html#a0">00134</a> <font class="keyword">typedef</font> <font class="keyword">struct </font><a class="code" href="structDBusHashEntry.html">DBusHashEntry</a> DBusHashEntry;
00135 
<a name="l00142"></a><a class="code" href="structDBusHashEntry.html">00142</a> <font class="keyword">struct </font>DBusHashEntry
00143 {
<a name="l00144"></a><a class="code" href="structDBusHashEntry.html#m0">00144</a>   DBusHashEntry *<a class="code" href="structDBusHashEntry.html#m0">next</a>;    
<a name="l00148"></a><a class="code" href="structDBusHashEntry.html#m1">00148</a>   <font class="keywordtype">void</font> *<a class="code" href="structDBusHashEntry.html#m1">key</a>;              
<a name="l00149"></a><a class="code" href="structDBusHashEntry.html#m2">00149</a>   <font class="keywordtype">void</font> *<a class="code" href="structDBusHashEntry.html#m2">value</a>;            
00150 };
00151 
<a name="l00155"></a><a class="code" href="group__DBusHashTableInternals.html#a1">00155</a> <font class="keyword">typedef</font> DBusHashEntry* (* DBusFindEntryFunction) (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>        *table,
00156                                                   <font class="keywordtype">void</font>                 *key,
00157                                                   dbus_bool_t           create_if_not_found,
00158                                                   DBusHashEntry      ***bucket,
00159                                                   DBusPreallocatedHash *preallocated);
00160 
<a name="l00167"></a><a class="code" href="structDBusHashTable.html">00167</a> <font class="keyword">struct </font><a class="code" href="structDBusHashTable.html">DBusHashTable</a> {
<a name="l00168"></a><a class="code" href="structDBusHashTable.html#m0">00168</a>   <font class="keywordtype">int</font> <a class="code" href="structDBusHashTable.html#m0">refcount</a>;                       
<a name="l00170"></a><a class="code" href="structDBusHashTable.html#m1">00170</a>   DBusHashEntry **<a class="code" href="structDBusHashTable.html#m1">buckets</a>;            
00174   DBusHashEntry *<a class="code" href="structDBusHashTable.html#m2">static_buckets</a>[DBUS_SMALL_HASH_TABLE];
<a name="l00178"></a><a class="code" href="structDBusHashTable.html#m3">00178</a>   <font class="keywordtype">int</font> <a class="code" href="structDBusHashTable.html#m3">n_buckets</a>;                       
<a name="l00181"></a><a class="code" href="structDBusHashTable.html#m4">00181</a>   <font class="keywordtype">int</font> <a class="code" href="structDBusHashTable.html#m4">n_entries</a>;                       
<a name="l00184"></a><a class="code" href="structDBusHashTable.html#m5">00184</a>   <font class="keywordtype">int</font> <a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a>;                 
<a name="l00187"></a><a class="code" href="structDBusHashTable.html#m6">00187</a>   <font class="keywordtype">int</font> <a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a>;                 
<a name="l00190"></a><a class="code" href="structDBusHashTable.html#m7">00190</a>   <font class="keywordtype">int</font> <a class="code" href="structDBusHashTable.html#m7">down_shift</a>;                      
<a name="l00194"></a><a class="code" href="structDBusHashTable.html#m8">00194</a>   <font class="keywordtype">int</font> <a class="code" href="structDBusHashTable.html#m8">mask</a>;                            
<a name="l00197"></a><a class="code" href="structDBusHashTable.html#m9">00197</a>   DBusHashType <a class="code" href="structDBusHashTable.html#m9">key_type</a>;               
<a name="l00200"></a><a class="code" href="structDBusHashTable.html#m10">00200</a>   DBusFindEntryFunction <a class="code" href="structDBusHashTable.html#m10">find_function</a>; 
<a name="l00202"></a><a class="code" href="structDBusHashTable.html#m11">00202</a>   DBusFreeFunction <a class="code" href="structDBusHashTable.html#m11">free_key_function</a>;   
<a name="l00203"></a><a class="code" href="structDBusHashTable.html#m12">00203</a>   DBusFreeFunction <a class="code" href="structDBusHashTable.html#m12">free_value_function</a>; 
<a name="l00205"></a><a class="code" href="structDBusHashTable.html#m13">00205</a>   <a class="code" href="structDBusMemPool.html">DBusMemPool</a> *<a class="code" href="structDBusHashTable.html#m13">entry_pool</a>;              
00206 };
00207 
<a name="l00211"></a><a class="code" href="structDBusRealHashIter.html">00211</a> <font class="keyword">typedef</font> <font class="keyword">struct</font>
00212 <font class="keyword"></font>{
<a name="l00213"></a><a class="code" href="structDBusRealHashIter.html#m0">00213</a>   <a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table;     
<a name="l00214"></a><a class="code" href="structDBusRealHashIter.html#m1">00214</a>   DBusHashEntry **bucket;   
<a name="l00218"></a><a class="code" href="structDBusRealHashIter.html#m2">00218</a>   DBusHashEntry *entry;      
<a name="l00219"></a><a class="code" href="structDBusRealHashIter.html#m3">00219</a>   DBusHashEntry *next_entry; 
<a name="l00220"></a><a class="code" href="structDBusRealHashIter.html#m4">00220</a>   <font class="keywordtype">int</font> next_bucket;           
<a name="l00221"></a><a class="code" href="structDBusRealHashIter.html#m5">00221</a>   <font class="keywordtype">int</font> n_entries_on_init;     
00222 } <a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>;
00223 
00224 <font class="keyword">static</font> DBusHashEntry* find_direct_function      (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>          *table,
00225                                                  <font class="keywordtype">void</font>                   *key,
00226                                                  dbus_bool_t             create_if_not_found,
00227                                                  DBusHashEntry        ***bucket,
00228                                                  DBusPreallocatedHash   *preallocated);
00229 <font class="keyword">static</font> DBusHashEntry* find_string_function      (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>          *table,
00230                                                  <font class="keywordtype">void</font>                   *key,
00231                                                  dbus_bool_t             create_if_not_found,
00232                                                  DBusHashEntry        ***bucket,
00233                                                  DBusPreallocatedHash   *preallocated);
00234 <font class="keyword">static</font> DBusHashEntry* find_two_strings_function (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>          *table,
00235                                                  <font class="keywordtype">void</font>                   *key,
00236                                                  dbus_bool_t             create_if_not_found,
00237                                                  DBusHashEntry        ***bucket,
00238                                                  DBusPreallocatedHash   *preallocated);
00239 <font class="keyword">static</font> <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font>   string_hash               (<font class="keyword">const</font> <font class="keywordtype">char</font>             *str);
00240 <font class="keyword">static</font> <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font>   two_strings_hash          (<font class="keyword">const</font> <font class="keywordtype">char</font>             *str);
00241 <font class="keyword">static</font> <font class="keywordtype">void</font>           rebuild_table             (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>          *table);
00242 <font class="keyword">static</font> DBusHashEntry* alloc_entry               (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>          *table);
00243 <font class="keyword">static</font> <font class="keywordtype">void</font>           remove_entry              (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>          *table,
00244                                                  DBusHashEntry         **bucket,
00245                                                  DBusHashEntry          *entry);
00246 <font class="keyword">static</font> <font class="keywordtype">void</font>           free_entry                (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>          *table,
00247                                                  DBusHashEntry          *entry);
00248 <font class="keyword">static</font> <font class="keywordtype">void</font>           free_entry_data           (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>          *table,
00249                                                  DBusHashEntry          *entry);
00250 
00251 
00287 <a class="code" href="structDBusHashTable.html">DBusHashTable</a>*
<a name="l00288"></a><a class="code" href="group__DBusHashTable.html#a1">00288</a> _dbus_hash_table_new (DBusHashType     type,
00289                       DBusFreeFunction key_free_function,
00290                       DBusFreeFunction value_free_function)
00291 {
00292   <a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table;
00293   <a class="code" href="structDBusMemPool.html">DBusMemPool</a> *entry_pool;
00294   
00295   table = dbus_new0 (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>, 1);
00296   <font class="keywordflow">if</font> (table == NULL)
00297     <font class="keywordflow">return</font> NULL;
00298 
00299   entry_pool = _dbus_mem_pool_new (<font class="keyword">sizeof</font> (DBusHashEntry), TRUE);
00300   <font class="keywordflow">if</font> (entry_pool == NULL)
00301     {
00302       dbus_free (table);
00303       <font class="keywordflow">return</font> NULL;
00304     }
00305   
00306   table-&gt;<a class="code" href="structDBusHashTable.html#m0">refcount</a> = 1;
00307   table-&gt;<a class="code" href="structDBusHashTable.html#m13">entry_pool</a> = entry_pool;
00308   
00309   _dbus_assert (DBUS_SMALL_HASH_TABLE == _DBUS_N_ELEMENTS (table-&gt;<a class="code" href="structDBusHashTable.html#m2">static_buckets</a>));
00310   
00311   table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a> = table-&gt;<a class="code" href="structDBusHashTable.html#m2">static_buckets</a>;  
00312   table-&gt;<a class="code" href="structDBusHashTable.html#m3">n_buckets</a> = DBUS_SMALL_HASH_TABLE;
00313   table-&gt;<a class="code" href="structDBusHashTable.html#m4">n_entries</a> = 0;
00314   table-&gt;<a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a> = DBUS_SMALL_HASH_TABLE * REBUILD_MULTIPLIER;
00315   table-&gt;<a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a> = 0;
00316   table-&gt;<a class="code" href="structDBusHashTable.html#m7">down_shift</a> = 28;
00317   table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a> = 3;
00318   table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> = type;
00319 
00320   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a> &lt; table-&gt;<a class="code" href="structDBusHashTable.html#m3">n_buckets</a>);
00321   
00322   <font class="keywordflow">switch</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a>)
00323     {
00324     <font class="keywordflow">case</font> DBUS_HASH_INT:
00325     <font class="keywordflow">case</font> DBUS_HASH_POINTER:
00326     <font class="keywordflow">case</font> DBUS_HASH_ULONG:
00327       table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a> = find_direct_function;
00328       <font class="keywordflow">break</font>;
00329     <font class="keywordflow">case</font> DBUS_HASH_STRING:
00330       table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a> = find_string_function;
00331       <font class="keywordflow">break</font>;
00332     <font class="keywordflow">case</font> DBUS_HASH_TWO_STRINGS:
00333       table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a> = find_two_strings_function;
00334       <font class="keywordflow">break</font>;
00335     <font class="keywordflow">default</font>:
00336       _dbus_assert_not_reached (<font class="stringliteral">"Unknown hash table type"</font>);
00337       <font class="keywordflow">break</font>;
00338     }
00339 
00340   table-&gt;<a class="code" href="structDBusHashTable.html#m11">free_key_function</a> = key_free_function;
00341   table-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a> = value_free_function;
00342 
00343   <font class="keywordflow">return</font> table;
00344 }
00345 
00346 
00353 <a class="code" href="structDBusHashTable.html">DBusHashTable</a> *
<a name="l00354"></a><a class="code" href="group__DBusHashTable.html#a2">00354</a> _dbus_hash_table_ref (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table)
00355 {
00356   table-&gt;<a class="code" href="structDBusHashTable.html#m0">refcount</a> += 1;
00357   
00358   <font class="keywordflow">return</font> table;
00359 }
00360 
00367 <font class="keywordtype">void</font>
<a name="l00368"></a><a class="code" href="group__DBusHashTable.html#a3">00368</a> _dbus_hash_table_unref (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table)
00369 {
00370   table-&gt;<a class="code" href="structDBusHashTable.html#m0">refcount</a> -= 1;
00371 
00372   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m0">refcount</a> == 0)
00373     {
00374 <font class="preprocessor">#if 0</font>
00375 <font class="preprocessor"></font>      DBusHashEntry *entry;
00376       DBusHashEntry *next;
00377       <font class="keywordtype">int</font> i;
00378 
00379       <font class="comment">/* Free the entries in the table. */</font>
00380       <font class="keywordflow">for</font> (i = 0; i &lt; table-&gt;<a class="code" href="structDBusHashTable.html#m3">n_buckets</a>; i++)
00381         {
00382           entry = table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a>[i];
00383           <font class="keywordflow">while</font> (entry != NULL)
00384             {
00385               next = entry-&gt;<a class="code" href="structDBusHashEntry.html#m0">next</a>;
00386 
00387               free_entry (table, entry);
00388               
00389               entry = next;
00390             }
00391         }
00392 <font class="preprocessor">#else</font>
00393 <font class="preprocessor"></font>      DBusHashEntry *entry;
00394       <font class="keywordtype">int</font> i;
00395 
00396       <font class="comment">/* Free the entries in the table. */</font>
00397       <font class="keywordflow">for</font> (i = 0; i &lt; table-&gt;<a class="code" href="structDBusHashTable.html#m3">n_buckets</a>; i++)
00398         {
00399           entry = table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a>[i];
00400           <font class="keywordflow">while</font> (entry != NULL)
00401             {
00402               free_entry_data (table, entry);
00403               
00404               entry = entry-&gt;<a class="code" href="structDBusHashEntry.html#m0">next</a>;
00405             }
00406         }
00407       <font class="comment">/* We can do this very quickly with memory pools ;-) */</font>
00408       _dbus_mem_pool_free (table-&gt;<a class="code" href="structDBusHashTable.html#m13">entry_pool</a>);
00409 <font class="preprocessor">#endif</font>
00410 <font class="preprocessor"></font>      
00411       <font class="comment">/* Free the bucket array, if it was dynamically allocated. */</font>
00412       <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a> != table-&gt;<a class="code" href="structDBusHashTable.html#m2">static_buckets</a>)
00413         dbus_free (table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a>);
00414 
00415       dbus_free (table);
00416     }
00417 }
00418 
00419 <font class="keyword">static</font> DBusHashEntry*
00420 alloc_entry (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table)
00421 {
00422   DBusHashEntry *entry;
00423 
00424   entry = _dbus_mem_pool_alloc (table-&gt;<a class="code" href="structDBusHashTable.html#m13">entry_pool</a>);
00425   
00426   <font class="keywordflow">return</font> entry;
00427 }
00428 
00429 <font class="keyword">static</font> <font class="keywordtype">void</font>
00430 free_entry_data (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>  *table,
00431                  DBusHashEntry  *entry)
00432 {
00433   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m11">free_key_function</a>)
00434     (* table-&gt;<a class="code" href="structDBusHashTable.html#m11">free_key_function</a>) (entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>);
00435   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a>)
00436     (* table-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>);
00437 }
00438 
00439 <font class="keyword">static</font> <font class="keywordtype">void</font>
00440 free_entry (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>  *table,
00441             DBusHashEntry  *entry)
00442 {
00443   free_entry_data (table, entry);
00444   _dbus_mem_pool_dealloc (table-&gt;<a class="code" href="structDBusHashTable.html#m13">entry_pool</a>, entry);
00445 }
00446 
00447 <font class="keyword">static</font> <font class="keywordtype">void</font>
00448 remove_entry (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>  *table,
00449               DBusHashEntry **bucket,
00450               DBusHashEntry  *entry)
00451 {
00452   _dbus_assert (table != NULL);
00453   _dbus_assert (bucket != NULL);
00454   _dbus_assert (*bucket != NULL);  
00455   _dbus_assert (entry != NULL);
00456   
00457   <font class="keywordflow">if</font> (*bucket == entry)
00458     *bucket = entry-&gt;<a class="code" href="structDBusHashEntry.html#m0">next</a>;
00459   <font class="keywordflow">else</font>
00460     {
00461       DBusHashEntry *prev;
00462       prev = *bucket;
00463 
00464       <font class="keywordflow">while</font> (prev-&gt;<a class="code" href="structDBusHashEntry.html#m0">next</a> != entry)
00465         prev = prev-&gt;<a class="code" href="structDBusHashEntry.html#m0">next</a>;      
00466       
00467       _dbus_assert (prev != NULL);
00468 
00469       prev-&gt;<a class="code" href="structDBusHashEntry.html#m0">next</a> = entry-&gt;<a class="code" href="structDBusHashEntry.html#m0">next</a>;
00470     }
00471   
00472   table-&gt;<a class="code" href="structDBusHashTable.html#m4">n_entries</a> -= 1;
00473   free_entry (table, entry);
00474 }
00475 
00507 <font class="keywordtype">void</font>
<a name="l00508"></a><a class="code" href="group__DBusHashTable.html#a4">00508</a> _dbus_hash_iter_init (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
00509                       <a class="code" href="structDBusHashIter.html">DBusHashIter</a>  *iter)
00510 {
00511   <a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a> *real;
00512   
00513   _dbus_assert (<font class="keyword">sizeof</font> (<a class="code" href="structDBusHashIter.html">DBusHashIter</a>) == <font class="keyword">sizeof</font> (<a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>));
00514   
00515   real = (<a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>*) iter;
00516 
00517   real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a> = table;
00518   real-&gt;<a class="code" href="structDBusRealHashIter.html#m1">bucket</a> = NULL;
00519   real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a> = NULL;
00520   real-&gt;<a class="code" href="structDBusRealHashIter.html#m3">next_entry</a> = NULL;
00521   real-&gt;<a class="code" href="structDBusRealHashIter.html#m4">next_bucket</a> = 0;
00522   real-&gt;<a class="code" href="structDBusRealHashIter.html#m5">n_entries_on_init</a> = table-&gt;<a class="code" href="structDBusHashTable.html#m4">n_entries</a>;
00523 }
00524 
00533 dbus_bool_t
<a name="l00534"></a><a class="code" href="group__DBusHashTable.html#a5">00534</a> _dbus_hash_iter_next (<a class="code" href="structDBusHashIter.html">DBusHashIter</a>  *iter)
00535 {
00536   <a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a> *real;
00537   
00538   _dbus_assert (<font class="keyword">sizeof</font> (<a class="code" href="structDBusHashIter.html">DBusHashIter</a>) == <font class="keyword">sizeof</font> (<a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>));
00539   
00540   real = (<a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>*) iter;
00541 
00542   <font class="comment">/* if this assertion failed someone probably added hash entries</font>
00543 <font class="comment">   * during iteration, which is bad.</font>
00544 <font class="comment">   */</font>
00545   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m5">n_entries_on_init</a> &gt;= real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a>-&gt;<a class="code" href="structDBusHashTable.html#m4">n_entries</a>);
00546   
00547   <font class="comment">/* Remember that real-&gt;entry may have been deleted */</font>
00548   
00549   <font class="keywordflow">while</font> (real-&gt;<a class="code" href="structDBusRealHashIter.html#m3">next_entry</a> == NULL)
00550     {
00551       <font class="keywordflow">if</font> (real-&gt;<a class="code" href="structDBusRealHashIter.html#m4">next_bucket</a> &gt;= real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a>-&gt;<a class="code" href="structDBusHashTable.html#m3">n_buckets</a>)
00552         {
00553           <font class="comment">/* invalidate iter and return false */</font>
00554           real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a> = NULL;
00555           real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a> = NULL;
00556           real-&gt;<a class="code" href="structDBusRealHashIter.html#m1">bucket</a> = NULL;
00557           <font class="keywordflow">return</font> FALSE;
00558         }
00559 
00560       real-&gt;<a class="code" href="structDBusRealHashIter.html#m1">bucket</a> = &amp;(real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a>-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a>[real-&gt;<a class="code" href="structDBusRealHashIter.html#m4">next_bucket</a>]);
00561       real-&gt;<a class="code" href="structDBusRealHashIter.html#m3">next_entry</a> = *(real-&gt;<a class="code" href="structDBusRealHashIter.html#m1">bucket</a>);
00562       real-&gt;<a class="code" href="structDBusRealHashIter.html#m4">next_bucket</a> += 1;
00563     }
00564 
00565   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m3">next_entry</a> != NULL);
00566   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m1">bucket</a> != NULL);
00567   
00568   real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a> = real-&gt;<a class="code" href="structDBusRealHashIter.html#m3">next_entry</a>;
00569   real-&gt;<a class="code" href="structDBusRealHashIter.html#m3">next_entry</a> = real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a>-&gt;<a class="code" href="structDBusHashEntry.html#m0">next</a>;
00570   
00571   <font class="keywordflow">return</font> TRUE;
00572 }
00573 
00582 <font class="keywordtype">void</font>
<a name="l00583"></a><a class="code" href="group__DBusHashTable.html#a6">00583</a> _dbus_hash_iter_remove_entry (<a class="code" href="structDBusHashIter.html">DBusHashIter</a> *iter)
00584 {
00585   <a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a> *real;
00586 
00587   real = (<a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>*) iter;
00588 
00589   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL);
00590   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a> != NULL);
00591   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m1">bucket</a> != NULL);
00592   
00593   remove_entry (real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a>, real-&gt;<a class="code" href="structDBusRealHashIter.html#m1">bucket</a>, real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a>);
00594 
00595   real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a> = NULL; <font class="comment">/* make it crash if you try to use this entry */</font>
00596 }
00597 
00603 <font class="keywordtype">void</font>*
<a name="l00604"></a><a class="code" href="group__DBusHashTable.html#a7">00604</a> _dbus_hash_iter_get_value (<a class="code" href="structDBusHashIter.html">DBusHashIter</a> *iter)
00605 {
00606   <a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a> *real;
00607 
00608   real = (<a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>*) iter;
00609 
00610   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL);
00611   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a> != NULL);
00612 
00613   <font class="keywordflow">return</font> real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a>-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>;
00614 }
00615 
00626 <font class="keywordtype">void</font>
<a name="l00627"></a><a class="code" href="group__DBusHashTable.html#a8">00627</a> _dbus_hash_iter_set_value (<a class="code" href="structDBusHashIter.html">DBusHashIter</a> *iter,
00628                            <font class="keywordtype">void</font>         *value)
00629 {
00630   <a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a> *real;
00631 
00632   real = (<a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>*) iter;
00633 
00634   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL);
00635   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a> != NULL);
00636 
00637   <font class="keywordflow">if</font> (real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a>-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a> &amp;&amp; value != real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a>-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>)    
00638     (* real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a>-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a>-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>);
00639   
00640   real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a>-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a> = value;
00641 }
00642 
00649 <font class="keywordtype">int</font>
<a name="l00650"></a><a class="code" href="group__DBusHashTable.html#a9">00650</a> _dbus_hash_iter_get_int_key (<a class="code" href="structDBusHashIter.html">DBusHashIter</a> *iter)
00651 {
00652   <a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a> *real;
00653 
00654   real = (<a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>*) iter;
00655 
00656   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL);
00657   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a> != NULL);
00658 
00659   <font class="keywordflow">return</font> _DBUS_POINTER_TO_INT (real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a>-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>);
00660 }
00661 
00668 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>
<a name="l00669"></a><a class="code" href="group__DBusHashTable.html#a10">00669</a> _dbus_hash_iter_get_ulong_key (<a class="code" href="structDBusHashIter.html">DBusHashIter</a> *iter)
00670 {
00671   <a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a> *real;
00672 
00673   real = (<a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>*) iter;
00674 
00675   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL);
00676   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a> != NULL);
00677 
00678   <font class="keywordflow">return</font> (<font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>) real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a>-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>;
00679 }
00680 
00686 <font class="keyword">const</font> <font class="keywordtype">char</font>*
<a name="l00687"></a><a class="code" href="group__DBusHashTable.html#a11">00687</a> _dbus_hash_iter_get_string_key (<a class="code" href="structDBusHashIter.html">DBusHashIter</a> *iter)
00688 {
00689   <a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a> *real;
00690 
00691   real = (<a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>*) iter;
00692 
00693   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL);
00694   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a> != NULL);
00695 
00696   <font class="keywordflow">return</font> real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a>-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>;
00697 }
00698 
00704 <font class="keyword">const</font> <font class="keywordtype">char</font>*
<a name="l00705"></a><a class="code" href="group__DBusHashTable.html#a12">00705</a> _dbus_hash_iter_get_two_strings_key (<a class="code" href="structDBusHashIter.html">DBusHashIter</a> *iter)
00706 {
00707   <a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a> *real;
00708 
00709   real = (<a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>*) iter;
00710 
00711   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL);
00712   _dbus_assert (real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a> != NULL);
00713 
00714   <font class="keywordflow">return</font> real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a>-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>;
00715 }
00716 
00748 dbus_bool_t
<a name="l00749"></a><a class="code" href="group__DBusHashTable.html#a13">00749</a> _dbus_hash_iter_lookup (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
00750                         <font class="keywordtype">void</font>          *key,
00751                         dbus_bool_t    create_if_not_found,
00752                         <a class="code" href="structDBusHashIter.html">DBusHashIter</a>  *iter)
00753 {
00754   <a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a> *real;
00755   DBusHashEntry *entry;
00756   DBusHashEntry **bucket;
00757   
00758   _dbus_assert (<font class="keyword">sizeof</font> (<a class="code" href="structDBusHashIter.html">DBusHashIter</a>) == <font class="keyword">sizeof</font> (<a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>));
00759   
00760   real = (<a class="code" href="structDBusRealHashIter.html">DBusRealHashIter</a>*) iter;
00761 
00762   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, key, create_if_not_found, &amp;bucket, NULL);
00763 
00764   <font class="keywordflow">if</font> (entry == NULL)
00765     <font class="keywordflow">return</font> FALSE;
00766   
00767   real-&gt;<a class="code" href="structDBusRealHashIter.html#m0">table</a> = table;
00768   real-&gt;<a class="code" href="structDBusRealHashIter.html#m1">bucket</a> = bucket;
00769   real-&gt;<a class="code" href="structDBusRealHashIter.html#m2">entry</a> = entry;
00770   real-&gt;<a class="code" href="structDBusRealHashIter.html#m3">next_entry</a> = entry-&gt;<a class="code" href="structDBusHashEntry.html#m0">next</a>;
00771   real-&gt;<a class="code" href="structDBusRealHashIter.html#m4">next_bucket</a> = (bucket - table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a>) + 1;
00772   real-&gt;<a class="code" href="structDBusRealHashIter.html#m5">n_entries_on_init</a> = table-&gt;<a class="code" href="structDBusHashTable.html#m4">n_entries</a>; 
00773 
00774   _dbus_assert (&amp;(table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a>[real-&gt;<a class="code" href="structDBusRealHashIter.html#m4">next_bucket</a>-1]) == real-&gt;<a class="code" href="structDBusRealHashIter.html#m1">bucket</a>);
00775   
00776   <font class="keywordflow">return</font> TRUE;
00777 }
00778 
00779 <font class="keyword">static</font> <font class="keywordtype">void</font>
00780 add_allocated_entry (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>   *table,
00781                      DBusHashEntry   *entry,
00782                      <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font>     idx,
00783                      <font class="keywordtype">void</font>            *key,
00784                      DBusHashEntry ***bucket)
00785 {
00786   DBusHashEntry **b;  
00787   
00788   entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a> = key;
00789   
00790   b = &amp;(table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a>[idx]);
00791   entry-&gt;<a class="code" href="structDBusHashEntry.html#m0">next</a> = *b;
00792   *b = entry;
00793 
00794   <font class="keywordflow">if</font> (bucket)
00795     *bucket = b;
00796   
00797   table-&gt;<a class="code" href="structDBusHashTable.html#m4">n_entries</a> += 1;
00798 
00799   <font class="comment">/* note we ONLY rebuild when ADDING - because you can iterate over a</font>
00800 <font class="comment">   * table and remove entries safely.</font>
00801 <font class="comment">   */</font>
00802   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m4">n_entries</a> &gt;= table-&gt;<a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a> ||
00803       table-&gt;<a class="code" href="structDBusHashTable.html#m4">n_entries</a> &lt; table-&gt;<a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a>)
00804     rebuild_table (table);
00805 }
00806 
00807 <font class="keyword">static</font> DBusHashEntry*
00808 add_entry (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>        *table, 
00809            <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font>          idx,
00810            <font class="keywordtype">void</font>                 *key,
00811            DBusHashEntry      ***bucket,
00812            DBusPreallocatedHash *preallocated)
00813 {
00814   DBusHashEntry  *entry;
00815 
00816   <font class="keywordflow">if</font> (preallocated == NULL)
00817     {
00818       entry = alloc_entry (table);
00819       <font class="keywordflow">if</font> (entry == NULL)
00820         {
00821           <font class="keywordflow">if</font> (bucket)
00822             *bucket = NULL;
00823           <font class="keywordflow">return</font> NULL;
00824         }
00825     }
00826   <font class="keywordflow">else</font>
00827     {
00828       entry = (DBusHashEntry*) preallocated;
00829     }
00830 
00831   add_allocated_entry (table, entry, idx, key, bucket);
00832 
00833   <font class="keywordflow">return</font> entry;
00834 }
00835 
00836 <font class="comment">/* This is g_str_hash from GLib which was</font>
00837 <font class="comment"> * extensively discussed/tested/profiled</font>
00838 <font class="comment"> */</font>
00839 <font class="keyword">static</font> <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font>
00840 string_hash (<font class="keyword">const</font> <font class="keywordtype">char</font> *str)
00841 {
00842   <font class="keyword">const</font> <font class="keywordtype">char</font> *p = str;
00843   <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> h = *p;
00844 
00845   <font class="keywordflow">if</font> (h)
00846     <font class="keywordflow">for</font> (p += 1; *p != <font class="charliteral">'\0'</font>; p++)
00847       h = (h &lt;&lt; 5) - h + *p;
00848 
00849   <font class="keywordflow">return</font> h;
00850 }
00851 
00852 <font class="comment">/* This hashes a memory block with two nul-terminated strings</font>
00853 <font class="comment"> * in it, used in dbus-object-registry.c at the moment.</font>
00854 <font class="comment"> */</font>
00855 <font class="keyword">static</font> <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font>
00856 two_strings_hash (<font class="keyword">const</font> <font class="keywordtype">char</font> *str)
00857 {
00858   <font class="keyword">const</font> <font class="keywordtype">char</font> *p = str;
00859   <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> h = *p;
00860 
00861   <font class="keywordflow">if</font> (h)
00862     <font class="keywordflow">for</font> (p += 1; *p != <font class="charliteral">'\0'</font>; p++)
00863       h = (h &lt;&lt; 5) - h + *p;
00864 
00865   <font class="keywordflow">for</font> (p += 1; *p != <font class="charliteral">'\0'</font>; p++)
00866     h = (h &lt;&lt; 5) - h + *p;
00867   
00868   <font class="keywordflow">return</font> h;
00869 }
00870 
<a name="l00872"></a><a class="code" href="group__DBusHashTable.html#a0">00872</a> <font class="keyword">typedef</font> int (* KeyCompareFunc) (<font class="keyword">const</font> <font class="keywordtype">void</font> *key_a, <font class="keyword">const</font> <font class="keywordtype">void</font> *key_b);
00873 
00874 <font class="keyword">static</font> DBusHashEntry*
00875 find_generic_function (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>        *table,
00876                        <font class="keywordtype">void</font>                 *key,
00877                        <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font>          idx,
00878                        KeyCompareFunc        compare_func,
00879                        dbus_bool_t           create_if_not_found,
00880                        DBusHashEntry      ***bucket,
00881                        DBusPreallocatedHash *preallocated)
00882 {
00883   DBusHashEntry *entry;
00884 
00885   <font class="keywordflow">if</font> (bucket)
00886     *bucket = NULL;
00887 
00888   <font class="comment">/* Search all of the entries in this bucket. */</font>
00889   entry = table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a>[idx];
00890   <font class="keywordflow">while</font> (entry != NULL)
00891     {
00892       <font class="keywordflow">if</font> ((compare_func == NULL &amp;&amp; key == entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>) ||
00893           (compare_func != NULL &amp;&amp; (* compare_func) (key, entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>) == 0))
00894         {
00895           <font class="keywordflow">if</font> (bucket)
00896             *bucket = &amp;(table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a>[idx]);
00897 
00898           <font class="keywordflow">if</font> (preallocated)
00899             _dbus_hash_table_free_preallocated_entry (table, preallocated);
00900           
00901           <font class="keywordflow">return</font> entry;
00902         }
00903       
00904       entry = entry-&gt;<a class="code" href="structDBusHashEntry.html#m0">next</a>;
00905     }
00906 
00907   <font class="keywordflow">if</font> (create_if_not_found)
00908     entry = add_entry (table, idx, key, bucket, preallocated);
00909   <font class="keywordflow">else</font> <font class="keywordflow">if</font> (preallocated)
00910     _dbus_hash_table_free_preallocated_entry (table, preallocated);
00911   
00912   <font class="keywordflow">return</font> entry;
00913 }
00914 
00915 <font class="keyword">static</font> DBusHashEntry*
00916 find_string_function (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>        *table,
00917                       <font class="keywordtype">void</font>                 *key,
00918                       dbus_bool_t           create_if_not_found,
00919                       DBusHashEntry      ***bucket,
00920                       DBusPreallocatedHash *preallocated)
00921 {
00922   <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> idx;
00923   
00924   idx = string_hash (key) &amp; table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a>;
00925 
00926   <font class="keywordflow">return</font> find_generic_function (table, key, idx,
00927                                 (KeyCompareFunc) strcmp, create_if_not_found, bucket,
00928                                 preallocated);
00929 }
00930 
00931 <font class="keyword">static</font> <font class="keywordtype">int</font>
00932 two_strings_cmp (<font class="keyword">const</font> <font class="keywordtype">char</font> *a,
00933                  <font class="keyword">const</font> <font class="keywordtype">char</font> *b)
00934 {
00935   size_t len_a;
00936   size_t len_b;
00937   <font class="keywordtype">int</font> res;
00938   
00939   res = strcmp (a, b);
00940   <font class="keywordflow">if</font> (res != 0)
00941     <font class="keywordflow">return</font> res;
00942 
00943   len_a = strlen (a);
00944   len_b = strlen (b);
00945 
00946   <font class="keywordflow">return</font> strcmp (a + len_a + 1, b + len_b + 1);
00947 }
00948 
00949 <font class="keyword">static</font> DBusHashEntry*
00950 find_two_strings_function (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>        *table,
00951                            <font class="keywordtype">void</font>                 *key,
00952                            dbus_bool_t           create_if_not_found,
00953                            DBusHashEntry      ***bucket,
00954                            DBusPreallocatedHash *preallocated)
00955 {
00956   <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> idx;
00957   
00958   idx = two_strings_hash (key) &amp; table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a>;
00959 
00960   <font class="keywordflow">return</font> find_generic_function (table, key, idx,
00961                                 (KeyCompareFunc) two_strings_cmp, create_if_not_found, bucket,
00962                                 preallocated);
00963 }
00964 
00965 <font class="keyword">static</font> DBusHashEntry*
00966 find_direct_function (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>        *table,
00967                       <font class="keywordtype">void</font>                 *key,
00968                       dbus_bool_t           create_if_not_found,
00969                       DBusHashEntry      ***bucket,
00970                       DBusPreallocatedHash *preallocated)
00971 {
00972   <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> idx;
00973   
00974   idx = RANDOM_INDEX (table, key) &amp; table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a>;
00975 
00976 
00977   <font class="keywordflow">return</font> find_generic_function (table, key, idx,
00978                                 NULL, create_if_not_found, bucket,
00979                                 preallocated);
00980 }
00981 
00982 <font class="keyword">static</font> <font class="keywordtype">void</font>
00983 rebuild_table (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table)
00984 {
00985   <font class="keywordtype">int</font> old_size;
00986   <font class="keywordtype">int</font> new_buckets;
00987   DBusHashEntry **old_buckets;
00988   DBusHashEntry **old_chain;
00989   DBusHashEntry *entry;
00990   dbus_bool_t growing;
00991   
00992   <font class="comment">/*</font>
00993 <font class="comment">   * Allocate and initialize the new bucket array, and set up</font>
00994 <font class="comment">   * hashing constants for new array size.</font>
00995 <font class="comment">   */</font>
00996 
00997   growing = table-&gt;<a class="code" href="structDBusHashTable.html#m4">n_entries</a> &gt;= table-&gt;<a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a>;
00998   
00999   old_size = table-&gt;<a class="code" href="structDBusHashTable.html#m3">n_buckets</a>;
01000   old_buckets = table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a>;
01001 
01002   <font class="keywordflow">if</font> (growing)
01003     {
01004       <font class="comment">/* overflow paranoia */</font>
01005       <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m3">n_buckets</a> &lt; _DBUS_INT_MAX / 4 &amp;&amp;
01006           table-&gt;<a class="code" href="structDBusHashTable.html#m7">down_shift</a> &gt;= 0)
01007         new_buckets = table-&gt;<a class="code" href="structDBusHashTable.html#m3">n_buckets</a> * 4;
01008       <font class="keywordflow">else</font>
01009         <font class="keywordflow">return</font>; <font class="comment">/* can't grow anymore */</font>
01010     }
01011   <font class="keywordflow">else</font>
01012     {
01013       new_buckets = table-&gt;<a class="code" href="structDBusHashTable.html#m3">n_buckets</a> / 4;
01014       <font class="keywordflow">if</font> (new_buckets &lt; DBUS_SMALL_HASH_TABLE)
01015         <font class="keywordflow">return</font>; <font class="comment">/* don't bother shrinking this far */</font>
01016     }
01017 
01018   table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a> = dbus_new0 (DBusHashEntry*, new_buckets);
01019   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a> == NULL)
01020     {
01021       <font class="comment">/* out of memory, yay - just don't reallocate, the table will</font>
01022 <font class="comment">       * still work, albeit more slowly.</font>
01023 <font class="comment">       */</font>
01024       table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a> = old_buckets;
01025       <font class="keywordflow">return</font>;
01026     }
01027 
01028   table-&gt;<a class="code" href="structDBusHashTable.html#m3">n_buckets</a> = new_buckets;
01029   
01030   <font class="keywordflow">if</font> (growing)
01031     {
01032       table-&gt;<a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a> = table-&gt;<a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a>;
01033       table-&gt;<a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a> *= 4;
01034       
01035       table-&gt;<a class="code" href="structDBusHashTable.html#m7">down_shift</a> -= 2;               <font class="comment">/* keep 2 more high bits */</font>
01036       table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a> = (table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a> &lt;&lt; 2) + 3; <font class="comment">/* keep 2 more high bits */</font>
01037     }
01038   <font class="keywordflow">else</font>
01039     {
01040       table-&gt;<a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a> = table-&gt;<a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a>;
01041       table-&gt;<a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a> /= 4;
01042 
01043       table-&gt;<a class="code" href="structDBusHashTable.html#m7">down_shift</a> += 2;         <font class="comment">/* keep 2 fewer high bits */</font>
01044       table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a> = table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a> &gt;&gt; 2; <font class="comment">/* keep 2 fewer high bits */</font>
01045     }
01046 
01047 <font class="preprocessor">#if 0</font>
01048 <font class="preprocessor"></font>  printf (<font class="stringliteral">"%s table to lo = %d hi = %d downshift = %d mask = 0x%x\n"</font>,
01049           growing ? <font class="stringliteral">"GROW"</font> : <font class="stringliteral">"SHRINK"</font>,
01050           table-&gt;<a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a>,
01051           table-&gt;<a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a>,
01052           table-&gt;<a class="code" href="structDBusHashTable.html#m7">down_shift</a>,
01053           table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a>);
01054 <font class="preprocessor">#endif</font>
01055 <font class="preprocessor"></font>  
01056   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a> &gt;= 0);
01057   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a> &gt; table-&gt;<a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a>);
01058   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a> != 0);
01059   <font class="comment">/* the mask is essentially the max index */</font>
01060   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a> &lt; table-&gt;<a class="code" href="structDBusHashTable.html#m3">n_buckets</a>);
01061   
01062   <font class="comment">/*</font>
01063 <font class="comment">   * Rehash all of the existing entries into the new bucket array.</font>
01064 <font class="comment">   */</font>
01065 
01066   <font class="keywordflow">for</font> (old_chain = old_buckets; old_size &gt; 0; old_size--, old_chain++)
01067     {
01068       <font class="keywordflow">for</font> (entry = *old_chain; entry != NULL; entry = *old_chain)
01069         {
01070           <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> idx;
01071           DBusHashEntry **bucket;
01072           
01073           *old_chain = entry-&gt;<a class="code" href="structDBusHashEntry.html#m0">next</a>;
01074           <font class="keywordflow">switch</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a>)
01075             {
01076             <font class="keywordflow">case</font> DBUS_HASH_STRING:
01077               idx = string_hash (entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>) &amp; table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a>;
01078               <font class="keywordflow">break</font>;
01079             <font class="keywordflow">case</font> DBUS_HASH_TWO_STRINGS:
01080               idx = two_strings_hash (entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>) &amp; table-&gt;<a class="code" href="structDBusHashTable.html#m8">mask</a>;
01081               <font class="keywordflow">break</font>;
01082             <font class="keywordflow">case</font> DBUS_HASH_INT:
01083             <font class="keywordflow">case</font> DBUS_HASH_ULONG:
01084             <font class="keywordflow">case</font> DBUS_HASH_POINTER:
01085               idx = RANDOM_INDEX (table, entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>);
01086               <font class="keywordflow">break</font>;
01087             <font class="keywordflow">default</font>:
01088               idx = 0;
01089               _dbus_assert_not_reached (<font class="stringliteral">"Unknown hash table type"</font>);
01090               <font class="keywordflow">break</font>;
01091             }
01092           
01093           bucket = &amp;(table-&gt;<a class="code" href="structDBusHashTable.html#m1">buckets</a>[idx]);
01094           entry-&gt;<a class="code" href="structDBusHashEntry.html#m0">next</a> = *bucket;
01095           *bucket = entry;
01096         }
01097     }
01098   
01099   <font class="comment">/* Free the old bucket array, if it was dynamically allocated. */</font>
01100 
01101   <font class="keywordflow">if</font> (old_buckets != table-&gt;<a class="code" href="structDBusHashTable.html#m2">static_buckets</a>)
01102     dbus_free (old_buckets);
01103 }
01104 
01114 <font class="keywordtype">void</font>*
<a name="l01115"></a><a class="code" href="group__DBusHashTable.html#a18">01115</a> _dbus_hash_table_lookup_string (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01116                                 <font class="keyword">const</font> <font class="keywordtype">char</font>    *key)
01117 {
01118   DBusHashEntry *entry;
01119 
01120   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_STRING);
01121   
01122   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, (<font class="keywordtype">char</font>*) key, FALSE, NULL, NULL);
01123 
01124   <font class="keywordflow">if</font> (entry)
01125     <font class="keywordflow">return</font> entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>;
01126   <font class="keywordflow">else</font>
01127     <font class="keywordflow">return</font> NULL;
01128 }
01129 
01139 <font class="keywordtype">void</font>*
<a name="l01140"></a><a class="code" href="group__DBusHashTable.html#a19">01140</a> _dbus_hash_table_lookup_two_strings (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01141                                      <font class="keyword">const</font> <font class="keywordtype">char</font>    *key)
01142 {
01143   DBusHashEntry *entry;
01144 
01145   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_TWO_STRINGS);
01146   
01147   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, (<font class="keywordtype">char</font>*) key, FALSE, NULL, NULL);
01148 
01149   <font class="keywordflow">if</font> (entry)
01150     <font class="keywordflow">return</font> entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>;
01151   <font class="keywordflow">else</font>
01152     <font class="keywordflow">return</font> NULL;
01153 }
01154 
01164 <font class="keywordtype">void</font>*
<a name="l01165"></a><a class="code" href="group__DBusHashTable.html#a20">01165</a> _dbus_hash_table_lookup_int (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01166                              <font class="keywordtype">int</font>            key)
01167 {
01168   DBusHashEntry *entry;
01169 
01170   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_INT);
01171   
01172   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, _DBUS_INT_TO_POINTER (key), FALSE, NULL, NULL);
01173 
01174   <font class="keywordflow">if</font> (entry)
01175     <font class="keywordflow">return</font> entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>;
01176   <font class="keywordflow">else</font>
01177     <font class="keywordflow">return</font> NULL;
01178 }
01179 
01180 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font>
01181 <font class="preprocessor"></font><font class="comment">/* disabled since it's only used for testing */</font>
01191 <font class="keywordtype">void</font>*
<a name="l01192"></a><a class="code" href="group__DBusHashTable.html#a21">01192</a> _dbus_hash_table_lookup_pointer (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01193                                  <font class="keywordtype">void</font>          *key)
01194 {
01195   DBusHashEntry *entry;
01196 
01197   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_POINTER);
01198   
01199   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, key, FALSE, NULL, NULL);
01200 
01201   <font class="keywordflow">if</font> (entry)
01202     <font class="keywordflow">return</font> entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>;
01203   <font class="keywordflow">else</font>
01204     <font class="keywordflow">return</font> NULL;
01205 }
01206 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font>
01207 
01217 <font class="keywordtype">void</font>*
<a name="l01218"></a><a class="code" href="group__DBusHashTable.html#a22">01218</a> _dbus_hash_table_lookup_ulong (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01219                                <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>  key)
01220 {
01221   DBusHashEntry *entry;
01222 
01223   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_ULONG);
01224   
01225   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, (<font class="keywordtype">void</font>*) key, FALSE, NULL, NULL);
01226 
01227   <font class="keywordflow">if</font> (entry)
01228     <font class="keywordflow">return</font> entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>;
01229   <font class="keywordflow">else</font>
01230     <font class="keywordflow">return</font> NULL;
01231 }
01232 
01241 dbus_bool_t
<a name="l01242"></a><a class="code" href="group__DBusHashTable.html#a23">01242</a> _dbus_hash_table_remove_string (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01243                                 <font class="keyword">const</font> <font class="keywordtype">char</font>    *key)
01244 {
01245   DBusHashEntry *entry;
01246   DBusHashEntry **bucket;
01247   
01248   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_STRING);
01249   
01250   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, (<font class="keywordtype">char</font>*) key, FALSE, &amp;bucket, NULL);
01251 
01252   <font class="keywordflow">if</font> (entry)
01253     {
01254       remove_entry (table, bucket, entry);
01255       <font class="keywordflow">return</font> TRUE;
01256     }
01257   <font class="keywordflow">else</font>
01258     <font class="keywordflow">return</font> FALSE;
01259 }
01260 
01269 dbus_bool_t
<a name="l01270"></a><a class="code" href="group__DBusHashTable.html#a24">01270</a> _dbus_hash_table_remove_two_strings (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01271                                      <font class="keyword">const</font> <font class="keywordtype">char</font>    *key)
01272 {
01273   DBusHashEntry *entry;
01274   DBusHashEntry **bucket;
01275   
01276   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_TWO_STRINGS);
01277   
01278   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, (<font class="keywordtype">char</font>*) key, FALSE, &amp;bucket, NULL);
01279 
01280   <font class="keywordflow">if</font> (entry)
01281     {
01282       remove_entry (table, bucket, entry);
01283       <font class="keywordflow">return</font> TRUE;
01284     }
01285   <font class="keywordflow">else</font>
01286     <font class="keywordflow">return</font> FALSE;
01287 }
01288 
01297 dbus_bool_t
<a name="l01298"></a><a class="code" href="group__DBusHashTable.html#a25">01298</a> _dbus_hash_table_remove_int (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01299                              <font class="keywordtype">int</font>            key)
01300 {
01301   DBusHashEntry *entry;
01302   DBusHashEntry **bucket;
01303   
01304   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_INT);
01305   
01306   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, _DBUS_INT_TO_POINTER (key), FALSE, &amp;bucket, NULL);
01307   
01308   <font class="keywordflow">if</font> (entry)
01309     {
01310       remove_entry (table, bucket, entry);
01311       <font class="keywordflow">return</font> TRUE;
01312     }
01313   <font class="keywordflow">else</font>
01314     <font class="keywordflow">return</font> FALSE;
01315 }
01316 
01317 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font>
01318 <font class="preprocessor"></font><font class="comment">/* disabled since it's only used for testing */</font>
01327 dbus_bool_t
<a name="l01328"></a><a class="code" href="group__DBusHashTable.html#a26">01328</a> _dbus_hash_table_remove_pointer (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01329                                  <font class="keywordtype">void</font>          *key)
01330 {
01331   DBusHashEntry *entry;
01332   DBusHashEntry **bucket;
01333   
01334   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_POINTER);
01335   
01336   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, key, FALSE, &amp;bucket, NULL);
01337   
01338   <font class="keywordflow">if</font> (entry)
01339     {
01340       remove_entry (table, bucket, entry);
01341       <font class="keywordflow">return</font> TRUE;
01342     }
01343   <font class="keywordflow">else</font>
01344     <font class="keywordflow">return</font> FALSE;
01345 }
01346 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font>
01347 
01356 dbus_bool_t
<a name="l01357"></a><a class="code" href="group__DBusHashTable.html#a27">01357</a> _dbus_hash_table_remove_ulong (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01358                                <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>  key)
01359 {
01360   DBusHashEntry *entry;
01361   DBusHashEntry **bucket;
01362   
01363   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_ULONG);
01364   
01365   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, (<font class="keywordtype">void</font>*) key, FALSE, &amp;bucket, NULL);
01366   
01367   <font class="keywordflow">if</font> (entry)
01368     {
01369       remove_entry (table, bucket, entry);
01370       <font class="keywordflow">return</font> TRUE;
01371     }
01372   <font class="keywordflow">else</font>
01373     <font class="keywordflow">return</font> FALSE;
01374 }
01375 
01391 dbus_bool_t
<a name="l01392"></a><a class="code" href="group__DBusHashTable.html#a28">01392</a> _dbus_hash_table_insert_string (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01393                                 <font class="keywordtype">char</font>          *key,
01394                                 <font class="keywordtype">void</font>          *value)
01395 {
01396   DBusPreallocatedHash *preallocated;
01397 
01398   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_STRING);
01399 
01400   preallocated = _dbus_hash_table_preallocate_entry (table);
01401   <font class="keywordflow">if</font> (preallocated == NULL)
01402     <font class="keywordflow">return</font> FALSE;
01403 
01404   _dbus_hash_table_insert_string_preallocated (table, preallocated,
01405                                                key, value);
01406   
01407   <font class="keywordflow">return</font> TRUE;
01408 }
01409 
01425 dbus_bool_t
<a name="l01426"></a><a class="code" href="group__DBusHashTable.html#a29">01426</a> _dbus_hash_table_insert_two_strings (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01427                                      <font class="keywordtype">char</font>          *key,
01428                                      <font class="keywordtype">void</font>          *value)
01429 {
01430   DBusHashEntry *entry;
01431   
01432   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_TWO_STRINGS);
01433   
01434   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, key, TRUE, NULL, NULL);
01435 
01436   <font class="keywordflow">if</font> (entry == NULL)
01437     <font class="keywordflow">return</font> FALSE; <font class="comment">/* no memory */</font>
01438 
01439   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m11">free_key_function</a> &amp;&amp; entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a> != key)
01440     (* table-&gt;<a class="code" href="structDBusHashTable.html#m11">free_key_function</a>) (entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>);
01441   
01442   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a> &amp;&amp; entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a> != value)
01443     (* table-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>);
01444   
01445   entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a> = key;
01446   entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a> = value;
01447 
01448   <font class="keywordflow">return</font> TRUE;
01449 }
01450 
01466 dbus_bool_t
<a name="l01467"></a><a class="code" href="group__DBusHashTable.html#a30">01467</a> _dbus_hash_table_insert_int (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01468                              <font class="keywordtype">int</font>            key,
01469                              <font class="keywordtype">void</font>          *value)
01470 {
01471   DBusHashEntry *entry;
01472 
01473   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_INT);
01474   
01475   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, _DBUS_INT_TO_POINTER (key), TRUE, NULL, NULL);
01476 
01477   <font class="keywordflow">if</font> (entry == NULL)
01478     <font class="keywordflow">return</font> FALSE; <font class="comment">/* no memory */</font>
01479 
01480   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m11">free_key_function</a> &amp;&amp; entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a> != _DBUS_INT_TO_POINTER (key))
01481     (* table-&gt;<a class="code" href="structDBusHashTable.html#m11">free_key_function</a>) (entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>);
01482   
01483   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a> &amp;&amp; entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a> != value)
01484     (* table-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>);
01485   
01486   entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a> = _DBUS_INT_TO_POINTER (key);
01487   entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a> = value;
01488 
01489   <font class="keywordflow">return</font> TRUE;
01490 }
01491 
01492 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font>
01493 <font class="preprocessor"></font><font class="comment">/* disabled since it's only used for testing */</font>
01509 dbus_bool_t
<a name="l01510"></a><a class="code" href="group__DBusHashTable.html#a31">01510</a> _dbus_hash_table_insert_pointer (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01511                                  <font class="keywordtype">void</font>          *key,
01512                                  <font class="keywordtype">void</font>          *value)
01513 {
01514   DBusHashEntry *entry;
01515 
01516   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_POINTER);
01517   
01518   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, key, TRUE, NULL, NULL);
01519 
01520   <font class="keywordflow">if</font> (entry == NULL)
01521     <font class="keywordflow">return</font> FALSE; <font class="comment">/* no memory */</font>
01522 
01523   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m11">free_key_function</a> &amp;&amp; entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a> != key)
01524     (* table-&gt;<a class="code" href="structDBusHashTable.html#m11">free_key_function</a>) (entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>);
01525   
01526   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a> &amp;&amp; entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a> != value)
01527     (* table-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>);
01528   
01529   entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a> = key;
01530   entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a> = value;
01531 
01532   <font class="keywordflow">return</font> TRUE;
01533 }
01534 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font>
01535 
01551 dbus_bool_t
<a name="l01552"></a><a class="code" href="group__DBusHashTable.html#a32">01552</a> _dbus_hash_table_insert_ulong (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table,
01553                                <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>  key,
01554                                <font class="keywordtype">void</font>          *value)
01555 {
01556   DBusHashEntry *entry;
01557 
01558   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_ULONG);
01559   
01560   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, (<font class="keywordtype">void</font>*) key, TRUE, NULL, NULL);
01561 
01562   <font class="keywordflow">if</font> (entry == NULL)
01563     <font class="keywordflow">return</font> FALSE; <font class="comment">/* no memory */</font>
01564 
01565   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m11">free_key_function</a> &amp;&amp; entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a> != (<font class="keywordtype">void</font>*) key)
01566     (* table-&gt;<a class="code" href="structDBusHashTable.html#m11">free_key_function</a>) (entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>);
01567   
01568   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a> &amp;&amp; entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a> != value)
01569     (* table-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>);
01570   
01571   entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a> = (<font class="keywordtype">void</font>*) key;
01572   entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a> = value;
01573 
01574   <font class="keywordflow">return</font> TRUE;
01575 }
01576 
01584 DBusPreallocatedHash*
<a name="l01585"></a><a class="code" href="group__DBusHashTable.html#a33">01585</a> _dbus_hash_table_preallocate_entry (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table)
01586 {
01587   DBusHashEntry *entry;
01588   
01589   entry = alloc_entry (table);
01590 
01591   <font class="keywordflow">return</font> (DBusPreallocatedHash*) entry;
01592 }
01593 
01601 <font class="keywordtype">void</font>
<a name="l01602"></a><a class="code" href="group__DBusHashTable.html#a34">01602</a> _dbus_hash_table_free_preallocated_entry (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>        *table,
01603                                           DBusPreallocatedHash *preallocated)
01604 {
01605   DBusHashEntry *entry;
01606 
01607   _dbus_assert (preallocated != NULL);
01608   
01609   entry = (DBusHashEntry*) preallocated;
01610   
01611   <font class="comment">/* Don't use free_entry(), since this entry has no key/data */</font>
01612   _dbus_mem_pool_dealloc (table-&gt;<a class="code" href="structDBusHashTable.html#m13">entry_pool</a>, entry);
01613 }
01614 
01628 <font class="keywordtype">void</font>
<a name="l01629"></a><a class="code" href="group__DBusHashTable.html#a35">01629</a> _dbus_hash_table_insert_string_preallocated (<a class="code" href="structDBusHashTable.html">DBusHashTable</a>        *table,
01630                                              DBusPreallocatedHash *preallocated,
01631                                              <font class="keywordtype">char</font>                 *key,
01632                                              <font class="keywordtype">void</font>                 *value)
01633 {
01634   DBusHashEntry *entry;
01635 
01636   _dbus_assert (table-&gt;<a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_STRING);
01637   _dbus_assert (preallocated != NULL);
01638   
01639   entry = (* table-&gt;<a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, key, TRUE, NULL, preallocated);
01640 
01641   _dbus_assert (entry != NULL);
01642   
01643   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m11">free_key_function</a> &amp;&amp; entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a> != key)
01644     (* table-&gt;<a class="code" href="structDBusHashTable.html#m11">free_key_function</a>) (entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a>);
01645 
01646   <font class="keywordflow">if</font> (table-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a> &amp;&amp; entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a> != value)
01647     (* table-&gt;<a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a>);
01648       
01649   entry-&gt;<a class="code" href="structDBusHashEntry.html#m1">key</a> = key;
01650   entry-&gt;<a class="code" href="structDBusHashEntry.html#m2">value</a> = value;
01651 }
01652 
01659 <font class="keywordtype">int</font>
<a name="l01660"></a><a class="code" href="group__DBusHashTable.html#a36">01660</a> _dbus_hash_table_get_n_entries (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table)
01661 {
01662   <font class="keywordflow">return</font> table-&gt;<a class="code" href="structDBusHashTable.html#m4">n_entries</a>;
01663 }
01664 
01667 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font>
01668 <font class="preprocessor"></font><font class="preprocessor">#include "dbus-test.h"</font>
01669 <font class="preprocessor">#include &lt;stdio.h&gt;</font>
01670 
01671 <font class="comment">/* If you're wondering why the hash table test takes</font>
01672 <font class="comment"> * forever to run, it's because we call this function</font>
01673 <font class="comment"> * in inner loops thus making things quadratic.</font>
01674 <font class="comment"> */</font>
01675 <font class="keyword">static</font> <font class="keywordtype">int</font>
01676 count_entries (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table)
01677 {
01678   <a class="code" href="structDBusHashIter.html">DBusHashIter</a> iter;
01679   <font class="keywordtype">int</font> count;
01680 
01681   count = 0;
01682   _dbus_hash_iter_init (table, &amp;iter);
01683   <font class="keywordflow">while</font> (_dbus_hash_iter_next (&amp;iter))
01684     ++count;
01685 
01686   _dbus_assert (count == _dbus_hash_table_get_n_entries (table));
01687   
01688   <font class="keywordflow">return</font> count;
01689 }
01690 
01691 <font class="comment">/* Copy the foo\0bar\0 double string thing */</font>
01692 <font class="keyword">static</font> <font class="keywordtype">char</font>*
01693 _dbus_strdup2 (<font class="keyword">const</font> <font class="keywordtype">char</font> *str)
01694 {
01695   size_t len;
01696   <font class="keywordtype">char</font> *copy;
01697   
01698   <font class="keywordflow">if</font> (str == NULL)
01699     <font class="keywordflow">return</font> NULL;
01700   
01701   len = strlen (str);
01702   len += strlen ((str + len + 1));
01703 
01704   copy = dbus_malloc (len + 2);
01705   <font class="keywordflow">if</font> (copy == NULL)
01706     <font class="keywordflow">return</font> NULL;
01707 
01708   memcpy (copy, str, len + 2);
01709   
01710   <font class="keywordflow">return</font> copy;
01711 }
01712 
01718 dbus_bool_t
<a name="l01719"></a><a class="code" href="group__DBusHashTableInternals.html#a12">01719</a> _dbus_hash_test (<font class="keywordtype">void</font>)
01720 {
01721   <font class="keywordtype">int</font> i;
01722   <a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table1;
01723   <a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table2;
01724   <a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table3;
01725   <a class="code" href="structDBusHashTable.html">DBusHashTable</a> *table4;
01726   <a class="code" href="structDBusHashIter.html">DBusHashIter</a> iter;
01727 <font class="preprocessor">#define N_HASH_KEYS 5000</font>
01728 <font class="preprocessor"></font>  <font class="keywordtype">char</font> **keys;
01729   dbus_bool_t ret = FALSE;
01730 
01731   keys = dbus_new (<font class="keywordtype">char</font> *, N_HASH_KEYS);
01732   <font class="keywordflow">if</font> (keys == NULL)
01733     _dbus_assert_not_reached (<font class="stringliteral">"no memory"</font>);
01734 
01735   <font class="keywordflow">for</font> (i = 0; i &lt; N_HASH_KEYS; i++)
01736     {
01737       keys[i] = dbus_malloc (128);
01738 
01739       <font class="keywordflow">if</font> (keys[i] == NULL)
01740         _dbus_assert_not_reached (<font class="stringliteral">"no memory"</font>);
01741     }
01742 
01743   printf (<font class="stringliteral">"Computing test hash keys...\n"</font>);
01744   i = 0;
01745   <font class="keywordflow">while</font> (i &lt; N_HASH_KEYS)
01746     {
01747       <font class="keywordtype">int</font> len;
01748 
01749       <font class="comment">/* all the hash keys are TWO_STRINGS, but</font>
01750 <font class="comment">       * then we can also use those as regular strings.</font>
01751 <font class="comment">       */</font>
01752       
01753       len = sprintf (keys[i], <font class="stringliteral">"Hash key %d"</font>, i);
01754       sprintf (keys[i] + len + 1, <font class="stringliteral">"Two string %d"</font>, i);
01755       _dbus_assert (*(keys[i] + len) == <font class="charliteral">'\0'</font>);
01756       _dbus_assert (*(keys[i] + len + 1) != <font class="charliteral">'\0'</font>);
01757       ++i;
01758     }
01759   printf (<font class="stringliteral">"... done.\n"</font>);
01760   
01761   table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
01762                                  dbus_free, dbus_free);
01763   <font class="keywordflow">if</font> (table1 == NULL)
01764     <font class="keywordflow">goto</font> out;
01765 
01766   table2 = _dbus_hash_table_new (DBUS_HASH_INT,
01767                                  NULL, dbus_free);
01768   <font class="keywordflow">if</font> (table2 == NULL)
01769     <font class="keywordflow">goto</font> out;
01770 
01771   table3 = _dbus_hash_table_new (DBUS_HASH_ULONG,
01772                                  NULL, dbus_free);
01773   <font class="keywordflow">if</font> (table3 == NULL)
01774     <font class="keywordflow">goto</font> out;
01775 
01776   table4 = _dbus_hash_table_new (DBUS_HASH_TWO_STRINGS,
01777                                  dbus_free, dbus_free);
01778   <font class="keywordflow">if</font> (table4 == NULL)
01779     <font class="keywordflow">goto</font> out;
01780 
01781   
01782   <font class="comment">/* Insert and remove a bunch of stuff, counting the table in between</font>
01783 <font class="comment">   * to be sure it's not broken and that iteration works</font>
01784 <font class="comment">   */</font>
01785   i = 0;
01786   <font class="keywordflow">while</font> (i &lt; 3000)
01787     {
01788       <font class="keywordtype">void</font> *value;
01789       <font class="keywordtype">char</font> *key;
01790 
01791       key = _dbus_strdup (keys[i]);
01792       <font class="keywordflow">if</font> (key == NULL)
01793         <font class="keywordflow">goto</font> out;
01794       value = _dbus_strdup (<font class="stringliteral">"Value!"</font>);
01795       <font class="keywordflow">if</font> (value == NULL)
01796         <font class="keywordflow">goto</font> out;
01797       
01798       <font class="keywordflow">if</font> (!_dbus_hash_table_insert_string (table1,
01799                                            key, value))
01800         <font class="keywordflow">goto</font> out;
01801 
01802       value = _dbus_strdup (keys[i]);
01803       <font class="keywordflow">if</font> (value == NULL)
01804         <font class="keywordflow">goto</font> out;
01805       
01806       <font class="keywordflow">if</font> (!_dbus_hash_table_insert_int (table2,
01807                                         i, value))
01808         <font class="keywordflow">goto</font> out;
01809 
01810       value = _dbus_strdup (keys[i]);
01811       <font class="keywordflow">if</font> (value == NULL)
01812         <font class="keywordflow">goto</font> out;
01813       
01814       <font class="keywordflow">if</font> (!_dbus_hash_table_insert_ulong (table3,
01815                                           i, value))
01816         <font class="keywordflow">goto</font> out;
01817 
01818       key = _dbus_strdup2 (keys[i]);
01819       <font class="keywordflow">if</font> (key == NULL)
01820         <font class="keywordflow">goto</font> out;
01821       value = _dbus_strdup (<font class="stringliteral">"Value!"</font>);
01822       <font class="keywordflow">if</font> (value == NULL)
01823         <font class="keywordflow">goto</font> out;
01824       
01825       <font class="keywordflow">if</font> (!_dbus_hash_table_insert_two_strings (table4,
01826                                                 key, value))
01827         <font class="keywordflow">goto</font> out;
01828       
01829       _dbus_assert (count_entries (table1) == i + 1);
01830       _dbus_assert (count_entries (table2) == i + 1);
01831       _dbus_assert (count_entries (table3) == i + 1);
01832       _dbus_assert (count_entries (table4) == i + 1);
01833 
01834       value = _dbus_hash_table_lookup_string (table1, keys[i]);
01835       _dbus_assert (value != NULL);
01836       _dbus_assert (strcmp (value, <font class="stringliteral">"Value!"</font>) == 0);
01837 
01838       value = _dbus_hash_table_lookup_int (table2, i);
01839       _dbus_assert (value != NULL);
01840       _dbus_assert (strcmp (value, keys[i]) == 0);
01841 
01842       value = _dbus_hash_table_lookup_ulong (table3, i);
01843       _dbus_assert (value != NULL);
01844       _dbus_assert (strcmp (value, keys[i]) == 0);
01845 
01846       value = _dbus_hash_table_lookup_two_strings (table4, keys[i]);
01847       _dbus_assert (value != NULL);
01848       _dbus_assert (strcmp (value, <font class="stringliteral">"Value!"</font>) == 0);
01849       
01850       ++i;
01851     }
01852 
01853   --i;
01854   <font class="keywordflow">while</font> (i &gt;= 0)
01855     {
01856       _dbus_hash_table_remove_string (table1,
01857                                       keys[i]);
01858 
01859       _dbus_hash_table_remove_int (table2, i);
01860 
01861       _dbus_hash_table_remove_ulong (table3, i); 
01862 
01863       _dbus_hash_table_remove_two_strings (table4,
01864                                            keys[i]);
01865       
01866       _dbus_assert (count_entries (table1) == i);
01867       _dbus_assert (count_entries (table2) == i);
01868       _dbus_assert (count_entries (table3) == i);
01869       _dbus_assert (count_entries (table4) == i);
01870 
01871       --i;
01872     }
01873 
01874   _dbus_hash_table_ref (table1);
01875   _dbus_hash_table_ref (table2);
01876   _dbus_hash_table_ref (table3);
01877   _dbus_hash_table_ref (table4);
01878   _dbus_hash_table_unref (table1);
01879   _dbus_hash_table_unref (table2);
01880   _dbus_hash_table_unref (table3);
01881   _dbus_hash_table_unref (table4);
01882   _dbus_hash_table_unref (table1);
01883   _dbus_hash_table_unref (table2);
01884   _dbus_hash_table_unref (table3);
01885   _dbus_hash_table_unref (table4);
01886   table3 = NULL;
01887 
01888   <font class="comment">/* Insert a bunch of stuff then check</font>
01889 <font class="comment">   * that iteration works correctly (finds the right</font>
01890 <font class="comment">   * values, iter_set_value works, etc.)</font>
01891 <font class="comment">   */</font>
01892   table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
01893                                  dbus_free, dbus_free);
01894   <font class="keywordflow">if</font> (table1 == NULL)
01895     <font class="keywordflow">goto</font> out;
01896   
01897   table2 = _dbus_hash_table_new (DBUS_HASH_INT,
01898                                  NULL, dbus_free);
01899   <font class="keywordflow">if</font> (table2 == NULL)
01900     <font class="keywordflow">goto</font> out;
01901   
01902   i = 0;
01903   <font class="keywordflow">while</font> (i &lt; 5000)
01904     {
01905       <font class="keywordtype">char</font> *key;
01906       <font class="keywordtype">void</font> *value;      
01907       
01908       key = _dbus_strdup (keys[i]);
01909       <font class="keywordflow">if</font> (key == NULL)
01910         <font class="keywordflow">goto</font> out;
01911       value = _dbus_strdup (<font class="stringliteral">"Value!"</font>);
01912       <font class="keywordflow">if</font> (value == NULL)
01913         <font class="keywordflow">goto</font> out;
01914       
01915       <font class="keywordflow">if</font> (!_dbus_hash_table_insert_string (table1,
01916                                            key, value))
01917         <font class="keywordflow">goto</font> out;
01918 
01919       value = _dbus_strdup (keys[i]);
01920       <font class="keywordflow">if</font> (value == NULL)
01921         <font class="keywordflow">goto</font> out;
01922       
01923       <font class="keywordflow">if</font> (!_dbus_hash_table_insert_int (table2,
01924                                         i, value))
01925         <font class="keywordflow">goto</font> out;
01926       
01927       _dbus_assert (count_entries (table1) == i + 1);
01928       _dbus_assert (count_entries (table2) == i + 1);
01929       
01930       ++i;
01931     }
01932 
01933   _dbus_hash_iter_init (table1, &amp;iter);
01934   <font class="keywordflow">while</font> (_dbus_hash_iter_next (&amp;iter))
01935     {
01936       <font class="keyword">const</font> <font class="keywordtype">char</font> *key;
01937       <font class="keywordtype">void</font> *value;
01938 
01939       key = _dbus_hash_iter_get_string_key (&amp;iter);
01940       value = _dbus_hash_iter_get_value (&amp;iter);
01941 
01942       _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
01943 
01944       value = _dbus_strdup (<font class="stringliteral">"Different value!"</font>);
01945       <font class="keywordflow">if</font> (value == NULL)
01946         <font class="keywordflow">goto</font> out;
01947       
01948       _dbus_hash_iter_set_value (&amp;iter, value);
01949 
01950       _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value);
01951     }
01952   
01953   _dbus_hash_iter_init (table1, &amp;iter);
01954   <font class="keywordflow">while</font> (_dbus_hash_iter_next (&amp;iter))
01955     {
01956       _dbus_hash_iter_remove_entry (&amp;iter);
01957       _dbus_assert (count_entries (table1) == i - 1);
01958       --i;
01959     }
01960 
01961   _dbus_hash_iter_init (table2, &amp;iter);
01962   <font class="keywordflow">while</font> (_dbus_hash_iter_next (&amp;iter))
01963     {
01964       <font class="keywordtype">int</font> key;
01965       <font class="keywordtype">void</font> *value;
01966 
01967       key = _dbus_hash_iter_get_int_key (&amp;iter);
01968       value = _dbus_hash_iter_get_value (&amp;iter);
01969 
01970       _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
01971 
01972       value = _dbus_strdup (<font class="stringliteral">"Different value!"</font>);
01973       <font class="keywordflow">if</font> (value == NULL)
01974         <font class="keywordflow">goto</font> out;
01975       
01976       _dbus_hash_iter_set_value (&amp;iter, value);
01977 
01978       _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value);
01979     }
01980 
01981   i = count_entries (table2);
01982   _dbus_hash_iter_init (table2, &amp;iter);
01983   <font class="keywordflow">while</font> (_dbus_hash_iter_next (&amp;iter))
01984     {
01985       _dbus_hash_iter_remove_entry (&amp;iter);
01986       _dbus_assert (count_entries (table2) + 1 == i);
01987       --i;
01988     }
01989 
01990   <font class="comment">/* add/remove interleaved, to check that we grow/shrink the table</font>
01991 <font class="comment">   * appropriately</font>
01992 <font class="comment">   */</font>
01993   i = 0;
01994   <font class="keywordflow">while</font> (i &lt; 1000)
01995     {
01996       <font class="keywordtype">char</font> *key;
01997       <font class="keywordtype">void</font> *value;
01998             
01999       key = _dbus_strdup (keys[i]);
02000       <font class="keywordflow">if</font> (key == NULL)
02001         <font class="keywordflow">goto</font> out;
02002 
02003       value = _dbus_strdup (<font class="stringliteral">"Value!"</font>);
02004       <font class="keywordflow">if</font> (value == NULL)
02005         <font class="keywordflow">goto</font> out;
02006       
02007       <font class="keywordflow">if</font> (!_dbus_hash_table_insert_string (table1,
02008                                            key, value))
02009         <font class="keywordflow">goto</font> out;
02010       
02011       ++i;
02012     }
02013 
02014   --i;
02015   <font class="keywordflow">while</font> (i &gt;= 0)
02016     {
02017       <font class="keywordtype">char</font> *key;
02018       <font class="keywordtype">void</font> *value;      
02019       
02020       key = _dbus_strdup (keys[i]);
02021       <font class="keywordflow">if</font> (key == NULL)
02022         <font class="keywordflow">goto</font> out;
02023       value = _dbus_strdup (<font class="stringliteral">"Value!"</font>);
02024       <font class="keywordflow">if</font> (value == NULL)
02025         <font class="keywordflow">goto</font> out;
02026 
02027       <font class="keywordflow">if</font> (!_dbus_hash_table_remove_string (table1, keys[i]))
02028         <font class="keywordflow">goto</font> out;
02029       
02030       <font class="keywordflow">if</font> (!_dbus_hash_table_insert_string (table1,
02031                                            key, value))
02032         <font class="keywordflow">goto</font> out;
02033 
02034       <font class="keywordflow">if</font> (!_dbus_hash_table_remove_string (table1, keys[i]))
02035         <font class="keywordflow">goto</font> out;
02036       
02037       _dbus_assert (_dbus_hash_table_get_n_entries (table1) == i);
02038       
02039       --i;
02040     }
02041 
02042   <font class="comment">/* nuke these tables */</font>
02043   _dbus_hash_table_unref (table1);
02044   _dbus_hash_table_unref (table2);
02045 
02046 
02047   <font class="comment">/* Now do a bunch of things again using _dbus_hash_iter_lookup() to</font>
02048 <font class="comment">   * be sure that interface works.</font>
02049 <font class="comment">   */</font>
02050   table1 = _dbus_hash_table_new (DBUS_HASH_STRING,
02051                                  dbus_free, dbus_free);
02052   <font class="keywordflow">if</font> (table1 == NULL)
02053     <font class="keywordflow">goto</font> out;
02054   
02055   table2 = _dbus_hash_table_new (DBUS_HASH_INT,
02056                                  NULL, dbus_free);
02057   <font class="keywordflow">if</font> (table2 == NULL)
02058     <font class="keywordflow">goto</font> out;
02059   
02060   i = 0;
02061   <font class="keywordflow">while</font> (i &lt; 3000)
02062     {
02063       <font class="keywordtype">void</font> *value;
02064       <font class="keywordtype">char</font> *key;
02065 
02066       key = _dbus_strdup (keys[i]);
02067       <font class="keywordflow">if</font> (key == NULL)
02068         <font class="keywordflow">goto</font> out;
02069       value = _dbus_strdup (<font class="stringliteral">"Value!"</font>);
02070       <font class="keywordflow">if</font> (value == NULL)
02071         <font class="keywordflow">goto</font> out;
02072       
02073       <font class="keywordflow">if</font> (!_dbus_hash_iter_lookup (table1,
02074                                    key, TRUE, &amp;iter))
02075         <font class="keywordflow">goto</font> out;
02076       _dbus_assert (_dbus_hash_iter_get_value (&amp;iter) == NULL);
02077       _dbus_hash_iter_set_value (&amp;iter, value);
02078 
02079       value = _dbus_strdup (keys[i]);
02080       <font class="keywordflow">if</font> (value == NULL)
02081         <font class="keywordflow">goto</font> out;
02082 
02083       <font class="keywordflow">if</font> (!_dbus_hash_iter_lookup (table2,
02084                                    _DBUS_INT_TO_POINTER (i), TRUE, &amp;iter))
02085         <font class="keywordflow">goto</font> out;
02086       _dbus_assert (_dbus_hash_iter_get_value (&amp;iter) == NULL);
02087       _dbus_hash_iter_set_value (&amp;iter, value); 
02088       
02089       _dbus_assert (count_entries (table1) == i + 1);
02090       _dbus_assert (count_entries (table2) == i + 1);
02091 
02092       <font class="keywordflow">if</font> (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &amp;iter))
02093         <font class="keywordflow">goto</font> out;
02094       
02095       value = _dbus_hash_iter_get_value (&amp;iter);
02096       _dbus_assert (value != NULL);
02097       _dbus_assert (strcmp (value, <font class="stringliteral">"Value!"</font>) == 0);
02098 
02099       <font class="comment">/* Iterate just to be sure it works, though</font>
02100 <font class="comment">       * it's a stupid thing to do</font>
02101 <font class="comment">       */</font>
02102       <font class="keywordflow">while</font> (_dbus_hash_iter_next (&amp;iter))
02103         ;
02104       
02105       <font class="keywordflow">if</font> (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &amp;iter))
02106         <font class="keywordflow">goto</font> out;
02107 
02108       value = _dbus_hash_iter_get_value (&amp;iter);
02109       _dbus_assert (value != NULL);
02110       _dbus_assert (strcmp (value, keys[i]) == 0);
02111 
02112       <font class="comment">/* Iterate just to be sure it works, though</font>
02113 <font class="comment">       * it's a stupid thing to do</font>
02114 <font class="comment">       */</font>
02115       <font class="keywordflow">while</font> (_dbus_hash_iter_next (&amp;iter))
02116         ;
02117       
02118       ++i;
02119     }
02120 
02121   --i;
02122   <font class="keywordflow">while</font> (i &gt;= 0)
02123     {
02124       <font class="keywordflow">if</font> (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &amp;iter))
02125         _dbus_assert_not_reached (<font class="stringliteral">"hash entry should have existed"</font>);
02126       _dbus_hash_iter_remove_entry (&amp;iter);
02127       
02128       <font class="keywordflow">if</font> (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &amp;iter))
02129         _dbus_assert_not_reached (<font class="stringliteral">"hash entry should have existed"</font>);
02130       _dbus_hash_iter_remove_entry (&amp;iter);
02131 
02132       _dbus_assert (count_entries (table1) == i);
02133       _dbus_assert (count_entries (table2) == i);
02134 
02135       --i;
02136     }
02137 
02138   _dbus_hash_table_unref (table1);
02139   _dbus_hash_table_unref (table2);
02140 
02141   ret = TRUE;
02142 
02143  out:
02144   <font class="keywordflow">for</font> (i = 0; i &lt; N_HASH_KEYS; i++)
02145     dbus_free (keys[i]);
02146 
02147   dbus_free (keys);
02148   
02149   <font class="keywordflow">return</font> ret;
02150 }
02151 
02152 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font>
</pre></div><hr><address align="right"><small>Generated on Wed Jun 9 05:01:25 2004 for D-BUS by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 
width=110 height=53></a>1.2.15 </small></address>
</body>
</html>