<!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> <a class="qindex" href="modules.html">Modules</a> <a class="qindex" href="annotated.html">Data Structures</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Data Fields</a> <a class="qindex" href="pages.html">Related Pages</a> </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) >> (table)->down_shift) & (table)->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-><a class="code" href="structDBusHashTable.html#m0">refcount</a> = 1; 00307 table-><a class="code" href="structDBusHashTable.html#m13">entry_pool</a> = entry_pool; 00308 00309 _dbus_assert (DBUS_SMALL_HASH_TABLE == _DBUS_N_ELEMENTS (table-><a class="code" href="structDBusHashTable.html#m2">static_buckets</a>)); 00310 00311 table-><a class="code" href="structDBusHashTable.html#m1">buckets</a> = table-><a class="code" href="structDBusHashTable.html#m2">static_buckets</a>; 00312 table-><a class="code" href="structDBusHashTable.html#m3">n_buckets</a> = DBUS_SMALL_HASH_TABLE; 00313 table-><a class="code" href="structDBusHashTable.html#m4">n_entries</a> = 0; 00314 table-><a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a> = DBUS_SMALL_HASH_TABLE * REBUILD_MULTIPLIER; 00315 table-><a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a> = 0; 00316 table-><a class="code" href="structDBusHashTable.html#m7">down_shift</a> = 28; 00317 table-><a class="code" href="structDBusHashTable.html#m8">mask</a> = 3; 00318 table-><a class="code" href="structDBusHashTable.html#m9">key_type</a> = type; 00319 00320 _dbus_assert (table-><a class="code" href="structDBusHashTable.html#m8">mask</a> < table-><a class="code" href="structDBusHashTable.html#m3">n_buckets</a>); 00321 00322 <font class="keywordflow">switch</font> (table-><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-><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-><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-><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-><a class="code" href="structDBusHashTable.html#m11">free_key_function</a> = key_free_function; 00341 table-><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-><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-><a class="code" href="structDBusHashTable.html#m0">refcount</a> -= 1; 00371 00372 <font class="keywordflow">if</font> (table-><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 < table-><a class="code" href="structDBusHashTable.html#m3">n_buckets</a>; i++) 00381 { 00382 entry = table-><a class="code" href="structDBusHashTable.html#m1">buckets</a>[i]; 00383 <font class="keywordflow">while</font> (entry != NULL) 00384 { 00385 next = entry-><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 < table-><a class="code" href="structDBusHashTable.html#m3">n_buckets</a>; i++) 00398 { 00399 entry = table-><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-><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-><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-><a class="code" href="structDBusHashTable.html#m1">buckets</a> != table-><a class="code" href="structDBusHashTable.html#m2">static_buckets</a>) 00413 dbus_free (table-><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-><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-><a class="code" href="structDBusHashTable.html#m11">free_key_function</a>) 00434 (* table-><a class="code" href="structDBusHashTable.html#m11">free_key_function</a>) (entry-><a class="code" href="structDBusHashEntry.html#m1">key</a>); 00435 <font class="keywordflow">if</font> (table-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) 00436 (* table-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (entry-><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-><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-><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-><a class="code" href="structDBusHashEntry.html#m0">next</a> != entry) 00465 prev = prev-><a class="code" href="structDBusHashEntry.html#m0">next</a>; 00466 00467 _dbus_assert (prev != NULL); 00468 00469 prev-><a class="code" href="structDBusHashEntry.html#m0">next</a> = entry-><a class="code" href="structDBusHashEntry.html#m0">next</a>; 00470 } 00471 00472 table-><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-><a class="code" href="structDBusRealHashIter.html#m0">table</a> = table; 00518 real-><a class="code" href="structDBusRealHashIter.html#m1">bucket</a> = NULL; 00519 real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a> = NULL; 00520 real-><a class="code" href="structDBusRealHashIter.html#m3">next_entry</a> = NULL; 00521 real-><a class="code" href="structDBusRealHashIter.html#m4">next_bucket</a> = 0; 00522 real-><a class="code" href="structDBusRealHashIter.html#m5">n_entries_on_init</a> = table-><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-><a class="code" href="structDBusRealHashIter.html#m5">n_entries_on_init</a> >= real-><a class="code" href="structDBusRealHashIter.html#m0">table</a>-><a class="code" href="structDBusHashTable.html#m4">n_entries</a>); 00546 00547 <font class="comment">/* Remember that real->entry may have been deleted */</font> 00548 00549 <font class="keywordflow">while</font> (real-><a class="code" href="structDBusRealHashIter.html#m3">next_entry</a> == NULL) 00550 { 00551 <font class="keywordflow">if</font> (real-><a class="code" href="structDBusRealHashIter.html#m4">next_bucket</a> >= real-><a class="code" href="structDBusRealHashIter.html#m0">table</a>-><a class="code" href="structDBusHashTable.html#m3">n_buckets</a>) 00552 { 00553 <font class="comment">/* invalidate iter and return false */</font> 00554 real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a> = NULL; 00555 real-><a class="code" href="structDBusRealHashIter.html#m0">table</a> = NULL; 00556 real-><a class="code" href="structDBusRealHashIter.html#m1">bucket</a> = NULL; 00557 <font class="keywordflow">return</font> FALSE; 00558 } 00559 00560 real-><a class="code" href="structDBusRealHashIter.html#m1">bucket</a> = &(real-><a class="code" href="structDBusRealHashIter.html#m0">table</a>-><a class="code" href="structDBusHashTable.html#m1">buckets</a>[real-><a class="code" href="structDBusRealHashIter.html#m4">next_bucket</a>]); 00561 real-><a class="code" href="structDBusRealHashIter.html#m3">next_entry</a> = *(real-><a class="code" href="structDBusRealHashIter.html#m1">bucket</a>); 00562 real-><a class="code" href="structDBusRealHashIter.html#m4">next_bucket</a> += 1; 00563 } 00564 00565 _dbus_assert (real-><a class="code" href="structDBusRealHashIter.html#m3">next_entry</a> != NULL); 00566 _dbus_assert (real-><a class="code" href="structDBusRealHashIter.html#m1">bucket</a> != NULL); 00567 00568 real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a> = real-><a class="code" href="structDBusRealHashIter.html#m3">next_entry</a>; 00569 real-><a class="code" href="structDBusRealHashIter.html#m3">next_entry</a> = real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a>-><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-><a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL); 00590 _dbus_assert (real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a> != NULL); 00591 _dbus_assert (real-><a class="code" href="structDBusRealHashIter.html#m1">bucket</a> != NULL); 00592 00593 remove_entry (real-><a class="code" href="structDBusRealHashIter.html#m0">table</a>, real-><a class="code" href="structDBusRealHashIter.html#m1">bucket</a>, real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a>); 00594 00595 real-><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-><a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL); 00611 _dbus_assert (real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a> != NULL); 00612 00613 <font class="keywordflow">return</font> real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a>-><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-><a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL); 00635 _dbus_assert (real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a> != NULL); 00636 00637 <font class="keywordflow">if</font> (real-><a class="code" href="structDBusRealHashIter.html#m0">table</a>-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a> && value != real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a>-><a class="code" href="structDBusHashEntry.html#m2">value</a>) 00638 (* real-><a class="code" href="structDBusRealHashIter.html#m0">table</a>-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a>-><a class="code" href="structDBusHashEntry.html#m2">value</a>); 00639 00640 real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a>-><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-><a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL); 00657 _dbus_assert (real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a> != NULL); 00658 00659 <font class="keywordflow">return</font> _DBUS_POINTER_TO_INT (real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a>-><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-><a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL); 00676 _dbus_assert (real-><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-><a class="code" href="structDBusRealHashIter.html#m2">entry</a>-><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-><a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL); 00694 _dbus_assert (real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a> != NULL); 00695 00696 <font class="keywordflow">return</font> real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a>-><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-><a class="code" href="structDBusRealHashIter.html#m0">table</a> != NULL); 00712 _dbus_assert (real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a> != NULL); 00713 00714 <font class="keywordflow">return</font> real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a>-><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-><a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, key, create_if_not_found, &bucket, NULL); 00763 00764 <font class="keywordflow">if</font> (entry == NULL) 00765 <font class="keywordflow">return</font> FALSE; 00766 00767 real-><a class="code" href="structDBusRealHashIter.html#m0">table</a> = table; 00768 real-><a class="code" href="structDBusRealHashIter.html#m1">bucket</a> = bucket; 00769 real-><a class="code" href="structDBusRealHashIter.html#m2">entry</a> = entry; 00770 real-><a class="code" href="structDBusRealHashIter.html#m3">next_entry</a> = entry-><a class="code" href="structDBusHashEntry.html#m0">next</a>; 00771 real-><a class="code" href="structDBusRealHashIter.html#m4">next_bucket</a> = (bucket - table-><a class="code" href="structDBusHashTable.html#m1">buckets</a>) + 1; 00772 real-><a class="code" href="structDBusRealHashIter.html#m5">n_entries_on_init</a> = table-><a class="code" href="structDBusHashTable.html#m4">n_entries</a>; 00773 00774 _dbus_assert (&(table-><a class="code" href="structDBusHashTable.html#m1">buckets</a>[real-><a class="code" href="structDBusRealHashIter.html#m4">next_bucket</a>-1]) == real-><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-><a class="code" href="structDBusHashEntry.html#m1">key</a> = key; 00789 00790 b = &(table-><a class="code" href="structDBusHashTable.html#m1">buckets</a>[idx]); 00791 entry-><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-><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-><a class="code" href="structDBusHashTable.html#m4">n_entries</a> >= table-><a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a> || 00803 table-><a class="code" href="structDBusHashTable.html#m4">n_entries</a> < table-><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 << 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 << 5) - h + *p; 00864 00865 <font class="keywordflow">for</font> (p += 1; *p != <font class="charliteral">'\0'</font>; p++) 00866 h = (h << 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-><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 && key == entry-><a class="code" href="structDBusHashEntry.html#m1">key</a>) || 00893 (compare_func != NULL && (* compare_func) (key, entry-><a class="code" href="structDBusHashEntry.html#m1">key</a>) == 0)) 00894 { 00895 <font class="keywordflow">if</font> (bucket) 00896 *bucket = &(table-><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-><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) & table-><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) & table-><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) & table-><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-><a class="code" href="structDBusHashTable.html#m4">n_entries</a> >= table-><a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a>; 00998 00999 old_size = table-><a class="code" href="structDBusHashTable.html#m3">n_buckets</a>; 01000 old_buckets = table-><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-><a class="code" href="structDBusHashTable.html#m3">n_buckets</a> < _DBUS_INT_MAX / 4 && 01006 table-><a class="code" href="structDBusHashTable.html#m7">down_shift</a> >= 0) 01007 new_buckets = table-><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-><a class="code" href="structDBusHashTable.html#m3">n_buckets</a> / 4; 01014 <font class="keywordflow">if</font> (new_buckets < DBUS_SMALL_HASH_TABLE) 01015 <font class="keywordflow">return</font>; <font class="comment">/* don't bother shrinking this far */</font> 01016 } 01017 01018 table-><a class="code" href="structDBusHashTable.html#m1">buckets</a> = dbus_new0 (DBusHashEntry*, new_buckets); 01019 <font class="keywordflow">if</font> (table-><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-><a class="code" href="structDBusHashTable.html#m1">buckets</a> = old_buckets; 01025 <font class="keywordflow">return</font>; 01026 } 01027 01028 table-><a class="code" href="structDBusHashTable.html#m3">n_buckets</a> = new_buckets; 01029 01030 <font class="keywordflow">if</font> (growing) 01031 { 01032 table-><a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a> = table-><a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a>; 01033 table-><a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a> *= 4; 01034 01035 table-><a class="code" href="structDBusHashTable.html#m7">down_shift</a> -= 2; <font class="comment">/* keep 2 more high bits */</font> 01036 table-><a class="code" href="structDBusHashTable.html#m8">mask</a> = (table-><a class="code" href="structDBusHashTable.html#m8">mask</a> << 2) + 3; <font class="comment">/* keep 2 more high bits */</font> 01037 } 01038 <font class="keywordflow">else</font> 01039 { 01040 table-><a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a> = table-><a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a>; 01041 table-><a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a> /= 4; 01042 01043 table-><a class="code" href="structDBusHashTable.html#m7">down_shift</a> += 2; <font class="comment">/* keep 2 fewer high bits */</font> 01044 table-><a class="code" href="structDBusHashTable.html#m8">mask</a> = table-><a class="code" href="structDBusHashTable.html#m8">mask</a> >> 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-><a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a>, 01051 table-><a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a>, 01052 table-><a class="code" href="structDBusHashTable.html#m7">down_shift</a>, 01053 table-><a class="code" href="structDBusHashTable.html#m8">mask</a>); 01054 <font class="preprocessor">#endif</font> 01055 <font class="preprocessor"></font> 01056 _dbus_assert (table-><a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a> >= 0); 01057 _dbus_assert (table-><a class="code" href="structDBusHashTable.html#m5">hi_rebuild_size</a> > table-><a class="code" href="structDBusHashTable.html#m6">lo_rebuild_size</a>); 01058 _dbus_assert (table-><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-><a class="code" href="structDBusHashTable.html#m8">mask</a> < table-><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 > 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-><a class="code" href="structDBusHashEntry.html#m0">next</a>; 01074 <font class="keywordflow">switch</font> (table-><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-><a class="code" href="structDBusHashEntry.html#m1">key</a>) & table-><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-><a class="code" href="structDBusHashEntry.html#m1">key</a>) & table-><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-><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 = &(table-><a class="code" href="structDBusHashTable.html#m1">buckets</a>[idx]); 01094 entry-><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-><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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_STRING); 01121 01122 entry = (* table-><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-><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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_TWO_STRINGS); 01146 01147 entry = (* table-><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-><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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_INT); 01171 01172 entry = (* table-><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-><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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_POINTER); 01198 01199 entry = (* table-><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-><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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_ULONG); 01224 01225 entry = (* table-><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-><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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_STRING); 01249 01250 entry = (* table-><a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, (<font class="keywordtype">char</font>*) key, FALSE, &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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_TWO_STRINGS); 01277 01278 entry = (* table-><a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, (<font class="keywordtype">char</font>*) key, FALSE, &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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_INT); 01305 01306 entry = (* table-><a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, _DBUS_INT_TO_POINTER (key), FALSE, &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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_POINTER); 01335 01336 entry = (* table-><a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, key, FALSE, &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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_ULONG); 01364 01365 entry = (* table-><a class="code" href="structDBusHashTable.html#m10">find_function</a>) (table, (<font class="keywordtype">void</font>*) key, FALSE, &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-><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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_TWO_STRINGS); 01433 01434 entry = (* table-><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-><a class="code" href="structDBusHashTable.html#m11">free_key_function</a> && entry-><a class="code" href="structDBusHashEntry.html#m1">key</a> != key) 01440 (* table-><a class="code" href="structDBusHashTable.html#m11">free_key_function</a>) (entry-><a class="code" href="structDBusHashEntry.html#m1">key</a>); 01441 01442 <font class="keywordflow">if</font> (table-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a> && entry-><a class="code" href="structDBusHashEntry.html#m2">value</a> != value) 01443 (* table-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (entry-><a class="code" href="structDBusHashEntry.html#m2">value</a>); 01444 01445 entry-><a class="code" href="structDBusHashEntry.html#m1">key</a> = key; 01446 entry-><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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_INT); 01474 01475 entry = (* table-><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-><a class="code" href="structDBusHashTable.html#m11">free_key_function</a> && entry-><a class="code" href="structDBusHashEntry.html#m1">key</a> != _DBUS_INT_TO_POINTER (key)) 01481 (* table-><a class="code" href="structDBusHashTable.html#m11">free_key_function</a>) (entry-><a class="code" href="structDBusHashEntry.html#m1">key</a>); 01482 01483 <font class="keywordflow">if</font> (table-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a> && entry-><a class="code" href="structDBusHashEntry.html#m2">value</a> != value) 01484 (* table-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (entry-><a class="code" href="structDBusHashEntry.html#m2">value</a>); 01485 01486 entry-><a class="code" href="structDBusHashEntry.html#m1">key</a> = _DBUS_INT_TO_POINTER (key); 01487 entry-><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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_POINTER); 01517 01518 entry = (* table-><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-><a class="code" href="structDBusHashTable.html#m11">free_key_function</a> && entry-><a class="code" href="structDBusHashEntry.html#m1">key</a> != key) 01524 (* table-><a class="code" href="structDBusHashTable.html#m11">free_key_function</a>) (entry-><a class="code" href="structDBusHashEntry.html#m1">key</a>); 01525 01526 <font class="keywordflow">if</font> (table-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a> && entry-><a class="code" href="structDBusHashEntry.html#m2">value</a> != value) 01527 (* table-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (entry-><a class="code" href="structDBusHashEntry.html#m2">value</a>); 01528 01529 entry-><a class="code" href="structDBusHashEntry.html#m1">key</a> = key; 01530 entry-><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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_ULONG); 01559 01560 entry = (* table-><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-><a class="code" href="structDBusHashTable.html#m11">free_key_function</a> && entry-><a class="code" href="structDBusHashEntry.html#m1">key</a> != (<font class="keywordtype">void</font>*) key) 01566 (* table-><a class="code" href="structDBusHashTable.html#m11">free_key_function</a>) (entry-><a class="code" href="structDBusHashEntry.html#m1">key</a>); 01567 01568 <font class="keywordflow">if</font> (table-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a> && entry-><a class="code" href="structDBusHashEntry.html#m2">value</a> != value) 01569 (* table-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (entry-><a class="code" href="structDBusHashEntry.html#m2">value</a>); 01570 01571 entry-><a class="code" href="structDBusHashEntry.html#m1">key</a> = (<font class="keywordtype">void</font>*) key; 01572 entry-><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-><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-><a class="code" href="structDBusHashTable.html#m9">key_type</a> == DBUS_HASH_STRING); 01637 _dbus_assert (preallocated != NULL); 01638 01639 entry = (* table-><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-><a class="code" href="structDBusHashTable.html#m11">free_key_function</a> && entry-><a class="code" href="structDBusHashEntry.html#m1">key</a> != key) 01644 (* table-><a class="code" href="structDBusHashTable.html#m11">free_key_function</a>) (entry-><a class="code" href="structDBusHashEntry.html#m1">key</a>); 01645 01646 <font class="keywordflow">if</font> (table-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a> && entry-><a class="code" href="structDBusHashEntry.html#m2">value</a> != value) 01647 (* table-><a class="code" href="structDBusHashTable.html#m12">free_value_function</a>) (entry-><a class="code" href="structDBusHashEntry.html#m2">value</a>); 01648 01649 entry-><a class="code" href="structDBusHashEntry.html#m1">key</a> = key; 01650 entry-><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-><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 <stdio.h></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, &iter); 01683 <font class="keywordflow">while</font> (_dbus_hash_iter_next (&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 < 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 < 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 < 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 >= 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 < 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, &iter); 01934 <font class="keywordflow">while</font> (_dbus_hash_iter_next (&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 (&iter); 01940 value = _dbus_hash_iter_get_value (&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 (&iter, value); 01949 01950 _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value); 01951 } 01952 01953 _dbus_hash_iter_init (table1, &iter); 01954 <font class="keywordflow">while</font> (_dbus_hash_iter_next (&iter)) 01955 { 01956 _dbus_hash_iter_remove_entry (&iter); 01957 _dbus_assert (count_entries (table1) == i - 1); 01958 --i; 01959 } 01960 01961 _dbus_hash_iter_init (table2, &iter); 01962 <font class="keywordflow">while</font> (_dbus_hash_iter_next (&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 (&iter); 01968 value = _dbus_hash_iter_get_value (&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 (&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, &iter); 01983 <font class="keywordflow">while</font> (_dbus_hash_iter_next (&iter)) 01984 { 01985 _dbus_hash_iter_remove_entry (&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 < 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 >= 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 < 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, &iter)) 02075 <font class="keywordflow">goto</font> out; 02076 _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL); 02077 _dbus_hash_iter_set_value (&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, &iter)) 02085 <font class="keywordflow">goto</font> out; 02086 _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL); 02087 _dbus_hash_iter_set_value (&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, &iter)) 02093 <font class="keywordflow">goto</font> out; 02094 02095 value = _dbus_hash_iter_get_value (&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 (&iter)) 02103 ; 02104 02105 <font class="keywordflow">if</font> (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter)) 02106 <font class="keywordflow">goto</font> out; 02107 02108 value = _dbus_hash_iter_get_value (&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 (&iter)) 02116 ; 02117 02118 ++i; 02119 } 02120 02121 --i; 02122 <font class="keywordflow">while</font> (i >= 0) 02123 { 02124 <font class="keywordflow">if</font> (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter)) 02125 _dbus_assert_not_reached (<font class="stringliteral">"hash entry should have existed"</font>); 02126 _dbus_hash_iter_remove_entry (&iter); 02127 02128 <font class="keywordflow">if</font> (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter)) 02129 _dbus_assert_not_reached (<font class="stringliteral">"hash entry should have existed"</font>); 02130 _dbus_hash_iter_remove_entry (&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 < 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>