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.
- 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
|
+
|