annotate src/hash.c @ 380:8626e4521993 r21-2-5

Import from CVS: tag r21-2-5
author cvs
date Mon, 13 Aug 2007 11:07:10 +0200
parents c5d627a313b1
children 7d59cb494b73
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1 /* Hash tables.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
2 Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
3
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
4 This file is part of XEmacs.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
5
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
6 XEmacs is free software; you can redistribute it and/or modify it
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
7 under the terms of the GNU General Public License as published by the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
8 Free Software Foundation; either version 2, or (at your option) any
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
9 later version.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
10
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
14 for more details.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
15
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
17 along with XEmacs; see the file COPYING. If not, write to
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
19 Boston, MA 02111-1307, USA. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
20
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
21 /* Synched up with: Not in FSF. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
22
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
23 #ifdef emacs
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
24 #include <config.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
25 #include "lisp.h"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
26
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
27 #define NULL_ENTRY (LISP_TO_VOID (Qnil))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
28
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
29 #else /* !emacs */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
30
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
31 #define NULL_ENTRY ((void *) 1)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
32
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
33 #endif /* !emacs */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
34
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
35 #include "hash.h"
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
36
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
37 #define COMFORTABLE_SIZE(size) (21 * (size) / 16)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
38
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
39 /* Knuth volume 3, hash functions */
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
40 #define WORD_HASH_4(word) (0x9c406b55 * (word))
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
41 #define WORD_HASH_8(word) (0x9c406b549c406b55 * (word))
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
42
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
43 static CONST hash_size_t
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
44 primes [] =
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
45 {
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
46 13,
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
47 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631,
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
48 761, 919, 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013,
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
49 8419, 10103, 12143, 14591, 17519, 21023, 25229, 30293, 36353, 43627, 52361,
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
50 62851, 75431, 90523, 108631, 130363, 156437, 187751, 225307, 270371, 324449,
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
51 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263, 1674319,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
52 2009191, 2411033, 2893249
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
53 };
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
54
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
55 #if 0
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
56 static CONST hash_size_t
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
57 primes [] =
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
58 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
59 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031, 1361,
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
60 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783, 19219, 24989,
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
61 32491, 42257, 54941, 71429, 92861, 120721, 156941, 204047, 265271,
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
62 344857, 448321, 582821, 757693, 985003, 1280519, 1664681, 2164111,
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
63 2813353, 3657361, 4754591, 6180989, 8035301, 10445899, 13579681,
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
64 17653589, 22949669, 29834603, 38784989, 50420551, 65546729, 85210757,
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
65 110774011, 144006217, 187208107, 243370577, 316381771, 411296309,
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
66 534685237, 695090819, 903618083, 1174703521, 1527114613, 1985248999,
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
67 2580823717, 3355070839, 4361592119
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
68 };
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
69 #endif
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
70
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
71 unsigned long
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
72 memory_hash (CONST void *xv, size_t size)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
73 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
74 unsigned int h = 0;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
75 unsigned CONST char *x = (unsigned CONST char *) xv;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
76
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
77 if (!x) return 0;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
78
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
79 while (size--)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
80 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
81 unsigned int g;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
82 h = (h << 4) + *x++;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
83 if ((g = h & 0xf0000000) != 0)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
84 h = (h ^ (g >> 24)) ^ g;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
85 }
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
86
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
87 return h;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
88 }
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
89
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
90 /* We've heard of binary search. */
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
91 static hash_size_t
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
92 prime_size (hash_size_t size)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
93 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
94 int low, high;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
95 for (low = 0, high = countof (primes) - 1; high - low > 1;)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
96 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
97 /* Loop Invariant: size < primes [high] */
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
98 int mid = (low + high) / 2;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
99 if (primes [mid] < size)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
100 low = mid;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
101 else
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
102 high = mid;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
103 }
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
104 return primes [high];
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
105 }
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
106
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
107 static void rehash (hentry *harray, struct hash_table *ht, hash_size_t size);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
108
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
109 #define KEYS_DIFFER_P(old, new, testfun) \
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
110 (((old) != (new)) && (!(testfun) || !(testfun) ((old),(new))))
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
111
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
112 CONST void *
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
113 gethash (CONST void *key, struct hash_table *hash_table, CONST void **ret_value)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
114 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
115 hentry *harray = hash_table->harray;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
116 hash_table_test_function test_function = hash_table->test_function;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
117 hash_size_t size = hash_table->size;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
118 unsigned int hcode_initial =
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
119 hash_table->hash_function ?
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
120 hash_table->hash_function (key) :
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
121 (unsigned long) key;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
122 unsigned int hcode = hcode_initial % size;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
123 hentry *e = &harray [hcode];
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
124 CONST void *e_key = e->key;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
125
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
126 if (!key)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
127 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
128 *ret_value = hash_table->zero_entry;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
129 return (void *) hash_table->zero_set;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
130 }
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
131
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
132 if (e_key ?
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
133 KEYS_DIFFER_P (e_key, key, test_function) :
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
134 e->contents == NULL_ENTRY)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
135 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
136 size_t h2 = size - 2;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
137 unsigned int incr = 1 + (hcode_initial % h2);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
138 do
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
139 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
140 hcode += incr; if (hcode >= size) hcode -= size;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
141 e = &harray [hcode];
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
142 e_key = e->key;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
143 }
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
144 while (e_key ?
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
145 KEYS_DIFFER_P (e_key, key, test_function) :
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
146 e->contents == NULL_ENTRY);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
147 }
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
148
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
149 *ret_value = e->contents;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
150 return e->key;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
151 }
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
152
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
153 void
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
154 clrhash (struct hash_table *hash_table)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
155 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
156 memset (hash_table->harray, 0, sizeof (hentry) * hash_table->size);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
157 hash_table->zero_entry = 0;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
158 hash_table->zero_set = 0;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
159 hash_table->fullness = 0;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
160 }
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
161
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
162 void
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
163 free_hash_table (struct hash_table *hash_table)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
164 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
165 xfree (hash_table->harray);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
166 xfree (hash_table);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
167 }
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
168
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
169 struct hash_table*
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
170 make_hash_table (hash_size_t size)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
171 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
172 struct hash_table *hash_table = xnew_and_zero (struct hash_table);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
173 hash_table->size = prime_size (COMFORTABLE_SIZE (size));
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
174 hash_table->harray = xnew_array (hentry, hash_table->size);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
175 clrhash (hash_table);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
176 return hash_table;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
177 }
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
178
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
179 struct hash_table *
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
180 make_general_hash_table (hash_size_t size,
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
181 hash_table_hash_function hash_function,
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
182 hash_table_test_function test_function)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
183 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
184 struct hash_table* hash_table = make_hash_table (size);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
185 hash_table->hash_function = hash_function;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
186 hash_table->test_function = test_function;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
187 return hash_table;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
188 }
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
189
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
190 #if 0 /* unused strings code */
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
191 struct hash_table *
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
192 make_strings_hash_table (hash_size_t size)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
193 {
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
194 return make_general_hash_table (size, string_hash, string_eq);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
195 }
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
196
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
197 /* from base/generic-hash.cc, and hence from Dragon book, p436 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
198 unsigned long
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
199 string_hash (CONST void *xv)
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
200 {
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
201 unsigned int h = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
202 unsigned CONST char *x = (unsigned CONST char *) xv;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
203
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
204 if (!x) return 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
205
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
206 while (*x != 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
207 {
272
c5d627a313b1 Import from CVS: tag r21-0b34
cvs
parents: 267
diff changeset
208 unsigned int g;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
209 h = (h << 4) + *x++;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
210 if ((g = h & 0xf0000000) != 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
211 h = (h ^ (g >> 24)) ^ g;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
212 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
213
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
214 return h;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
215 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
216
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
217 static int
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
218 string_eq (CONST void *s1, CONST void *s2)
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
219 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
220 return s1 && s2 ? !strcmp ((CONST char *) s1, (CONST char *) s2) : s1 == s2;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
221 }
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
222 #endif /* unused strings code */
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
223
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
224 void
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
225 copy_hash (struct hash_table *dest, struct hash_table *src)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
226 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
227 if (dest->size != src->size)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
228 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
229 xfree (dest->harray);
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
230
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
231 dest->size = src->size;
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
232 dest->harray = xnew_array (hentry, dest->size);
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
233 }
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
234 dest->fullness = src->fullness;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
235 dest->zero_entry = src->zero_entry;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
236 dest->zero_set = src->zero_set;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
237 dest->hash_function = src->hash_function;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
238 dest->test_function = src->test_function;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
239 memcpy (dest->harray, src->harray, sizeof (hentry) * dest->size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
240 }
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
241
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
242 static void
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
243 grow_hash_table (struct hash_table *hash_table, hash_size_t new_size)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
244 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
245 hash_size_t old_size = hash_table->size;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
246 hentry *old_harray = hash_table->harray;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
247 hentry *new_harray;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
248
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
249 new_size = prime_size (new_size);
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
250
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
251 new_harray = xnew_array (hentry, new_size);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
252
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
253 hash_table->size = new_size;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
254 hash_table->harray = new_harray;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
255
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
256 /* do the rehash on the "grown" table */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
257 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
258 long old_zero_set = hash_table->zero_set;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
259 void *old_zero_entry = hash_table->zero_entry;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
260 clrhash (hash_table);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
261 hash_table->zero_set = old_zero_set;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
262 hash_table->zero_entry = old_zero_entry;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
263 rehash (old_harray, hash_table, old_size);
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
264 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
265
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
266 xfree (old_harray);
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
267 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
268
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
269 void
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
270 expand_hash_table (struct hash_table *hash_table, hash_size_t needed_size)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
271 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
272 hash_size_t size = hash_table->size;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
273 hash_size_t comfortable_size = COMFORTABLE_SIZE (needed_size);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
274 if (size < comfortable_size)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
275 grow_hash_table (hash_table, comfortable_size + 1);
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
276 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
277
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
278 void
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
279 puthash (CONST void *key, void *contents, struct hash_table *hash_table)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
280 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
281 hash_table_test_function test_function = hash_table->test_function;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
282 hash_size_t size = hash_table->size;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
283 hash_size_t fullness = hash_table->fullness;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
284 hentry *harray;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
285 CONST void *e_key;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
286 hentry *e;
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
287 unsigned int hcode_initial =
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
288 hash_table->hash_function ?
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
289 hash_table->hash_function (key) :
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
290 (unsigned long) key;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
291 unsigned int hcode;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
292 unsigned int incr = 0;
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
293 size_t h2;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
294 CONST void *oldcontents;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
295
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
296 if (!key)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
297 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
298 hash_table->zero_entry = contents;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
299 hash_table->zero_set = 1;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
300 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
301 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
302
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
303 if (size < (1 + COMFORTABLE_SIZE (fullness)))
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
304 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
305 grow_hash_table (hash_table, size + 1);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
306 size = hash_table->size;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
307 fullness = hash_table->fullness;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
308 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
309
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
310 harray= hash_table->harray;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
311 h2 = size - 2;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
312
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
313 hcode = hcode_initial % size;
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
314
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
315 e_key = harray [hcode].key;
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
316 if (e_key && KEYS_DIFFER_P (e_key, key, test_function))
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
317 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
318 h2 = size - 2;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
319 incr = 1 + (hcode_initial % h2);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
320 do
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
321 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
322 hcode += incr;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
323 if (hcode >= size) hcode -= size;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
324 e_key = harray [hcode].key;
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
325 }
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
326 while (e_key && KEYS_DIFFER_P (e_key, key, test_function));
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
327 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
328 oldcontents = harray [hcode].contents;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
329 harray [hcode].key = key;
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
330 harray [hcode].contents = contents;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
331 /* If the entry that we used was a deleted entry,
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
332 check for a non deleted entry of the same key,
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
333 then delete it. */
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
334 if (!e_key && oldcontents == NULL_ENTRY)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
335 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
336 if (!incr) incr = 1 + ((unsigned long) key % h2);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
337
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
338 do
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
339 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
340 hcode += incr; if (hcode >= size) hcode -= size;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
341 e = &harray [hcode];
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
342 e_key = e->key;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
343 }
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
344 while (e_key ?
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
345 KEYS_DIFFER_P (e_key, key, test_function):
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
346 e->contents == NULL_ENTRY);
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
347
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
348 if (e_key)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
349 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
350 e->key = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
351 e->contents = NULL_ENTRY;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
352 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
353 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
354
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
355 /* only increment the fullness when we used up a new hentry */
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
356 if (!e_key || KEYS_DIFFER_P (e_key, key, test_function))
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
357 hash_table->fullness++;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
358 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
359
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
360 static void
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
361 rehash (hentry *harray, struct hash_table *hash_table, hash_size_t size)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
362 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
363 hentry *limit = harray + size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
364 hentry *e;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
365 for (e = harray; e < limit; e++)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
366 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
367 if (e->key)
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
368 puthash (e->key, e->contents, hash_table);
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
369 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
370 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
371
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
372 void
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
373 remhash (CONST void *key, struct hash_table *hash_table)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
374 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
375 hentry *harray = hash_table->harray;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
376 hash_table_test_function test_function = hash_table->test_function;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
377 hash_size_t size = hash_table->size;
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
378 unsigned int hcode_initial =
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
379 (hash_table->hash_function) ?
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
380 (hash_table->hash_function (key)) :
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
381 ((unsigned long) key);
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
382 unsigned int hcode = hcode_initial % size;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
383 hentry *e = &harray [hcode];
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
384 CONST void *e_key = e->key;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
385
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
386 if (!key)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
387 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
388 hash_table->zero_entry = 0;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
389 hash_table->zero_set = 0;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
390 return;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
391 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
392
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
393 if (e_key ?
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
394 KEYS_DIFFER_P (e_key, key, test_function) :
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
395 e->contents == NULL_ENTRY)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
396 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
397 size_t h2 = size - 2;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
398 unsigned int incr = 1 + (hcode_initial % h2);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
399 do
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
400 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
401 hcode += incr; if (hcode >= size) hcode -= size;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
402 e = &harray [hcode];
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
403 e_key = e->key;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
404 }
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
405 while (e_key?
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
406 KEYS_DIFFER_P (e_key, key, test_function):
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
407 e->contents == NULL_ENTRY);
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
408 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
409 if (e_key)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
410 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
411 e->key = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
412 e->contents = NULL_ENTRY;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
413 /* Note: you can't do fullness-- here, it breaks the world. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
414 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
415 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
416
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
417 void
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
418 maphash (maphash_function mf, struct hash_table *hash_table, void *arg)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
419 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
420 hentry *e;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
421 hentry *limit;
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
422
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
423 if (hash_table->zero_set)
241
f955c73f5258 Import from CVS: tag r20-5b19
cvs
parents: 185
diff changeset
424 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
425 if (mf (0, hash_table->zero_entry, arg))
241
f955c73f5258 Import from CVS: tag r20-5b19
cvs
parents: 185
diff changeset
426 return;
f955c73f5258 Import from CVS: tag r20-5b19
cvs
parents: 185
diff changeset
427 }
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
428
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
429 for (e = hash_table->harray, limit = e + hash_table->size; e < limit; e++)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
430 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
431 if (e->key && mf (e->key, e->contents, arg))
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
432 return;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
433 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
434 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
435
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
436 void
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
437 map_remhash (remhash_predicate predicate, struct hash_table *hash_table, void *arg)
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
438 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
439 hentry *e;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
440 hentry *limit;
173
8eaf7971accc Import from CVS: tag r20-3b13
cvs
parents: 0
diff changeset
441
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
442 if (hash_table->zero_set && predicate (0, hash_table->zero_entry, arg))
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
443 {
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
444 hash_table->zero_set = 0;
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
445 hash_table->zero_entry = 0;
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
446 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
447
380
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
448 for (e = hash_table->harray, limit = e + hash_table->size; e < limit; e++)
8626e4521993 Import from CVS: tag r21-2-5
cvs
parents: 272
diff changeset
449 if (predicate (e->key, e->contents, arg))
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
450 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
451 e->key = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
452 e->contents = NULL_ENTRY;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
453 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
454 }