1 /* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
4 #include "hashtable_itr.h"
7 #include <string.h> /* for memcmp */
9 static const int ITEM_COUNT
= 4000;
11 typedef unsigned int uint32_t;
12 typedef unsigned short uint16_t;
14 /*****************************************************************************/
17 uint32_t one_ip
; uint32_t two_ip
; uint16_t one_port
; uint16_t two_port
;
25 DEFINE_HASHTABLE_INSERT(insert_some
, struct key
, struct value
);
26 DEFINE_HASHTABLE_SEARCH(search_some
, struct key
, struct value
);
27 DEFINE_HASHTABLE_REMOVE(remove_some
, struct key
, struct value
);
28 DEFINE_HASHTABLE_ITERATOR_SEARCH(search_itr_some
, struct key
);
31 /*****************************************************************************/
35 struct key
*k
= (struct key
*)ky
;
36 return (((k
->one_ip
<< 17) | (k
->one_ip
>> 15)) ^ k
->two_ip
) +
37 (k
->one_port
* 17) + (k
->two_port
* 13 * 29);
41 equalkeys(void *k1
, void *k2
)
43 return (0 == memcmp(k1
,k2
,sizeof(struct key
)));
46 /*****************************************************************************/
48 main(int argc
, char **argv
)
51 struct value
*v
, *found
;
53 struct hashtable_itr itr
;
56 h
= create_hashtable(16, hashfromkey
, equalkeys
);
57 if (NULL
== h
) exit(-1); /*oom*/
60 /*****************************************************************************/
62 for (i
= 0; i
< ITEM_COUNT
; i
++)
64 k
= (struct key
*)malloc(sizeof(struct key
));
66 printf("ran out of memory allocating a key\n");
69 k
->one_ip
= 0xcfccee40 + i
;
70 k
->two_ip
= 0xcf0cee67 - (5 * i
);
71 k
->one_port
= 22 + (7 * i
);
72 k
->two_port
= 5522 - (3 * i
);
74 v
= (struct value
*)malloc(sizeof(struct value
));
77 if (!insert_some(h
,k
,v
)) exit(-1); /*oom*/
79 printf("After insertion, hashtable contains %u items.\n",
82 /*****************************************************************************/
83 /* Hashtable search */
84 k
= (struct key
*)malloc(sizeof(struct key
));
86 printf("ran out of memory allocating a key\n");
90 for (i
= 0; i
< ITEM_COUNT
; i
++)
92 k
->one_ip
= 0xcfccee40 + i
;
93 k
->two_ip
= 0xcf0cee67 - (5 * i
);
94 k
->one_port
= 22 + (7 * i
);
95 k
->two_port
= 5522 - (3 * i
);
97 if (NULL
== (found
= search_some(h
,k
))) {
98 printf("BUG: key not found\n");
102 /*****************************************************************************/
103 /* Hashtable iteration */
104 /* Iterator constructor only returns a valid iterator if
105 * the hashtable is not empty */
106 hashtable_iterator_init(&itr
, h
);
108 if (hashtable_count(h
) > 0)
111 kk
= hashtable_iterator_key(&itr
);
112 v
= hashtable_iterator_value(&itr
);
113 /* here (kk,v) are a valid (key, value) pair */
114 /* We could call 'hashtable_remove(h,kk)' - and this operation
115 * 'free's kk. However, the iterator is then broken.
116 * This is why hashtable_iterator_remove exists - see below.
120 } while (hashtable_iterator_advance(&itr
));
122 printf("Iterated through %u entries.\n", i
);
124 /*****************************************************************************/
125 /* Hashtable iterator search */
127 /* Try the search some method */
128 for (i
= 0; i
< ITEM_COUNT
; i
++)
130 k
->one_ip
= 0xcfccee40 + i
;
131 k
->two_ip
= 0xcf0cee67 - (5 * i
);
132 k
->one_port
= 22 + (7 * i
);
133 k
->two_port
= 5522 - (3 * i
);
135 if (0 == search_itr_some(&itr
,h
,k
)) {
136 printf("BUG: key not found searching with iterator");
140 /*****************************************************************************/
141 /* Hashtable removal */
143 for (i
= 0; i
< ITEM_COUNT
; i
++)
145 k
->one_ip
= 0xcfccee40 + i
;
146 k
->two_ip
= 0xcf0cee67 - (5 * i
);
147 k
->one_port
= 22 + (7 * i
);
148 k
->two_port
= 5522 - (3 * i
);
150 if (NULL
== (found
= remove_some(h
,k
))) {
151 printf("BUG: key not found for removal\n");
154 printf("After removal, hashtable contains %u items.\n",
157 /*****************************************************************************/
158 /* Hashtable destroy and create */
160 hashtable_destroy(h
, 1);
164 h
= create_hashtable(160, hashfromkey
, equalkeys
);
166 printf("out of memory allocating second hashtable\n");
170 /*****************************************************************************/
171 /* Hashtable insertion */
173 for (i
= 0; i
< ITEM_COUNT
; i
++)
175 k
= (struct key
*)malloc(sizeof(struct key
));
176 k
->one_ip
= 0xcfccee40 + i
;
177 k
->two_ip
= 0xcf0cee67 - (5 * i
);
178 k
->one_port
= 22 + (7 * i
);
179 k
->two_port
= 5522 - (3 * i
);
181 v
= (struct value
*)malloc(sizeof(struct value
));
184 if (!insert_some(h
,k
,v
))
186 printf("out of memory inserting into second hashtable\n");
190 printf("After insertion, hashtable contains %u items.\n",
193 /*****************************************************************************/
194 /* Hashtable iterator search and iterator remove */
196 k
= (struct key
*)malloc(sizeof(struct key
));
198 printf("ran out of memory allocating a key\n");
202 for (i
= ITEM_COUNT
- 1; i
>= 0; i
= i
- 7)
204 k
->one_ip
= 0xcfccee40 + i
;
205 k
->two_ip
= 0xcf0cee67 - (5 * i
);
206 k
->one_port
= 22 + (7 * i
);
207 k
->two_port
= 5522 - (3 * i
);
209 if (0 == search_itr_some(&itr
, h
, k
)) {
210 printf("BUG: key %u not found for search preremoval using iterator\n", i
);
213 if (0 == hashtable_iterator_remove(&itr
)) {
214 printf("BUG: key not found for removal using iterator\n");
219 /*****************************************************************************/
220 /* Hashtable iterator remove and advance */
222 for (hashtable_iterator_init(&itr
, h
);
223 hashtable_iterator_remove(&itr
) != 0; ) {
226 printf("After removal, hashtable contains %u items.\n",
229 /*****************************************************************************/
230 /* Hashtable destroy */
232 hashtable_destroy(h
, 1);
238 * Copyright (c) 2002, 2004, Christopher Clark
239 * All rights reserved.
241 * Redistribution and use in source and binary forms, with or without
242 * modification, are permitted provided that the following conditions
245 * * Redistributions of source code must retain the above copyright
246 * notice, this list of conditions and the following disclaimer.
248 * * Redistributions in binary form must reproduce the above copyright
249 * notice, this list of conditions and the following disclaimer in the
250 * documentation and/or other materials provided with the distribution.
252 * * Neither the name of the original author; nor the names of any contributors
253 * may be used to endorse or promote products derived from this software
254 * without specific prior written permission.
257 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
258 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
259 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
260 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
261 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
262 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
263 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
264 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
265 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
266 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
267 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.