undns 0.4.0a
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/undns_decode +29 -0
- data/ext/undns/buffer.c +247 -0
- data/ext/undns/buffer.h +59 -0
- data/ext/undns/config.h +2 -0
- data/ext/undns/conventions.c +1813 -0
- data/ext/undns/conventions.h +89 -0
- data/ext/undns/conventlex.c +2808 -0
- data/ext/undns/earth.c +180 -0
- data/ext/undns/earth.h +4 -0
- data/ext/undns/exception.h +12 -0
- data/ext/undns/extconf.rb +44 -0
- data/ext/undns/filetest.c +90 -0
- data/ext/undns/filetest.h +7 -0
- data/ext/undns/hashes.c +104 -0
- data/ext/undns/hashes.h +48 -0
- data/ext/undns/hashtable.c +518 -0
- data/ext/undns/hashtable.h +103 -0
- data/ext/undns/my_ruby.h +3 -0
- data/ext/undns/nscommon.h +207 -0
- data/ext/undns/originAS.c +134 -0
- data/ext/undns/originAS.h +17 -0
- data/ext/undns/progress.c +285 -0
- data/ext/undns/progress.h +45 -0
- data/ext/undns/queue.c +346 -0
- data/ext/undns/queue.h +70 -0
- data/ext/undns/radix.c +517 -0
- data/ext/undns/radix.h +72 -0
- data/ext/undns/ruleset.c +603 -0
- data/ext/undns/ruleset.h +108 -0
- data/ext/undns/swig-undns_wrap-rb.c +2995 -0
- data/ext/undns/typed_hashtable.h +158 -0
- data/ext/undns/typed_queue.h +112 -0
- data/ext/undns/xmalloc.c +153 -0
- data/ext/undns/xmalloc.h +14 -0
- data/lib/undns.rb +5 -0
- metadata +84 -0
data/ext/undns/hashes.h
ADDED
@@ -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
|
+
|