undns 0.4.0a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,48 @@
1
+ /*
2
+ * Copyright (c) 2002
3
+ * Neil Spring and the University of Washington.
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions
8
+ * are met:
9
+ * 1. Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * 3. The name of the author(s) may not be used to endorse or promote
15
+ * products derived from this software without specific prior
16
+ * written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
19
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
22
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ */
29
+
30
+ #ifndef _hashes_h
31
+ #define _hashes_h
32
+ #include <sys/types.h>
33
+ #include <netinet/in.h>
34
+ typedef char *hash_cptr;
35
+ unsigned int mac_hash(const void *key);
36
+ unsigned int ip_hash(const void *key); // treats void * as u_int *
37
+ unsigned int port_hash(const void *key); // treats void * as u_int
38
+ unsigned int string_hash(const char *key);
39
+ unsigned int pstring_hash(const hash_cptr *key);
40
+ unsigned int sockaddr_in_hash(const struct sockaddr_in *v);
41
+
42
+ boolean mac_isequal(const void *v1, const void *v2);
43
+ boolean ip_isequal(const void *v1, const void *v2);
44
+ boolean port_isequal(const void *key1, const void *key2);
45
+ boolean string_isequal(const char *string1, const char *string2);
46
+ boolean pstring_isequal(const hash_cptr *string1, const hash_cptr *string2);
47
+ boolean sockaddr_in_isequal(const struct sockaddr_in *v1, const struct sockaddr_in *v2);
48
+ #endif
@@ -0,0 +1,518 @@
1
+ /*
2
+ * Copyright (c) 2002
3
+ * Neil Spring and the University of Washington.
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions
8
+ * are met:
9
+ * 1. Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * 3. The name of the author(s) may not be used to endorse or promote
15
+ * products derived from this software without specific prior
16
+ * written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
19
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
22
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ */
29
+
30
+ #ifdef HAVE_CONFIG_H
31
+ #include <config.h>
32
+ #endif
33
+ #ifdef HAVE_LIBPTHREAD
34
+ #include <pthread.h>
35
+ int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind); // grr...
36
+ #else
37
+ // typedef void *pthread_mutex_t;
38
+ #define pthread_mutex_lock(x) (0)
39
+ #define pthread_mutex_unlock(x) (0)
40
+ #define pthread_mutex_init(x,y) (0)
41
+ #define pthread_mutexattr_init(x,y) (0)
42
+ #define pthread_mutexattr_setkind_np(x,y) (0)
43
+ #define pthread_mutexattr_destroy(x,y) (0)
44
+ #define pthread_mutex_destroy(x) (0)
45
+ #endif
46
+ #include <stdlib.h>
47
+ #include <string.h>
48
+ #include <assert.h>
49
+ #include <stdio.h>
50
+ #include "hashtable.h"
51
+ #include "progress.h"
52
+ #ifdef WITH_DMALLOC
53
+ #include <dmalloc.h>
54
+ #endif
55
+
56
+ typedef struct hashentry_struct {
57
+ struct hashentry_struct *next;
58
+ unsigned int hashkey;
59
+ const void *keyval;
60
+ } hashentry;
61
+
62
+ struct hashtable_struct {
63
+ hashentry **table;
64
+ unsigned int table_size;
65
+ unsigned int (*hash)(const void *key);
66
+ boolean (*isequal)(const void *key1, const void *key2);
67
+ /*@null@*/ void (*free_keyval)(void *key);
68
+ #ifdef _REENTRANT
69
+ pthread_mutex_t mutex;
70
+ #endif
71
+ };
72
+
73
+ hashtable ht_new(unsigned int size,
74
+ unsigned int (*hash)(const void *key),
75
+ boolean (*isequal)(const void *key1,
76
+ const void *key2),
77
+ /*@null@*/ void (*free_keyval)(void *key)) {
78
+ hashtable ht = malloc(sizeof(struct hashtable_struct));
79
+ #ifdef _REENTRANT
80
+ pthread_mutexattr_t attrib;
81
+ #endif
82
+ assert(ht!=NULL);
83
+ ht->table = (hashentry **)malloc(sizeof(hashentry *)*size);
84
+ assert(ht->table!=NULL);
85
+ memset(ht->table, 0, size * sizeof(hashentry *));
86
+ ht->table_size = size;
87
+ ht->hash = hash;
88
+ ht->isequal = isequal;
89
+ ht->free_keyval = free_keyval;
90
+ #ifdef _REENTRANT
91
+ #ifdef PTHREAD_MUTEX_RECURSIVE_NP
92
+ (void)pthread_mutexattr_init(&attrib);
93
+ // (void)pthread_mutexattr_setkind_np(&attrib, PTHREAD_MUTEX_RECURSIVE_NP);
94
+ // (void)pthread_mutexattr_setkind(&attrib, PTHREAD_MUTEX_RECURSIVE_NP);
95
+ (void)pthread_mutexattr_settype(&attrib, PTHREAD_MUTEX_RECURSIVE_NP);
96
+ (void)pthread_mutex_init(&ht->mutex, &attrib);
97
+ (void)pthread_mutexattr_destroy(&attrib);
98
+ #endif
99
+ #endif
100
+ return(ht);
101
+ }
102
+
103
+ #ifdef _REENTRANT
104
+ #define LOCK assert(pthread_mutex_lock(&ht->mutex)==0)
105
+ #define UNLOCK assert(pthread_mutex_unlock(&ht->mutex)==0)
106
+ #else
107
+ #define LOCK do { } while(0)
108
+ #define UNLOCK do { } while(0)
109
+ #endif
110
+
111
+ void ht_insert(hashtable ht, const void *keyval) {
112
+ hashentry *he;
113
+ assert(ht!=NULL);
114
+ he = malloc_ordie(sizeof(hashentry));
115
+ he->hashkey = ht->hash(keyval);
116
+ he->keyval = keyval;
117
+ LOCK;
118
+ he->next = ht->table[he->hashkey%ht->table_size];
119
+ ht->table[he->hashkey%ht->table_size] = he;
120
+ UNLOCK;
121
+ }
122
+
123
+ void ht_free_entry(hashtable ht, const void *keyval) {
124
+ if(ht->free_keyval!= NULL)
125
+ ht->free_keyval((void *)keyval);
126
+ }
127
+
128
+ void ht_delete(/*@only@*/ hashtable ht, boolean show_progress) {
129
+ unsigned int i;
130
+ if(show_progress) {
131
+ progress_label("ht_delete");
132
+ progress_reset();
133
+ }
134
+ LOCK;
135
+ for(i=0; i<ht->table_size; i++) {
136
+ hashentry *he = ht->table[i];
137
+ hashentry *prvhe;
138
+ if(show_progress && (i % 100)==0)
139
+ progress((float)i / (float)ht->table_size);
140
+ while(he) {
141
+ /* remove from the list */
142
+ prvhe = he;
143
+ he=he->next;
144
+ /* then free the data -- avoiding dodgy free-calls-remove cycles. */
145
+ ht_free_entry(ht, prvhe->keyval);
146
+ free(prvhe);
147
+ }
148
+ }
149
+ UNLOCK;
150
+ if(show_progress)
151
+ progress(1.0);
152
+ free(ht->table);
153
+ free(ht);
154
+ }
155
+
156
+ /* returns true if found and removed */
157
+ /* returns false if not there */
158
+ /* does not free, regardless of the value of
159
+ ht->free_keyval, invoked only when deleting. */
160
+ boolean ht_remove(hashtable ht, const void *key) {
161
+ unsigned int hkey;
162
+ hashentry *he, *prehe;
163
+ assert(ht!=NULL);
164
+ hkey = ht->hash(key);
165
+ prehe = NULL;
166
+ LOCK;
167
+ he = ht->table[hkey%ht->table_size];
168
+ while(he!=NULL) {
169
+ if(he->hashkey == hkey && ht->isequal(he->keyval,key)) {
170
+ if(prehe != NULL) {
171
+ prehe->next = he->next;
172
+ } else {
173
+ ht->table[hkey%ht->table_size] = he->next;
174
+ }
175
+ UNLOCK;
176
+ free(he);
177
+ return TRUE;
178
+ }
179
+ prehe = he;
180
+ he = he->next;
181
+ }
182
+ UNLOCK;
183
+ return FALSE;
184
+ }
185
+
186
+ void *ht_lookup(hashtable ht,
187
+ const void *key) {
188
+ unsigned int hkey;
189
+ hashentry *he;
190
+ assert(ht!=NULL);
191
+ hkey = ht->hash(key);
192
+ LOCK;
193
+ he = ht->table[hkey%ht->table_size];
194
+ while(he!=NULL) {
195
+ if(he->hashkey == hkey && ht->isequal(he->keyval,key)) {
196
+ UNLOCK;
197
+ return((void *)he->keyval);
198
+ }
199
+ he = he->next;
200
+ }
201
+ UNLOCK;
202
+ return NULL;
203
+ }
204
+
205
+ /*@dependent@*/
206
+ void *ht_lookup_nofail(hashtable ht,
207
+ const void *key,
208
+ ht_constructor_cb constructor) {
209
+ void *ret = ht_lookup(ht, key);
210
+ if(ret == NULL) {
211
+ ret = constructor(key);
212
+ if(ret != NULL) {
213
+ ht_insert(ht,ret);
214
+ }
215
+ }
216
+ return(ret);
217
+ }
218
+
219
+ typedef struct ht_iterate_pairs_pthread_struct {
220
+ hashtable ht;
221
+ unsigned int nThreads;
222
+ unsigned int chunkSize;
223
+ boolean (*callback)(const void *keyval, const void *keyval2);
224
+ int threadId;
225
+ } ht_iterate_pairs_pthread_struct;
226
+
227
+ static int ht_iterate_pairs_advance(unsigned int * istart,unsigned int *iend,unsigned int *jstart,unsigned int *jend,unsigned int tablesize,unsigned int chunksize);
228
+
229
+ static int ht_iterate_pairs_advance_k(unsigned int * istart, unsigned int *iend, unsigned int *jstart,unsigned int *jend, unsigned int tablesize, unsigned int chunksize,int k)
230
+ {
231
+ int i;
232
+ for(i=0;i<k;i++)
233
+ if( ht_iterate_pairs_advance(istart,iend,jstart,jend,tablesize,chunksize))
234
+ return 1;
235
+ return 0;
236
+ }
237
+ void * ht_iterate_pairs_pthreadstub(void * args )
238
+ //hashtable ht, int nThreads, int chunkSize,
239
+ // boolean (*callback)(const void *keyval, const void *keyval2)) {
240
+ {
241
+
242
+ ht_iterate_pairs_pthread_struct *data = (ht_iterate_pairs_pthread_struct*)args;
243
+ unsigned int i,j;
244
+ unsigned int istart, jstart;
245
+ unsigned int iend,jend;
246
+ hashtable ht;
247
+ boolean (*callback)(const void *keyval, const void *keyval2) = data->callback;
248
+ istart=jstart=0;
249
+ ht = data->ht;
250
+ iend=min(istart+data->chunkSize,ht->table_size);
251
+ jend=min(jstart+data->chunkSize,ht->table_size);
252
+ // fprintf(stderr,"hello from thread %d\n", data->threadId);
253
+ if(!ht_iterate_pairs_advance_k(&istart,&iend,&jstart,&jend,ht->table_size,data->chunkSize,data->threadId)) {
254
+ do {
255
+ assert(istart < iend);
256
+ assert(jstart < jend);
257
+ // fprintf(stderr,"thread %d: i=%d to %d; j=%d to %d\n", data->threadId, istart, iend, jstart, jend);
258
+ for(i=istart; i<iend ; i++) {
259
+ hashentry *he1 = ht->table[i];
260
+ while(he1 ) {
261
+ // fprintf(stderr,"thread %d: i=%d, j=%d to %d\n", data->threadId, i, jstart, min(i,jend));
262
+ for(j=jstart; j<min(i+1,jend) ; j++) {
263
+ hashentry *he2 = (i==j) ? he1->next : ht->table[j];
264
+ while(he2 ) {
265
+ callback(he1->keyval, he2->keyval);
266
+ he2=he2->next;
267
+ }
268
+ }
269
+ he1=he1->next;
270
+ }
271
+ }
272
+ assert(istart < iend);
273
+ assert(jstart < jend);
274
+ } while(!ht_iterate_pairs_advance_k(&istart,&iend,&jstart,&jend,ht->table_size,data->chunkSize,data->nThreads));
275
+ }
276
+ free(args);
277
+ return NULL;
278
+ }
279
+ #ifdef _REENTRANT
280
+
281
+ boolean ht_iterate_pairs(hashtable ht, unsigned int nThreads, unsigned int chunkSize,
282
+ boolean (*callback)(const void *keyval, const void *keyval2)) {
283
+ unsigned int threadId;
284
+ pthread_t * threads;
285
+ void * ignore;
286
+ int err;
287
+
288
+ if(ht == NULL) return FALSE;
289
+ ht_iterate_pairs_pthread_struct * data;
290
+ assert(nThreads<100);
291
+ assert(chunkSize < ht->table_size);
292
+
293
+ threads = malloc(sizeof(pthread_t) * nThreads);
294
+ assert(threads);
295
+ for(threadId=0; threadId<nThreads; threadId++)
296
+ {
297
+ data = (ht_iterate_pairs_pthread_struct * ) malloc(sizeof(ht_iterate_pairs_pthread_struct));
298
+ assert(data);
299
+ data->ht=ht;
300
+ data->nThreads=nThreads;
301
+ data->chunkSize=chunkSize;
302
+ data->callback=callback;
303
+ data->threadId=threadId;
304
+ err = pthread_create(&threads[threadId],NULL,ht_iterate_pairs_pthreadstub,(void *)data);
305
+ assert(!err);
306
+ }
307
+ for(threadId=0; threadId<nThreads; threadId++)
308
+ pthread_join(threads[threadId], &ignore);
309
+
310
+ return TRUE;
311
+ }
312
+
313
+ #else
314
+ boolean ht_iterate_pairs(hashtable ht, unsigned int nThreads, unsigned int chunkSize,
315
+ boolean (*callback)(const void *keyval, const void *keyval2)) {
316
+ unsigned int threadId;
317
+ /* probably should make nThreads be 1 or abort if not 1.... */
318
+ if(ht == NULL) return FALSE;
319
+ ht_iterate_pairs_pthread_struct * data;
320
+ assert(nThreads<100);
321
+ assert(chunkSize < ht->table_size);
322
+
323
+ for(threadId=0; threadId<nThreads; threadId++)
324
+ {
325
+ data = (ht_iterate_pairs_pthread_struct * ) malloc(sizeof(ht_iterate_pairs_pthread_struct));
326
+ assert(data);
327
+ data->ht=ht;
328
+ data->nThreads=nThreads;
329
+ data->chunkSize=chunkSize;
330
+ data->callback=callback;
331
+ data->threadId=threadId;
332
+ ht_iterate_pairs_pthreadstub(data);
333
+ }
334
+ return TRUE;
335
+ }
336
+
337
+ #endif
338
+ static int ht_iterate_pairs_advance(unsigned int * istart,unsigned int *iend,unsigned int *jstart,unsigned int *jend,unsigned int tablesize, unsigned int chunksize)
339
+ {
340
+ *jstart=*jend;
341
+ *jend=min(*jend+chunksize,*iend);
342
+ if( *jstart >= *iend )
343
+ {
344
+ *istart=*iend;
345
+ *iend=min(*iend+chunksize,tablesize);
346
+ *jstart=0;
347
+ *jend=chunksize;
348
+ if(*istart >= tablesize)
349
+ return 1; // done scanning
350
+ }
351
+ assert(*istart < *iend);
352
+ if(! (*jstart < *jend)) {
353
+ fprintf(stderr, "new jstart = %d, jend = %d\n", *jstart, *jend);
354
+ abort();
355
+ }
356
+ return 0;
357
+ }
358
+
359
+
360
+ boolean ht_iterate(hashtable ht,
361
+ boolean (*callback)(const void *keyval, void *user),
362
+ void *user) {
363
+ unsigned int i;
364
+ boolean cont = TRUE;
365
+ if(ht == NULL) return FALSE;
366
+ LOCK;
367
+ for(i=0; i<ht->table_size && cont; i++) {
368
+ hashentry *he = ht->table[i];
369
+ while(he && cont) {
370
+ cont = callback(he->keyval, user);
371
+ he=he->next;
372
+ }
373
+ }
374
+ UNLOCK;
375
+ return cont;
376
+ }
377
+
378
+ boolean ht_iterate_nc(hashtable ht,
379
+ boolean (*callback)(void *keyval, void *user),
380
+ void *user) {
381
+ unsigned int i;
382
+ boolean cont = TRUE;
383
+ if(ht == NULL) return FALSE;
384
+ LOCK;
385
+ for(i=0; i<ht->table_size && cont; i++) {
386
+ hashentry *he = ht->table[i];
387
+ while(he && cont) {
388
+ cont = callback((void *) (he->keyval), user);
389
+ he=he->next;
390
+ }
391
+ }
392
+ UNLOCK;
393
+ return cont;
394
+ }
395
+
396
+ unsigned int ht_delete_if(hashtable ht,
397
+ ht_delete_if_cb callback,
398
+ void *user) {
399
+ unsigned int i;
400
+ unsigned int count = 0;
401
+ if(ht == NULL) return FALSE;
402
+ LOCK;
403
+ for(i=0; i<ht->table_size; i++) {
404
+ hashentry *he = ht->table[i];
405
+ hashentry *prehe = NULL;
406
+ while(he != NULL) {
407
+ if(callback((void *)he->keyval, user)) {
408
+ if(prehe != NULL) {
409
+ prehe->next = he->next;
410
+ free(he); count++;
411
+ he = prehe->next;
412
+ } else {
413
+ ht->table[i] = he->next;
414
+ free(he); count++;
415
+ he = ht->table[i];
416
+ }
417
+ } else {
418
+ prehe = he;
419
+ he=he->next;
420
+ }
421
+ }
422
+ }
423
+ UNLOCK;
424
+ return count;
425
+ }
426
+
427
+
428
+ void ht_occupancyjgr(const hashtable ht, const char *fname) {
429
+ unsigned int i;
430
+ int hist[101];
431
+ FILE *fp;
432
+ fp=fopen(fname,"w");
433
+ if(fp != NULL) {
434
+ memset(hist,0,sizeof(hist));
435
+ for(i=0;i<ht->table_size; i++) {
436
+ const hashentry *he = ht->table[i];
437
+ int c;
438
+ for(c=0; he!= NULL; he=he->next, c++);
439
+ hist[min(c,100)] ++;
440
+ }
441
+ fprintf(fp, "newgraph xaxis label : length of chain\n"
442
+ "yaxis label : number of chains\n"
443
+ "newcurve pts\n");
444
+ for(i=0;i<=100;i++) {
445
+ fprintf(fp, "%u %d\n", i, hist[i]);
446
+ }
447
+ fclose(fp);
448
+ }
449
+ }
450
+
451
+ unsigned int hash_8byte(const void *k) {
452
+ unsigned int a = *(const unsigned int *)k;
453
+ unsigned int b = *(const unsigned int *)k+1;
454
+ return(a*b);
455
+ }
456
+ boolean isequal_8byte(const void *ia, const void *ib) {
457
+ int a = *(int *)ia, b = *(int*)ib;
458
+ int a2 = *((int *)ia+1), b2 = *((int*)ib+1);
459
+ return(a==b && a2==b2);
460
+ }
461
+
462
+ unsigned int hash_k_int(const int *k) {
463
+ return(*k);
464
+ }
465
+ unsigned int hash_int(const void *k) {
466
+ return(hash_k_int((const int *)k));
467
+ }
468
+
469
+ boolean isequal_k_int(const int *a, const int *b) {
470
+ return((*a)==(*b));
471
+ }
472
+
473
+ boolean isequal_int(const void *ia, const void *ib) {
474
+ return(isequal_k_int((const int *)ia, (const int*)ib));
475
+ }
476
+
477
+ unsigned int hash_ushort(const void *k) {
478
+ unsigned short a = *(const unsigned short *)k;
479
+ return(a);
480
+ }
481
+
482
+ boolean isequal_ushort(const void *ia, const void *ib) {
483
+ unsigned short a = *(const unsigned short *)ia;
484
+ unsigned short b = *(const unsigned short *)ib;
485
+ return(a==b);
486
+ }
487
+
488
+ #include <sys/types.h>
489
+ #include <netinet/in.h>
490
+ unsigned int hash_k_saddr(const struct in_addr *k) {
491
+ return(k->s_addr);
492
+ }
493
+ boolean isequal_k_saddr(const struct in_addr *a, const struct in_addr *b) {
494
+ return(a->s_addr==b->s_addr);
495
+ }
496
+
497
+ unsigned int hash_k_uint(const unsigned int *k) {
498
+ return(*k);
499
+ }
500
+ boolean isequal_k_uint(const unsigned int *a, const unsigned int *b) {
501
+ return((*a)==(*b));
502
+ }
503
+
504
+ static boolean counter(const void *v __attribute__ ((unused)),
505
+ void *count) {
506
+ (*(unsigned long *)count)++;
507
+ assert((*(unsigned long *)count) < 200000);
508
+ return TRUE;
509
+ }
510
+ unsigned long ht_count(hashtable ht) {
511
+ unsigned long count=0;
512
+ if(ht!=NULL)
513
+ (void)ht_iterate(ht, counter, &count);
514
+ return count;
515
+ }
516
+
517
+
518
+