annotate lib/hash.c @ 1039:4d7cd20a6c87

(hash_free_0): Remove prototype. Move function to precede first use.
author Jim Meyering <jim@meyering.net>
date Sun, 21 Sep 1997 04:41:19 +0000
parents b12d8086ca7a
children f9473b8f6df1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1038
b12d8086ca7a (ZALLOC): Take Ht parameter instead of relying on one being in scope.
Jim Meyering <jim@meyering.net>
parents: 1037
diff changeset
1 /* A generic hash table package. */
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
2
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
3 #include <stdio.h>
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
4 #include <stdlib.h>
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
5 #include <assert.h>
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
6
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
7 #include "hash.h"
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
8
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
9 #ifdef USE_OBSTACK
1038
b12d8086ca7a (ZALLOC): Take Ht parameter instead of relying on one being in scope.
Jim Meyering <jim@meyering.net>
parents: 1037
diff changeset
10 # define ZALLOC(Ht, N) obstack_alloc (&(ht->ht_obstack), (N))
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
11 #else
1038
b12d8086ca7a (ZALLOC): Take Ht parameter instead of relying on one being in scope.
Jim Meyering <jim@meyering.net>
parents: 1037
diff changeset
12 # define ZALLOC(Ht, N) malloc ((N))
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
13 #endif
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
14
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
15 #define BUCKET_HEAD(ht, idx) ((ht)->hash_table[(idx)])
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
16
1033
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
17 static int
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
18 is_prime (candidate)
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
19 unsigned long candidate;
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
20 {
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
21 /* No even number and none less than 10 will be passed here. */
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
22 unsigned long divn = 3;
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
23 unsigned long sq = divn * divn;
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
24
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
25 while (sq < candidate && (candidate % divn))
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
26 {
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
27 divn++;
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
28 sq += 4 * divn;
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
29 divn++;
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
30 }
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
31
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
32 return (candidate % divn);
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
33 }
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
34
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
35 /* Round a given number up to the nearest prime. */
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
36
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
37 static unsigned long
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
38 next_prime (candidate)
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
39 unsigned long candidate;
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
40 {
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
41 /* Make it definitely odd. */
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
42 candidate |= 1;
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
43
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
44 while (!is_prime (candidate))
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
45 candidate += 2;
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
46
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
47 return candidate;
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
48 }
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
49
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
50 static void
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
51 hash_free_entry (HT *ht, HASH_ENT *e)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
52 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
53 e->key = NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
54 e->next = ht->hash_free_entry_list;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
55 ht->hash_free_entry_list = e;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
56 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
57
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
58 static HASH_ENT *
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
59 hash_allocate_entry (HT *ht)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
60 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
61 HASH_ENT *new;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
62 if (ht->hash_free_entry_list)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
63 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
64 new = ht->hash_free_entry_list;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
65 ht->hash_free_entry_list = new->next;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
66 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
67 else
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
68 {
1038
b12d8086ca7a (ZALLOC): Take Ht parameter instead of relying on one being in scope.
Jim Meyering <jim@meyering.net>
parents: 1037
diff changeset
69 new = (HASH_ENT *) ZALLOC (ht, sizeof (HASH_ENT));
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
70 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
71 return new;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
72 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
73
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
74 unsigned int
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
75 hash_get_n_slots_used (const HT *ht)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
76 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
77 return ht->hash_n_slots_used;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
78 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
79
1039
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
80 /* Free all storage associated with HT that functions in this package
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
81 have allocated. If a key_freer function has been supplied (when HT
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
82 was created), this function applies it to the key of each entry before
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
83 freeing that entry. */
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
84
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
85 static void
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
86 hash_free_0 (HT *ht, int free_user_data)
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
87 {
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
88 if (free_user_data && ht->hash_key_freer != NULL)
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
89 {
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
90 unsigned int i;
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
91
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
92 for (i = 0; i < ht->hash_table_size; i++)
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
93 {
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
94 HASH_ENT *p;
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
95 HASH_ENT *next;
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
96
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
97 for (p = BUCKET_HEAD (ht, i); p; p = next)
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
98 {
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
99 next = p->next;
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
100 ht->hash_key_freer (p->key);
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
101 }
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
102 }
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
103 }
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
104
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
105 #ifdef USE_OBSTACK
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
106 obstack_free (&(ht->ht_obstack), NULL);
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
107 #else
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
108 {
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
109 unsigned int i;
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
110 for (i = 0; i < ht->hash_table_size; i++)
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
111 {
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
112 HASH_ENT *p;
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
113 HASH_ENT *next;
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
114
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
115 for (p = BUCKET_HEAD (ht, i); p; p = next)
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
116 {
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
117 next = p->next;
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
118 free (p);
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
119 }
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
120 }
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
121 }
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
122 #endif
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
123 ht->hash_free_entry_list = NULL;
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
124 free (ht->hash_table);
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
125 }
4d7cd20a6c87 (hash_free_0): Remove prototype.
Jim Meyering <jim@meyering.net>
parents: 1038
diff changeset
126
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
127 /* FIXME-comment */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
128
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
129 int
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
130 hash_rehash (HT *ht, unsigned int new_table_size)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
131 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
132 HT *ht_new;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
133 unsigned int i;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
134
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
135 if (ht->hash_table_size <= 0 || new_table_size == 0)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
136 return 1;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
137
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
138 ht_new = hash_initialize (new_table_size, ht->hash_key_freer,
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
139 ht->hash_hash, ht->hash_key_comparator);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
140
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
141 if (ht_new == NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
142 return 1;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
143
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
144 for (i = 0; i < ht->hash_table_size; i++)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
145 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
146 HASH_ENT *p = BUCKET_HEAD (ht, i);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
147 for ( /* empty */ ; p; p = p->next)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
148 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
149 int failed;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
150 const void *already_in_table;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
151 already_in_table = hash_insert_if_absent (ht_new, p->key, &failed);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
152 assert (failed == 0 && already_in_table == 0);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
153 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
154 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
155
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
156 hash_free_0 (ht, 0);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
157
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
158 #ifdef TESTING
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
159 assert (hash_table_ok (ht_new));
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
160 #endif
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
161 *ht = *ht_new;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
162 free (ht_new);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
163
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
164 /* FIXME: fill in ht_new->n_slots_used and other statistics fields. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
165
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
166 return 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
167 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
168
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
169 /* FIXME-comment */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
170
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
171 unsigned int
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
172 hash_get_max_chain_length (HT *ht)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
173 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
174 unsigned int i;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
175 unsigned int max_chain_length = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
176
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
177 if (!ht->hash_dirty_max_chain_length)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
178 return ht->hash_max_chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
179
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
180 for (i = 0; i < ht->hash_table_size; i++)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
181 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
182 unsigned int chain_length = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
183 HASH_ENT *p = BUCKET_HEAD (ht, i);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
184 for ( /* empty */ ; p; p = p->next)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
185 ++chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
186 if (chain_length > max_chain_length)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
187 max_chain_length = chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
188 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
189
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
190 ht->hash_max_chain_length = max_chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
191 ht->hash_dirty_max_chain_length = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
192 return ht->hash_max_chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
193 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
194
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
195 unsigned int
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
196 hash_get_n_keys (const HT *ht)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
197 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
198 return ht->hash_n_keys;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
199 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
200
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
201 unsigned int
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
202 hash_get_table_size (const HT *ht)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
203 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
204 return ht->hash_table_size;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
205 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
206
1036
959139283fc7 *** empty log message ***
Jim Meyering <jim@meyering.net>
parents: 1035
diff changeset
207 /* CANDIDATE_TABLE_SIZE need not be prime. If WHEN_TO_REHASH (FIXME: add
959139283fc7 *** empty log message ***
Jim Meyering <jim@meyering.net>
parents: 1035
diff changeset
208 this parameter) is positive, when that percentage of table entries have
959139283fc7 *** empty log message ***
Jim Meyering <jim@meyering.net>
parents: 1035
diff changeset
209 been used, the table size is increased; then a new, larger table
959139283fc7 *** empty log message ***
Jim Meyering <jim@meyering.net>
parents: 1035
diff changeset
210 (GROW_FACTOR (FIXME: maybe add this parameter) times larger than the previous
959139283fc7 *** empty log message ***
Jim Meyering <jim@meyering.net>
parents: 1035
diff changeset
211 size) is allocated and all entries in the old table are rehashed into
959139283fc7 *** empty log message ***
Jim Meyering <jim@meyering.net>
parents: 1035
diff changeset
212 the new, larger one. The old table is freed. If WHEN_TO_REHASH is zero
959139283fc7 *** empty log message ***
Jim Meyering <jim@meyering.net>
parents: 1035
diff changeset
213 or negative, the table is never resized.
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
214
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
215 The function returns non-zero
1036
959139283fc7 *** empty log message ***
Jim Meyering <jim@meyering.net>
parents: 1035
diff changeset
216 - if CANDIDATE_TABLE_SIZE is zero or negative
959139283fc7 *** empty log message ***
Jim Meyering <jim@meyering.net>
parents: 1035
diff changeset
217 - if KEY_COMPARATOR or HASH is null
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
218 - if it was unable to allocate sufficient storage for the hash table
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
219 - if WHEN_TO_REHASH is zero or negative
1037
b24d08ec1fa3 *** empty log message ***
Jim Meyering <jim@meyering.net>
parents: 1036
diff changeset
220 Otherwise it returns zero. */
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
221
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
222 HT *
1033
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
223 hash_initialize (unsigned int candidate_table_size,
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
224 Hash_key_freer_type key_freer,
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
225 unsigned int (*hash) (const void *, unsigned int),
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
226 int (*key_comparator) (const void *, const void *))
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
227 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
228 HT *ht;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
229 unsigned int i;
1033
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
230 unsigned int table_size;
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
231
1033
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
232 if (candidate_table_size <= 0)
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
233 return NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
234
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
235 if (hash == NULL || key_comparator == NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
236 return NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
237
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
238 ht = (HT *) malloc (sizeof (HT));
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
239 if (ht == NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
240 return NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
241
1033
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
242 table_size = next_prime (candidate_table_size);
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
243 ht->hash_table = (HASH_ENT **) malloc (table_size * sizeof (HASH_ENT *));
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
244 if (ht->hash_table == NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
245 return NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
246
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
247 for (i = 0; i < table_size; i++)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
248 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
249 BUCKET_HEAD (ht, i) = NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
250 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
251
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
252 ht->hash_free_entry_list = NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
253 ht->hash_table_size = table_size;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
254 ht->hash_hash = hash;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
255 ht->hash_key_comparator = key_comparator;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
256 ht->hash_key_freer = key_freer;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
257 ht->hash_n_slots_used = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
258 ht->hash_max_chain_length = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
259 ht->hash_n_keys = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
260 ht->hash_dirty_max_chain_length = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
261 #ifdef USE_OBSTACK
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
262 obstack_init (&(ht->ht_obstack));
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
263 #endif
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
264
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
265 return ht;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
266 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
267
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
268 /* This private function is used to help with insertion and deletion.
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
269 If E does *not* compare equal to the key of any entry in the table,
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
270 return NULL.
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
271 When E matches an entry in the table, return a pointer to the matching
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
272 entry. When DELETE is non-zero and E matches an entry in the table,
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
273 unlink the matching entry. Set *CHAIN_LENGTH to the number of keys
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
274 that have hashed to the bucket E hashed to. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
275
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
276 static HASH_ENT *
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
277 hash_find_entry (HT *ht, const void *e, unsigned int *table_idx,
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
278 unsigned int *chain_length, int delete)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
279 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
280 unsigned int idx;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
281 int found;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
282 HASH_ENT *p, *prev;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
283
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
284 idx = ht->hash_hash (e, ht->hash_table_size);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
285 assert (idx < ht->hash_table_size);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
286
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
287 *table_idx = idx;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
288 *chain_length = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
289
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
290 prev = ht->hash_table[idx];
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
291
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
292 if (prev == NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
293 return NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
294
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
295 *chain_length = 1;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
296 if (ht->hash_key_comparator (e, prev->key) == 0)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
297 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
298 if (delete)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
299 ht->hash_table[idx] = prev->next;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
300 return prev;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
301 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
302
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
303 p = prev->next;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
304 found = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
305 while (p)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
306 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
307 ++(*chain_length);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
308 if (ht->hash_key_comparator (e, p->key) == 0)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
309 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
310 found = 1;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
311 break;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
312 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
313 prev = p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
314 p = p->next;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
315 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
316
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
317 if (!found)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
318 return NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
319
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
320 assert (p != NULL);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
321 if (delete)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
322 prev->next = p->next;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
323
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
324 return p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
325 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
326
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
327 /* Return non-zero if E is already in the table, zero otherwise. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
328
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
329 int
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
330 hash_query_in_table (const HT *ht, const void *e)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
331 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
332 unsigned int idx;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
333 HASH_ENT *p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
334
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
335 idx = ht->hash_hash (e, ht->hash_table_size);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
336 assert (idx < ht->hash_table_size);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
337 for (p = BUCKET_HEAD (ht, idx); p != NULL; p = p->next)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
338 if (ht->hash_key_comparator (e, p->key) == 0)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
339 return 1;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
340 return 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
341 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
342
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
343 void *
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
344 hash_lookup (const HT *ht, const void *e)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
345 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
346 unsigned int idx;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
347 HASH_ENT *p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
348
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
349 idx = ht->hash_hash (e, ht->hash_table_size);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
350 assert (idx < ht->hash_table_size);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
351 for (p = BUCKET_HEAD (ht, idx); p != NULL; p = p->next)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
352 if (ht->hash_key_comparator (e, p->key) == 0)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
353 return p->key;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
354 return NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
355 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
356
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
357 /* If E matches an entry already in the hash table, don't modify the
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
358 table and return a pointer to the matched entry. If E does not
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
359 match any item in the table, insert E and return NULL.
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
360 If the storage required for insertion cannot be allocated
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
361 set *FAILED to non-zero and return NULL. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
362
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
363 void *
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
364 hash_insert_if_absent (HT *ht, const void *e, int *failed)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
365 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
366 const HASH_ENT *ent;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
367 HASH_ENT *new;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
368 unsigned int idx;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
369 unsigned int chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
370
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
371 assert (e != NULL); /* Can't insert a NULL key. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
372
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
373 *failed = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
374 ent = hash_find_entry (ht, e, &idx, &chain_length, 0);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
375 if (ent != NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
376 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
377 /* E matches a key from an entry already in the table. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
378 return ent->key;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
379 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
380
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
381 new = hash_allocate_entry (ht);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
382 if (new == NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
383 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
384 *failed = 1;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
385 return NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
386 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
387
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
388 new->key = (void *) e;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
389 new->next = BUCKET_HEAD (ht, idx);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
390 BUCKET_HEAD (ht, idx) = new;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
391
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
392 if (chain_length == 0)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
393 ++(ht->hash_n_slots_used);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
394
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
395 /* The insertion has just increased chain_length by 1. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
396 ++chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
397
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
398 if (chain_length > ht->hash_max_chain_length)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
399 ht->hash_max_chain_length = chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
400
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
401 ++(ht->hash_n_keys);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
402 if ((double) ht->hash_n_keys / ht->hash_table_size > 0.80)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
403 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
404 unsigned int new_size;
1033
f4f00c32582a use malloc, not xmalloc in obstack #define
Jim Meyering <jim@meyering.net>
parents: 1031
diff changeset
405 new_size = next_prime (2 * ht->hash_table_size + 1);
1031
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
406 *failed = hash_rehash (ht, new_size);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
407 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
408
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
409 #ifdef TESTING
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
410 assert (hash_table_ok (ht));
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
411 #endif
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
412
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
413 return NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
414 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
415
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
416 /* If E is already in the table, remove it and return a pointer to
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
417 the just-deleted key (the user may want to deallocate its storage).
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
418 If E is not in the table, don't modify the table and return NULL. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
419
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
420 void *
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
421 hash_delete_if_present (HT *ht, const void *e)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
422 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
423 HASH_ENT *ent;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
424 void *key;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
425 unsigned int idx;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
426 unsigned int chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
427
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
428 ent = hash_find_entry (ht, e, &idx, &chain_length, 1);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
429 if (ent == NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
430 return NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
431
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
432 if (ent->next == NULL && chain_length == 1)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
433 --(ht->hash_n_slots_used);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
434
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
435 key = ent->key;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
436
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
437 --(ht->hash_n_keys);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
438 ht->hash_dirty_max_chain_length = 1;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
439 if (ent->next == NULL && chain_length < ht->hash_max_chain_length)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
440 ht->hash_dirty_max_chain_length = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
441
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
442 hash_free_entry (ht, ent);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
443
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
444 #ifdef TESTING
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
445 assert (hash_table_ok (ht));
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
446 #endif
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
447 return key;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
448 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
449
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
450 void
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
451 hash_print_statistics (const HT *ht, FILE *stream)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
452 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
453 unsigned int n_slots_used;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
454 unsigned int n_keys;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
455 unsigned int max_chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
456 int err;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
457
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
458 err = hash_get_statistics (ht, &n_slots_used, &n_keys, &max_chain_length);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
459 assert (err == 0);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
460 fprintf (stream, "table size: %d\n", ht->hash_table_size);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
461 fprintf (stream, "# slots used: %u (%.2f%%)\n", n_slots_used,
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
462 (100.0 * n_slots_used) / ht->hash_table_size);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
463 fprintf (stream, "# keys: %u\n", n_keys);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
464 fprintf (stream, "max chain length: %u\n", max_chain_length);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
465 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
466
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
467 /* If there is *NO* table (so, no meaningful stats) return non-zero
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
468 and don't reference the argument pointers. Otherwise compute the
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
469 performance statistics and return non-zero. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
470
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
471 int
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
472 hash_get_statistics (const HT *ht,
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
473 unsigned int *n_slots_used,
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
474 unsigned int *n_keys,
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
475 unsigned int *max_chain_length)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
476 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
477 unsigned int i;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
478
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
479 if (ht == NULL || ht->hash_table == NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
480 return 1;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
481
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
482 *max_chain_length = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
483 *n_slots_used = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
484 *n_keys = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
485
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
486 for (i = 0; i < ht->hash_table_size; i++)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
487 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
488 unsigned int chain_length = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
489 HASH_ENT *p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
490
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
491 p = BUCKET_HEAD (ht, i);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
492 if (p != NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
493 ++(*n_slots_used);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
494
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
495 for (; p; p = p->next)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
496 ++chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
497
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
498 *n_keys += chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
499 if (chain_length > *max_chain_length)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
500 *max_chain_length = chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
501 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
502 return 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
503 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
504
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
505 int
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
506 hash_table_ok (HT *ht)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
507 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
508 int code;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
509 unsigned int n_slots_used;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
510 unsigned int n_keys;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
511 unsigned int max_chain_length;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
512
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
513 if (ht == NULL || ht->hash_table == NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
514 return 1;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
515
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
516 code = hash_get_statistics (ht, &n_slots_used, &n_keys,
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
517 &max_chain_length);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
518
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
519 if (code != 0
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
520 || n_slots_used != ht->hash_n_slots_used
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
521 || n_keys != ht->hash_n_keys
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
522 || max_chain_length != hash_get_max_chain_length (ht))
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
523 return 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
524
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
525 return 1;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
526 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
527
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
528 /* See hash_do_for_each_2 (below) for a variant. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
529
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
530 void
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
531 hash_do_for_each (HT *ht, void (*f) (void *e, void *aux), void *aux)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
532 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
533 unsigned int i;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
534
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
535 #ifdef TESTING
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
536 assert (hash_table_ok (ht));
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
537 #endif
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
538
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
539 if (ht->hash_table == NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
540 return;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
541
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
542 for (i = 0; i < ht->hash_table_size; i++)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
543 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
544 HASH_ENT *p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
545 for (p = BUCKET_HEAD (ht, i); p; p = p->next)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
546 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
547 (*f) (p->key, aux);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
548 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
549 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
550 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
551
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
552 /* Just like hash_do_for_each, except that function F returns an int
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
553 that can signal (when non-zero) we should return early. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
554
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
555 int
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
556 hash_do_for_each_2 (HT *ht, int (*f) (void *e, void *aux), void *aux)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
557 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
558 unsigned int i;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
559
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
560 #ifdef TESTING
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
561 assert (hash_table_ok (ht));
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
562 #endif
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
563
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
564 if (ht->hash_table == NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
565 return 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
566
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
567 for (i = 0; i < ht->hash_table_size; i++)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
568 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
569 HASH_ENT *p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
570 for (p = BUCKET_HEAD (ht, i); p; p = p->next)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
571 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
572 int return_code;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
573
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
574 return_code = (*f) (p->key, aux);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
575 if (return_code != 0)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
576 return return_code;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
577 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
578 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
579 return 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
580 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
581
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
582 /* For each entry in the bucket addressed by BUCKET_KEY of the hash
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
583 table HT, invoke the function F. If F returns non-zero, stop
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
584 iterating and return that value. Otherwise, apply F to all entries
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
585 in the selected bucket and return zero. The AUX argument to this
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
586 function is passed as the last argument in each invocation of F.
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
587 The first argument to F is BUCKET_KEY, and the second is the key of
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
588 an entry in the selected bucket. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
589
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
590 int
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
591 hash_do_for_each_in_selected_bucket (HT *ht, const void *bucket_key,
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
592 int (*f) (const void *bucket_key,
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
593 void *e, void *aux),
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
594 void *aux)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
595 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
596 int idx;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
597 HASH_ENT *p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
598
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
599 #ifdef TESTING
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
600 assert (hash_table_ok (ht));
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
601 #endif
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
602
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
603 if (ht->hash_table == NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
604 return 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
605
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
606 idx = ht->hash_hash (bucket_key, ht->hash_table_size);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
607
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
608 for (p = BUCKET_HEAD (ht, idx); p != NULL; p = p->next)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
609 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
610 int return_code;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
611
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
612 return_code = (*f) (bucket_key, p->key, aux);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
613 if (return_code != 0)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
614 return return_code;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
615 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
616
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
617 return 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
618 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
619
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
620 /* Make all buckets empty, placing any chained entries on the free list.
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
621 As with hash_free, apply the user-specified function key_freer
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
622 (if it's not NULL) to the keys of any affected entries. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
623
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
624 void
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
625 hash_clear (HT *ht)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
626 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
627 unsigned int i;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
628 HASH_ENT *p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
629
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
630 for (i = 0; i < ht->hash_table_size; i++)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
631 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
632 HASH_ENT *tail = NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
633 HASH_ENT *head = BUCKET_HEAD (ht, i);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
634
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
635 /* Free any keys and get tail pointer to last entry in chain. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
636 for (p = head; p; p = p->next)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
637 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
638 if (ht->hash_key_freer != NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
639 ht->hash_key_freer (p->key);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
640 p->key = NULL; /* Make sure no one tries to use this key later. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
641 tail = p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
642 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
643 BUCKET_HEAD (ht, i) = NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
644
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
645 /* If there's a chain in this bucket, tack it onto the
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
646 beginning of the free list. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
647 if (head != NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
648 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
649 assert (tail != NULL && tail->next == NULL);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
650 tail->next = ht->hash_free_entry_list;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
651 ht->hash_free_entry_list = head;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
652 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
653 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
654 ht->hash_n_slots_used = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
655 ht->hash_max_chain_length = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
656 ht->hash_n_keys = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
657 ht->hash_dirty_max_chain_length = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
658 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
659
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
660 void
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
661 hash_free (HT *ht)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
662 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
663 hash_free_0 (ht, 1);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
664 free (ht);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
665 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
666
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
667 #ifdef TESTING
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
668
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
669 void
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
670 hash_print (const HT *ht)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
671 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
672 int i;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
673
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
674 for (i = 0; i < ht->hash_table_size; i++)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
675 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
676 HASH_ENT *p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
677
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
678 if (BUCKET_HEAD (ht, i) != NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
679 printf ("%d:\n", i);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
680
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
681 for (p = BUCKET_HEAD (ht, i); p; p = p->next)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
682 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
683 char *s = (char *) p->key;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
684 /* FIXME */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
685 printf (" %s\n", s);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
686 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
687 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
688 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
689
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
690 #endif /* TESTING */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
691
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
692 void
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
693 hash_get_key_list (const HT *ht, unsigned int bufsize, void **buf)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
694 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
695 unsigned int i;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
696 unsigned int c = 0;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
697
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
698 for (i = 0; i < ht->hash_table_size; i++)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
699 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
700 HASH_ENT *p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
701
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
702 for (p = BUCKET_HEAD (ht, i); p; p = p->next)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
703 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
704 if (c >= bufsize)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
705 return;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
706 buf[c++] = p->key;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
707 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
708 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
709 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
710
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
711 /* Return the first key in the table. If the table is empty, return NULL. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
712
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
713 void *
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
714 hash_get_first (const HT *ht)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
715 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
716 unsigned int idx;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
717 HASH_ENT *p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
718
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
719 if (ht->hash_n_keys == 0)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
720 return NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
721
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
722 for (idx = 0; idx < ht->hash_table_size; idx++)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
723 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
724 if ((p = BUCKET_HEAD (ht, idx)) != NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
725 return p->key;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
726 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
727 abort ();
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
728 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
729
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
730 /* Return the key in the entry following the entry whose key matches E.
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
731 If there is the only one key in the table and that key matches E,
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
732 return the matching key. If E is not in the table, return NULL. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
733
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
734 void *
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
735 hash_get_next (const HT *ht, const void *e)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
736 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
737 unsigned int idx;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
738 HASH_ENT *p;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
739
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
740 idx = ht->hash_hash (e, ht->hash_table_size);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
741 assert (idx < ht->hash_table_size);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
742 for (p = BUCKET_HEAD (ht, idx); p != NULL; p = p->next)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
743 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
744 if (ht->hash_key_comparator (e, p->key) == 0)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
745 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
746 if (p->next != NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
747 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
748 return p->next->key;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
749 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
750 else
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
751 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
752 unsigned int bucket;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
753
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
754 /* E is the last or only key in the bucket chain. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
755 if (ht->hash_n_keys == 1)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
756 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
757 /* There is only one key in the table, and it matches E. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
758 return p->key;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
759 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
760 bucket = idx;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
761 do
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
762 {
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
763 idx = (idx + 1) % ht->hash_table_size;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
764 if ((p = BUCKET_HEAD (ht, idx)) != NULL)
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
765 return p->key;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
766 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
767 while (idx != bucket);
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
768 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
769 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
770 }
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
771
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
772 /* E is not in the table. */
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
773 return NULL;
e34b8e81638f from ti/hdlsv
Jim Meyering <jim@meyering.net>
parents:
diff changeset
774 }