rubysl-syck 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,576 @@
1
+ /* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */
2
+
3
+ /* static char sccsid[] = "@(#) st.c 5.1 89/12/14 Crucible"; */
4
+
5
+ #include "defines.h"
6
+ #include "ruby.h"
7
+
8
+ #include <stdio.h>
9
+ #ifdef HAVE_STDLIB_H
10
+ #include <stdlib.h>
11
+ #endif
12
+ #include <string.h>
13
+ #include "st.h"
14
+
15
+ typedef struct st_table_entry st_table_entry;
16
+
17
+ struct st_table_entry {
18
+ unsigned int hash;
19
+ st_data_t key;
20
+ st_data_t record;
21
+ st_table_entry *next;
22
+ };
23
+
24
+ #define ST_DEFAULT_MAX_DENSITY 5
25
+ #define ST_DEFAULT_INIT_TABLE_SIZE 11
26
+
27
+ /*
28
+ * DEFAULT_MAX_DENSITY is the default for the largest we allow the
29
+ * average number of items per bin before increasing the number of
30
+ * bins
31
+ *
32
+ * DEFAULT_INIT_TABLE_SIZE is the default for the number of bins
33
+ * allocated initially
34
+ *
35
+ */
36
+ static int numcmp(long, long);
37
+ static int numhash(long);
38
+ static struct st_hash_type type_numhash = {
39
+ numcmp,
40
+ numhash,
41
+ };
42
+
43
+ /* extern int strcmp(const char *, const char *); */
44
+ static int strhash(const char *);
45
+ static struct st_hash_type type_strhash = {
46
+ strcmp,
47
+ strhash,
48
+ };
49
+
50
+ static void rehash(st_table *);
51
+
52
+ #ifdef RUBY
53
+ #define malloc xmalloc
54
+ #define calloc xcalloc
55
+ #endif
56
+
57
+ #define alloc(type) (type*)malloc((unsigned)sizeof(type))
58
+ #define Calloc(n,s) (char*)calloc((n),(s))
59
+
60
+ #define EQUAL(table,x,y) ((x)==(y) || (*table->type->compare)((x),(y)) == 0)
61
+
62
+ #define do_hash(key,table) (unsigned int)(*(table)->type->hash)((key))
63
+ #define do_hash_bin(key,table) (do_hash(key, table)%(table)->num_bins)
64
+
65
+ /*
66
+ * MINSIZE is the minimum size of a dictionary.
67
+ */
68
+
69
+ #define MINSIZE 8
70
+
71
+ /*
72
+ Table of prime numbers 2^n+a, 2<=n<=30.
73
+ */
74
+ static long primes[] = {
75
+ 8 + 3,
76
+ 16 + 3,
77
+ 32 + 5,
78
+ 64 + 3,
79
+ 128 + 3,
80
+ 256 + 27,
81
+ 512 + 9,
82
+ 1024 + 9,
83
+ 2048 + 5,
84
+ 4096 + 3,
85
+ 8192 + 27,
86
+ 16384 + 43,
87
+ 32768 + 3,
88
+ 65536 + 45,
89
+ 131072 + 29,
90
+ 262144 + 3,
91
+ 524288 + 21,
92
+ 1048576 + 7,
93
+ 2097152 + 17,
94
+ 4194304 + 15,
95
+ 8388608 + 9,
96
+ 16777216 + 43,
97
+ 33554432 + 35,
98
+ 67108864 + 15,
99
+ 134217728 + 29,
100
+ 268435456 + 3,
101
+ 536870912 + 11,
102
+ 1073741824 + 85,
103
+ 0
104
+ };
105
+
106
+ static int
107
+ new_size(size)
108
+ int size;
109
+ {
110
+ int i;
111
+
112
+ #if 0
113
+ for (i=3; i<31; i++) {
114
+ if ((1<<i) > size) return 1<<i;
115
+ }
116
+ return -1;
117
+ #else
118
+ int newsize;
119
+
120
+ for (i = 0, newsize = MINSIZE;
121
+ i < sizeof(primes)/sizeof(primes[0]);
122
+ i++, newsize <<= 1)
123
+ {
124
+ if (newsize > size) return primes[i];
125
+ }
126
+ /* Ran out of polynomials */
127
+ return -1; /* should raise exception */
128
+ #endif
129
+ }
130
+
131
+ #ifdef HASH_LOG
132
+ static int collision = 0;
133
+ static int init_st = 0;
134
+
135
+ static void
136
+ stat_col()
137
+ {
138
+ FILE *f = fopen("/tmp/col", "w");
139
+ fprintf(f, "collision: %d\n", collision);
140
+ fclose(f);
141
+ }
142
+ #endif
143
+
144
+ st_table*
145
+ st_init_table_with_size(type, size)
146
+ struct st_hash_type *type;
147
+ int size;
148
+ {
149
+ st_table *tbl;
150
+
151
+ #ifdef HASH_LOG
152
+ if (init_st == 0) {
153
+ init_st = 1;
154
+ atexit(stat_col);
155
+ }
156
+ #endif
157
+
158
+ size = new_size(size); /* round up to prime number */
159
+
160
+ tbl = alloc(st_table);
161
+ tbl->type = type;
162
+ tbl->num_entries = 0;
163
+ tbl->num_bins = size;
164
+ tbl->bins = (st_table_entry **)Calloc(size, sizeof(st_table_entry*));
165
+
166
+ return tbl;
167
+ }
168
+
169
+ st_table*
170
+ st_init_table(type)
171
+ struct st_hash_type *type;
172
+ {
173
+ return st_init_table_with_size(type, 0);
174
+ }
175
+
176
+ st_table*
177
+ st_init_numtable(void)
178
+ {
179
+ return st_init_table(&type_numhash);
180
+ }
181
+
182
+ st_table*
183
+ st_init_numtable_with_size(size)
184
+ int size;
185
+ {
186
+ return st_init_table_with_size(&type_numhash, size);
187
+ }
188
+
189
+ st_table*
190
+ st_init_strtable(void)
191
+ {
192
+ return st_init_table(&type_strhash);
193
+ }
194
+
195
+ st_table*
196
+ st_init_strtable_with_size(size)
197
+ int size;
198
+ {
199
+ return st_init_table_with_size(&type_strhash, size);
200
+ }
201
+
202
+ void
203
+ st_free_table(table)
204
+ st_table *table;
205
+ {
206
+ register st_table_entry *ptr, *next;
207
+ int i;
208
+
209
+ for(i = 0; i < table->num_bins; i++) {
210
+ ptr = table->bins[i];
211
+ while (ptr != 0) {
212
+ next = ptr->next;
213
+ free(ptr);
214
+ ptr = next;
215
+ }
216
+ }
217
+ free(table->bins);
218
+ free(table);
219
+ }
220
+
221
+ #define PTR_NOT_EQUAL(table, ptr, hash_val, key) \
222
+ ((ptr) != 0 && (ptr->hash != (hash_val) || !EQUAL((table), (key), (ptr)->key)))
223
+
224
+ #ifdef HASH_LOG
225
+ #define COLLISION collision++
226
+ #else
227
+ #define COLLISION
228
+ #endif
229
+
230
+ #define FIND_ENTRY(table, ptr, hash_val, bin_pos) do {\
231
+ bin_pos = hash_val%(table)->num_bins;\
232
+ ptr = (table)->bins[bin_pos];\
233
+ if (PTR_NOT_EQUAL(table, ptr, hash_val, key)) {\
234
+ COLLISION;\
235
+ while (PTR_NOT_EQUAL(table, ptr->next, hash_val, key)) {\
236
+ ptr = ptr->next;\
237
+ }\
238
+ ptr = ptr->next;\
239
+ }\
240
+ } while (0)
241
+
242
+ int
243
+ st_lookup(table, key, value)
244
+ st_table *table;
245
+ register st_data_t key;
246
+ st_data_t *value;
247
+ {
248
+ unsigned int hash_val, bin_pos;
249
+ register st_table_entry *ptr;
250
+
251
+ hash_val = do_hash(key, table);
252
+ FIND_ENTRY(table, ptr, hash_val, bin_pos);
253
+
254
+ if (ptr == 0) {
255
+ return 0;
256
+ }
257
+ else {
258
+ if (value != 0) *value = ptr->record;
259
+ return 1;
260
+ }
261
+ }
262
+
263
+ #define ADD_DIRECT(table, key, value, hash_val, bin_pos)\
264
+ do {\
265
+ st_table_entry *entry;\
266
+ if (table->num_entries/(table->num_bins) > ST_DEFAULT_MAX_DENSITY) {\
267
+ rehash(table);\
268
+ bin_pos = hash_val % table->num_bins;\
269
+ }\
270
+ \
271
+ entry = alloc(st_table_entry);\
272
+ \
273
+ entry->hash = hash_val;\
274
+ entry->key = key;\
275
+ entry->record = value;\
276
+ entry->next = table->bins[bin_pos];\
277
+ table->bins[bin_pos] = entry;\
278
+ table->num_entries++;\
279
+ } while (0)
280
+
281
+ int
282
+ st_insert(table, key, value)
283
+ register st_table *table;
284
+ register st_data_t key;
285
+ st_data_t value;
286
+ {
287
+ unsigned int hash_val, bin_pos;
288
+ register st_table_entry *ptr;
289
+
290
+ hash_val = do_hash(key, table);
291
+ FIND_ENTRY(table, ptr, hash_val, bin_pos);
292
+
293
+ if (ptr == 0) {
294
+ ADD_DIRECT(table, key, value, hash_val, bin_pos);
295
+ return 0;
296
+ }
297
+ else {
298
+ ptr->record = value;
299
+ return 1;
300
+ }
301
+ }
302
+
303
+ void
304
+ st_add_direct(table, key, value)
305
+ st_table *table;
306
+ st_data_t key;
307
+ st_data_t value;
308
+ {
309
+ unsigned int hash_val, bin_pos;
310
+
311
+ hash_val = do_hash(key, table);
312
+ bin_pos = hash_val % table->num_bins;
313
+ ADD_DIRECT(table, key, value, hash_val, bin_pos);
314
+ }
315
+
316
+ static void
317
+ rehash(table)
318
+ register st_table *table;
319
+ {
320
+ register st_table_entry *ptr, *next, **new_bins;
321
+ int i, old_num_bins = table->num_bins, new_num_bins;
322
+ unsigned int hash_val;
323
+
324
+ new_num_bins = new_size(old_num_bins+1);
325
+ new_bins = (st_table_entry**)Calloc(new_num_bins, sizeof(st_table_entry*));
326
+
327
+ for(i = 0; i < old_num_bins; i++) {
328
+ ptr = table->bins[i];
329
+ while (ptr != 0) {
330
+ next = ptr->next;
331
+ hash_val = ptr->hash % new_num_bins;
332
+ ptr->next = new_bins[hash_val];
333
+ new_bins[hash_val] = ptr;
334
+ ptr = next;
335
+ }
336
+ }
337
+ free(table->bins);
338
+ table->num_bins = new_num_bins;
339
+ table->bins = new_bins;
340
+ }
341
+
342
+ st_table*
343
+ st_copy(old_table)
344
+ st_table *old_table;
345
+ {
346
+ st_table *new_table;
347
+ st_table_entry *ptr, *entry;
348
+ int i, num_bins = old_table->num_bins;
349
+
350
+ new_table = alloc(st_table);
351
+ if (new_table == 0) {
352
+ return 0;
353
+ }
354
+
355
+ *new_table = *old_table;
356
+ new_table->bins = (st_table_entry**)
357
+ Calloc((unsigned)num_bins, sizeof(st_table_entry*));
358
+
359
+ if (new_table->bins == 0) {
360
+ free(new_table);
361
+ return 0;
362
+ }
363
+
364
+ for(i = 0; i < num_bins; i++) {
365
+ new_table->bins[i] = 0;
366
+ ptr = old_table->bins[i];
367
+ while (ptr != 0) {
368
+ entry = alloc(st_table_entry);
369
+ if (entry == 0) {
370
+ free(new_table->bins);
371
+ free(new_table);
372
+ return 0;
373
+ }
374
+ *entry = *ptr;
375
+ entry->next = new_table->bins[i];
376
+ new_table->bins[i] = entry;
377
+ ptr = ptr->next;
378
+ }
379
+ }
380
+ return new_table;
381
+ }
382
+
383
+ int
384
+ st_delete(table, key, value)
385
+ register st_table *table;
386
+ register st_data_t *key;
387
+ st_data_t *value;
388
+ {
389
+ unsigned int hash_val;
390
+ st_table_entry *tmp;
391
+ register st_table_entry *ptr;
392
+
393
+ hash_val = do_hash_bin(*key, table);
394
+ ptr = table->bins[hash_val];
395
+
396
+ if (ptr == 0) {
397
+ if (value != 0) *value = 0;
398
+ return 0;
399
+ }
400
+
401
+ if (EQUAL(table, *key, ptr->key)) {
402
+ table->bins[hash_val] = ptr->next;
403
+ table->num_entries--;
404
+ if (value != 0) *value = ptr->record;
405
+ *key = ptr->key;
406
+ free(ptr);
407
+ return 1;
408
+ }
409
+
410
+ for(; ptr->next != 0; ptr = ptr->next) {
411
+ if (EQUAL(table, ptr->next->key, *key)) {
412
+ tmp = ptr->next;
413
+ ptr->next = ptr->next->next;
414
+ table->num_entries--;
415
+ if (value != 0) *value = tmp->record;
416
+ *key = tmp->key;
417
+ free(tmp);
418
+ return 1;
419
+ }
420
+ }
421
+
422
+ return 0;
423
+ }
424
+
425
+ int
426
+ st_delete_safe(table, key, value, never)
427
+ register st_table *table;
428
+ register st_data_t *key;
429
+ st_data_t *value;
430
+ st_data_t never;
431
+ {
432
+ unsigned int hash_val;
433
+ register st_table_entry *ptr;
434
+
435
+ hash_val = do_hash_bin(*key, table);
436
+ ptr = table->bins[hash_val];
437
+
438
+ if (ptr == 0) {
439
+ if (value != 0) *value = 0;
440
+ return 0;
441
+ }
442
+
443
+ for(; ptr != 0; ptr = ptr->next) {
444
+ if ((ptr->key != never) && EQUAL(table, ptr->key, *key)) {
445
+ table->num_entries--;
446
+ *key = ptr->key;
447
+ if (value != 0) *value = ptr->record;
448
+ ptr->key = ptr->record = never;
449
+ return 1;
450
+ }
451
+ }
452
+
453
+ return 0;
454
+ }
455
+
456
+ static int
457
+ delete_never(key, value, never)
458
+ st_data_t key, value, never;
459
+ {
460
+ if (value == never) return ST_DELETE;
461
+ return ST_CONTINUE;
462
+ }
463
+
464
+ void
465
+ st_cleanup_safe(table, never)
466
+ st_table *table;
467
+ st_data_t never;
468
+ {
469
+ int num_entries = table->num_entries;
470
+
471
+ st_foreach(table, delete_never, never);
472
+ table->num_entries = num_entries;
473
+ }
474
+
475
+ int
476
+ st_foreach(table, func, arg)
477
+ st_table *table;
478
+ int (*func)();
479
+ st_data_t arg;
480
+ {
481
+ st_table_entry *ptr, *last, *tmp;
482
+ enum st_retval retval;
483
+ int i;
484
+
485
+ for(i = 0; i < table->num_bins; i++) {
486
+ last = 0;
487
+ for(ptr = table->bins[i]; ptr != 0;) {
488
+ retval = (*func)(ptr->key, ptr->record, arg);
489
+ switch (retval) {
490
+ case ST_CHECK: /* check if hash is modified during iteration */
491
+ tmp = 0;
492
+ if (i < table->num_bins) {
493
+ for (tmp = table->bins[i]; tmp; tmp=tmp->next) {
494
+ if (tmp == ptr) break;
495
+ }
496
+ }
497
+ if (!tmp) {
498
+ /* call func with error notice */
499
+ return 1;
500
+ }
501
+ /* fall through */
502
+ case ST_CONTINUE:
503
+ last = ptr;
504
+ ptr = ptr->next;
505
+ break;
506
+ case ST_STOP:
507
+ return 0;
508
+ case ST_DELETE:
509
+ tmp = ptr;
510
+ if (last == 0) {
511
+ table->bins[i] = ptr->next;
512
+ }
513
+ else {
514
+ last->next = ptr->next;
515
+ }
516
+ ptr = ptr->next;
517
+ free(tmp);
518
+ table->num_entries--;
519
+ }
520
+ }
521
+ }
522
+ return 0;
523
+ }
524
+
525
+ static int
526
+ strhash(string)
527
+ register const char *string;
528
+ {
529
+ register int c;
530
+
531
+ #ifdef HASH_ELFHASH
532
+ register unsigned int h = 0, g;
533
+
534
+ while ((c = *string++) != '\0') {
535
+ h = ( h << 4 ) + c;
536
+ if ( g = h & 0xF0000000 )
537
+ h ^= g >> 24;
538
+ h &= ~g;
539
+ }
540
+ return h;
541
+ #elif defined(HASH_PERL)
542
+ register int val = 0;
543
+
544
+ while ((c = *string++) != '\0') {
545
+ val += c;
546
+ val += (val << 10);
547
+ val ^= (val >> 6);
548
+ }
549
+ val += (val << 3);
550
+ val ^= (val >> 11);
551
+
552
+ return val + (val << 15);
553
+ #else
554
+ register int val = 0;
555
+
556
+ while ((c = *string++) != '\0') {
557
+ val = val*997 + c;
558
+ }
559
+
560
+ return val + (val>>5);
561
+ #endif
562
+ }
563
+
564
+ static int
565
+ numcmp(x, y)
566
+ long x, y;
567
+ {
568
+ return x != y;
569
+ }
570
+
571
+ static int
572
+ numhash(n)
573
+ long n;
574
+ {
575
+ return n;
576
+ }
@@ -0,0 +1,72 @@
1
+ /* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */
2
+
3
+ /* @(#) st.h 5.1 89/12/14 */
4
+
5
+ #ifndef ST_INCLUDED
6
+
7
+ #define ST_INCLUDED
8
+
9
+ #if SIZEOF_LONG == SIZEOF_VOIDP
10
+ typedef unsigned long st_data_t;
11
+ #elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
12
+ typedef unsigned LONG_LONG st_data_t;
13
+ #else
14
+ # error ---->> st.c requires sizeof(void*) == sizeof(long) to be compiled. <<---
15
+ -
16
+ #endif
17
+ #define ST_DATA_T_DEFINED
18
+
19
+ typedef struct st_table st_table;
20
+
21
+ struct st_hash_type {
22
+ int (*compare)();
23
+ int (*hash)();
24
+ };
25
+
26
+ struct st_table {
27
+ struct st_hash_type *type;
28
+ int num_bins;
29
+ int num_entries;
30
+ struct st_table_entry **bins;
31
+ };
32
+
33
+ #define st_is_member(table,key) st_lookup(table,key,(st_data_t *)0)
34
+
35
+ enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK};
36
+
37
+ #ifndef _
38
+ # define _(args) args
39
+ #endif
40
+ #ifndef ANYARGS
41
+ # ifdef __cplusplus
42
+ # define ANYARGS ...
43
+ # else
44
+ # define ANYARGS
45
+ # endif
46
+ #endif
47
+
48
+ st_table *st_init_table _((struct st_hash_type *));
49
+ st_table *st_init_table_with_size _((struct st_hash_type *, int));
50
+ st_table *st_init_numtable _((void));
51
+ st_table *st_init_numtable_with_size _((int));
52
+ st_table *st_init_strtable _((void));
53
+ st_table *st_init_strtable_with_size _((int));
54
+ int st_delete _((st_table *, st_data_t *, st_data_t *));
55
+ int st_delete_safe _((st_table *, st_data_t *, st_data_t *, st_data_t));
56
+ int st_insert _((st_table *, st_data_t, st_data_t));
57
+ int st_lookup _((st_table *, st_data_t, st_data_t *));
58
+ int st_foreach _((st_table *, int (*)(ANYARGS), st_data_t));
59
+ void st_add_direct _((st_table *, st_data_t, st_data_t));
60
+ void st_free_table _((st_table *));
61
+ void st_cleanup_safe _((st_table *, st_data_t));
62
+ st_table *st_copy _((st_table *));
63
+
64
+ #define ST_NUMCMP ((int (*)()) 0)
65
+ #define ST_NUMHASH ((int (*)()) -2)
66
+
67
+ #define st_numcmp ST_NUMCMP
68
+ #define st_numhash ST_NUMHASH
69
+
70
+ int st_strhash();
71
+
72
+ #endif /* ST_INCLUDED */