1 /* PSPP - computes sample statistics.
2 Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 #include "quicksort.h"
32 size_t used; /* Number of filled entries. */
33 size_t size; /* Number of entries (a power of 2). */
34 void **entries; /* Hash table proper. */
37 hsh_compare_func *compare;
42 /* Note for constructing hash functions:
44 You can store the hash values in the records, then compare hash
45 values (in the compare function) before bothering to compare keys.
46 Hash values can simply be returned from the records instead of
47 recalculating when rehashing. */
51 Since hash_probe and hash_find take void * pointers, it's easy to
52 pass a void ** to your data by accidentally inserting an `&'
53 reference operator where one shouldn't go. It took me an hour to
54 hunt down a bug like that once. */
56 /* Prime numbers and hash functions. */
58 /* Returns smallest power of 2 greater than X. */
60 next_power_of_2 (size_t x)
66 /* Turn off rightmost 1-bit in x. */
67 size_t y = x & (x - 1);
69 /* If y is 0 then x only had a single 1-bit. */
73 /* Otherwise turn off the next. */
78 /* Colin Plumb's "one-at-a-time" hash, for bytes. */
80 hsh_hash_bytes (const void *buf_, size_t size)
82 const unsigned char *buf = buf_;
96 /* Colin Plumb's "one-at-a-time" hash, for strings. */
98 hsh_hash_string (const char *s_)
100 const unsigned char *s = s_;
105 hash += (hash << 10);
109 hash ^= (hash >> 11);
110 hash += (hash << 15);
118 return hsh_hash_bytes (&i, sizeof i);
123 /* Creates a hash table with at least M entries. COMPARE is a
124 function that compares two entries and returns 0 if they are
125 identical, nonzero otherwise; HASH returns a nonnegative hash value
126 for an entry; FREE destroys an entry. */
128 hsh_create (int size, hsh_compare_func *compare, hsh_hash_func *hash,
129 hsh_free_func *free, void *param)
131 struct hsh_table *h = xmalloc (sizeof *h);
135 h->size = next_power_of_2 (size);
136 h->entries = xmalloc (sizeof *h->entries * h->size);
137 for (i = 0; i < h->size; i++)
138 h->entries[i] = NULL;
140 h->compare = compare;
146 /* Destroys the contents of table H. */
148 hsh_clear (struct hsh_table *h)
153 for (i = 0; i < h->size; i++)
154 if (h->entries[i] != NULL)
155 h->free (h->entries[i], h->param);
157 for (i = 0; i < h->size; i++)
158 h->entries[i] = NULL;
161 /* Destroys table H and all its contents. */
163 hsh_destroy (struct hsh_table *h)
170 for (i = 0; i < h->size; i++)
171 if (h->entries[i] != NULL)
172 h->free (h->entries[i], h->param);
177 /* Changes the capacity of H to NEW_SIZE. */
179 hsh_rehash (struct hsh_table *h, size_t new_size)
181 void **begin = h->entries;
182 void **end = &h->entries[h->size];
187 h->entries = xmalloc (sizeof *h->entries * h->size);
188 for (i = 0; i < h->size; i++)
189 h->entries[i] = NULL;
190 for (table_p = begin; table_p < end; table_p++)
194 if (*table_p == NULL)
196 entry = &h->entries[h->hash (*table_p, h->param) & (h->size - 1)];
198 if (--entry < h->entries)
199 entry = &h->entries[h->size - 1];
205 /* hsh_sort() helper function that ensures NULLs are sorted after the
206 rest of the table. */
208 sort_nulls_last (const void *a_, const void *b_, void *h_)
210 void *a = *(void **) a_;
211 void *b = *(void **) b_;
212 struct hsh_table *h = h_;
217 return h->compare (a, b, h->param);
230 /* Sorts hash table H based on hash comparison function. NULLs
231 are sent to the end of the table. The resultant table is
232 returned (it is guaranteed to be NULL-terminated). H should
233 not be used again as a hash table until and unless hsh_clear()
236 hsh_sort (struct hsh_table *h)
238 quicksort (h->entries, h->size, sizeof *h->entries, sort_nulls_last, h);
244 /* Searches hash table H for TARGET. If found, returns a pointer to a
245 pointer to that entry; otherwise returns a pointer to a NULL entry
246 which _must_ be used to insert a new entry having the same key
249 hsh_probe (struct hsh_table *h, const void *target)
253 /* Order of these statements is important! */
254 if (h->used > h->size / 2)
255 hsh_rehash (h, h->size * 2);
256 entry = &h->entries[h->hash (target, h->param) & (h->size - 1)];
260 if (!h->compare (*entry, target, h->param))
262 if (--entry < h->entries)
263 entry = &h->entries[h->size - 1];
269 /* Locates an entry matching TARGET. Returns a pointer to the
270 entry, or a null pointer on failure. */
271 static inline void **
272 locate_matching_entry (struct hsh_table *h, const void *target)
274 void **entry = &h->entries[h->hash (target, h->param) & (h->size - 1)];
278 if (!h->compare (*entry, target, h->param))
280 if (--entry < h->entries)
281 entry = &h->entries[h->size - 1];
286 /* Returns the entry in hash table H that matches TARGET, or NULL
289 hsh_find (struct hsh_table *h, const void *target)
291 void **entry = locate_matching_entry (h, target);
292 return entry != NULL ? *entry : NULL;
295 /* Deletes the entry in hash table H that matches TARGET.
296 Returns nonzero if an entry was deleted.
298 Note: this function is very slow because it rehashes the
299 entire table. Don't use this hash table implementation if
300 deletion is a common operation. */
302 hsh_delete (struct hsh_table *h, const void *target)
304 void **entry = locate_matching_entry (h, target);
307 h->free (*entry, h->param);
309 hsh_rehash (h, h->size);
318 /* Finds and returns an entry in TABLE, and initializes ITER for
319 use with hsh_next(). If TABLE is empty, returns a null
322 hsh_first (struct hsh_table *h, struct hsh_iterator *iter)
325 assert (iter != NULL);
328 return hsh_next (h, iter);
331 /* Iterates through TABLE with iterator ITER. Returns the next
332 entry in TABLE, or a null pointer after the last entry.
334 Entries are returned in an undefined order. Modifying TABLE
335 during iteration may cause some entries to be returned
336 multiple times or not at all. */
338 hsh_next (struct hsh_table *h, struct hsh_iterator *iter)
343 assert (iter != NULL);
344 assert (iter->next <= h->size);
346 for (i = iter->next; i < h->size; i++)
350 return h->entries[i];
353 iter->next = h->size;
357 /* Returns the number of items in H. */
359 hsh_count (struct hsh_table *h)
373 /* Displays contents of hash table H on stdout. */
375 hsh_dump (struct hsh_table *h)
377 void **entry = h->entries;
380 printf (_("hash table:"));
381 for (i = 0; i < h->size; i++)
382 printf (" %p", *entry++);
386 /* This wrapper around hsh_probe() assures that it returns a pointer
387 to a NULL pointer. This function is used when it is known that the
388 entry to be inserted does not already exist in the table. */
390 hsh_force_insert (struct hsh_table *h, void *p)
392 void **pp = hsh_probe (h, p);
393 assert (*pp == NULL);
397 /* This wrapper around hsh_find() assures that it returns non-NULL.
398 This function is for use when it is known that the entry being
399 searched for must exist in the table. */
401 hsh_force_find (struct hsh_table *h, const void *target)
403 void *found = hsh_find (h, target);
404 assert (found != NULL);
408 /* This wrapper for hsh_delete() verifies that an item really was
411 hsh_force_delete (struct hsh_table *h, const void *target)
413 int found = hsh_delete (h, target);