627751e16adcdd8d9dacee018a44741de2c17903
[pspp-builds.git] / src / libpspp / hash.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <stdbool.h>
19 #include "hash.h"
20 #include "message.h"
21 #include <assert.h>
22 #include <ctype.h>
23 #include <gsl/gsl_math.h>
24 #include <limits.h>
25 #include <stdbool.h>
26 #include <stdlib.h>
27 #include "array.h"
28 #include "compiler.h"
29 #include "misc.h"
30 #include "str.h"
31 #include "pool.h"
32
33 #include "xalloc.h"
34
35 #include "gettext.h"
36 #define _(msgid) gettext (msgid)
37
38 /* Note for constructing hash functions:
39
40    You can store the hash values in the records, then compare hash
41    values (in the compare function) before bothering to compare keys.
42    Hash values can simply be returned from the records instead of
43    recalculating when rehashing. */
44
45 /* Debugging note:
46
47    Since hash_probe and hash_find take void * pointers, it's easy to
48    pass a void ** to your data by accidentally inserting an `&'
49    reference operator where one shouldn't go.  It took me an hour to
50    hunt down a bug like that once. */
51 \f
52 /* Prime numbers and hash functions. */
53
54 /* Returns smallest power of 2 greater than X. */
55 static size_t
56 next_power_of_2 (size_t x)
57 {
58   assert (x != 0);
59
60   for (;;)
61     {
62       /* Turn off rightmost 1-bit in x. */
63       size_t y = x & (x - 1);
64
65       /* If y is 0 then x only had a single 1-bit. */
66       if (y == 0)
67         return 2 * x;
68
69       /* Otherwise turn off the next. */
70       x = y;
71     }
72 }
73
74 /* Fowler-Noll-Vo hash constants, for 32-bit word sizes. */
75 #define FNV_32_PRIME 16777619u
76 #define FNV_32_BASIS 2166136261u
77
78 /* Fowler-Noll-Vo 32-bit hash, for bytes. */
79 unsigned
80 hsh_hash_bytes (const void *buf_, size_t size)
81 {
82   const unsigned char *buf = (const unsigned char *) buf_;
83   unsigned hash;
84
85   assert (buf != NULL);
86
87   hash = FNV_32_BASIS;
88   while (size-- > 0)
89     hash = (hash * FNV_32_PRIME) ^ *buf++;
90
91   return hash;
92 }
93
94 /* Fowler-Noll-Vo 32-bit hash, for strings. */
95 unsigned
96 hsh_hash_string (const char *s_)
97 {
98   const unsigned char *s = (const unsigned char *) s_;
99   unsigned hash;
100
101   assert (s != NULL);
102
103   hash = FNV_32_BASIS;
104   while (*s != '\0')
105     hash = (hash * FNV_32_PRIME) ^ *s++;
106
107   return hash;
108 }
109
110 /* Fowler-Noll-Vo 32-bit hash, for case-insensitive strings. */
111 unsigned
112 hsh_hash_case_string (const char *s_)
113 {
114   const unsigned char *s = (const unsigned char *) s_;
115   unsigned hash;
116
117   assert (s != NULL);
118
119   hash = FNV_32_BASIS;
120   while (*s != '\0')
121     hash = (hash * FNV_32_PRIME) ^ toupper (*s++);
122
123   return hash;
124 }
125
126 /* Hash for ints. */
127 unsigned
128 hsh_hash_int (int i)
129 {
130   return hsh_hash_bytes (&i, sizeof i);
131 }
132
133 /* Hash for double. */
134 unsigned
135 hsh_hash_double (double d)
136 {
137   if (!gsl_isnan (d))
138     return hsh_hash_bytes (&d, sizeof d);
139   else
140     return 0;
141 }
142 \f
143 /* Hash tables. */
144
145 /* Hash table. */
146 struct hsh_table
147   {
148     size_t used;                /* Number of filled entries. */
149     size_t size;                /* Number of entries (a power of 2). */
150     void **entries;             /* Hash table proper. */
151
152     const void *aux;            /* Auxiliary data for comparison functions. */
153     hsh_compare_func *compare;
154     hsh_hash_func *hash;
155     hsh_free_func *free;
156
157 #ifndef NDEBUG
158     /* Set to false if hsh_data() or hsh_sort() has been called,
159        so that most hsh_*() functions may no longer be called. */
160     bool hash_ordered;
161 #endif
162
163     struct pool *pool;         /* The pool used for this hash table */
164   };
165
166 struct hsh_table *
167 hsh_create (int size, hsh_compare_func *compare, hsh_hash_func *hash,
168             hsh_free_func *free, const void *aux)
169 {
170   return hsh_create_pool (NULL, size, compare, hash, free, aux);
171 }
172
173
174
175 /* Creates a hash table with at least M entries.  COMPARE is a
176    function that compares two entries and returns 0 if they are
177    identical, nonzero otherwise; HASH returns a nonnegative hash value
178    for an entry; FREE destroys an entry. */
179 struct hsh_table *
180 hsh_create_pool (struct pool *pool, int size,
181                  hsh_compare_func *compare, hsh_hash_func *hash,
182                  hsh_free_func *free, const void *aux)
183 {
184   struct hsh_table *h;
185   int i;
186
187   assert (compare != NULL);
188   assert (hash != NULL);
189
190   h = pool_malloc (pool, sizeof *h);
191   h->pool = pool;
192   h->used = 0;
193   if (size < 4)
194     size = 4;
195   h->size = next_power_of_2 (size);
196   h->entries = pool_nmalloc (pool, h->size, sizeof *h->entries);
197   for (i = 0; i < h->size; i++)
198     h->entries[i] = NULL;
199   h->aux = aux;
200   h->compare = compare;
201   h->hash = hash;
202   h->free = free;
203 #ifndef NDEBUG
204   h->hash_ordered = true;
205 #endif
206   return h;
207 }
208
209 /* Destroys the contents of table H. */
210 void
211 hsh_clear (struct hsh_table *h)
212 {
213   int i;
214
215   assert (h != NULL);
216   if (h->free)
217     for (i = 0; i < h->size; i++)
218       if (h->entries[i] != NULL)
219         h->free (h->entries[i], h->aux);
220
221   for (i = 0; i < h->size; i++)
222     h->entries[i] = NULL;
223
224   h->used = 0;
225
226 #ifndef NDEBUG
227   h->hash_ordered = true;
228 #endif
229 }
230
231 /* Destroys table H and all its contents. */
232 void
233 hsh_destroy (struct hsh_table *h)
234 {
235   int i;
236
237   if (h != NULL)
238     {
239       if (h->free)
240         for (i = 0; i < h->size; i++)
241           if (h->entries[i] != NULL)
242             h->free (h->entries[i], h->aux);
243       pool_free (h->pool, h->entries);
244       pool_free (h->pool, h);
245     }
246 }
247
248 /* Locates an entry matching TARGET.  Returns the index for the
249    entry, if found, or the index of an empty entry that indicates
250    where TARGET should go, otherwise. */
251 static inline unsigned
252 locate_matching_entry (struct hsh_table *h, const void *target)
253 {
254   unsigned i = h->hash (target, h->aux);
255
256   assert (h->hash_ordered);
257   for (;;)
258     {
259       void *entry;
260       i &= h->size - 1;
261       entry = h->entries[i];
262       if (entry == NULL || !h->compare (entry, target, h->aux))
263         return i;
264       i--;
265     }
266 }
267
268 /* Returns the index of an empty entry that indicates
269    where TARGET should go, assuming that TARGET is not equal to
270    any item already in the hash table. */
271 static inline unsigned
272 locate_empty_entry (struct hsh_table *h, const void *target)
273 {
274   unsigned i = h->hash (target, h->aux);
275
276   assert (h->hash_ordered);
277   for (;;)
278     {
279       i &= h->size - 1;
280       if (h->entries[i] == NULL)
281         return i;
282       i--;
283     }
284 }
285
286 /* Changes the capacity of H to NEW_SIZE, which must be a
287    positive power of 2 at least as large as the number of
288    elements in H. */
289 static void
290 rehash (struct hsh_table *h, size_t new_size)
291 {
292   void **begin, **end, **table_p;
293   int i;
294
295   assert (h != NULL);
296   assert (new_size >= h->used);
297
298   /* Verify that NEW_SIZE is a positive power of 2. */
299   assert (new_size > 0 && (new_size & (new_size - 1)) == 0);
300
301   begin = h->entries;
302   end = begin + h->size;
303
304   h->size = new_size;
305   h->entries = pool_nmalloc (h->pool, h->size, sizeof *h->entries);
306   for (i = 0; i < h->size; i++)
307     h->entries[i] = NULL;
308   for (table_p = begin; table_p < end; table_p++)
309     {
310       void *entry = *table_p;
311       if (entry != NULL)
312         h->entries[locate_empty_entry (h, entry)] = entry;
313     }
314   pool_free (h->pool, begin);
315
316 #ifndef NDEBUG
317   h->hash_ordered = true;
318 #endif
319 }
320
321 /* A "algo_predicate_func" that returns true if DATA points
322    to a non-null void. */
323 static bool
324 not_null (const void *data_, const void *aux UNUSED)
325 {
326   void *const *data = data_;
327
328   return *data != NULL;
329 }
330
331 /* Compacts hash table H and returns a pointer to its data.  The
332    returned data consists of hsh_count(H) non-null pointers, in
333    no particular order, followed by a null pointer.
334
335    After calling this function, only hsh_destroy() and
336    hsh_count() should be applied to H.  hsh_first() and
337    hsh_next() could also be used, but you're better off just
338    iterating through the returned array.
339
340    This function is intended for use in situations where data
341    processing occurs in two phases.  In the first phase, data is
342    added, removed, and searched for within a hash table.  In the
343    second phase, the contents of the hash table are output and
344    the hash property itself is no longer of interest.
345
346    Use hsh_sort() instead, if the second phase wants data in
347    sorted order.  Use hsh_data_copy() or hsh_sort_copy() instead,
348    if the second phase still needs to search the hash table. */
349 void *const *
350 hsh_data (struct hsh_table *h)
351 {
352   size_t n;
353
354   assert (h != NULL);
355   n = partition (h->entries, h->size, sizeof *h->entries, not_null, NULL);
356   assert (n == h->used);
357 #ifndef NDEBUG
358   h->hash_ordered = false;
359 #endif
360   return h->entries;
361 }
362
363 /* Dereferences void ** pointers and passes them to the hash
364    comparison function. */
365 static int
366 comparison_helper (const void *a_, const void *b_, const void *h_)
367 {
368   void *const *a = a_;
369   void *const *b = b_;
370   const struct hsh_table *h = h_;
371
372   assert(a);
373   assert(b);
374
375   return h->compare (*a, *b, h->aux);
376 }
377
378 /* Sorts hash table H based on hash comparison function.  The
379    returned data consists of hsh_count(H) non-null pointers,
380    sorted in order of the hash comparison function, followed by a
381    null pointer.
382
383    After calling this function, only hsh_destroy() and
384    hsh_count() should be applied to H.  hsh_first() and
385    hsh_next() could also be used, but you're better off just
386    iterating through the returned array.
387
388    This function is intended for use in situations where data
389    processing occurs in two phases.  In the first phase, data is
390    added, removed, and searched for within a hash table.  In the
391    second phase, the contents of the hash table are output and
392    the hash property itself is no longer of interest.
393
394    Use hsh_data() instead, if the second phase doesn't need the
395    data in any particular order.  Use hsh_data_copy() or
396    hsh_sort_copy() instead, if the second phase still needs to
397    search the hash table. */
398 void *const *
399 hsh_sort (struct hsh_table *h)
400 {
401   assert (h != NULL);
402
403   hsh_data (h);
404   sort (h->entries, h->used, sizeof *h->entries, comparison_helper, h);
405   return h->entries;
406 }
407
408 /* Makes and returns a copy of the pointers to the data in H.
409    The returned data consists of hsh_count(H) non-null pointers,
410    in no particular order, followed by a null pointer.  The hash
411    table is not modified.  The caller is responsible for freeing
412    the allocated data.
413
414    If you don't need to search or modify the hash table, then
415    hsh_data() is a more efficient choice. */
416 void **
417 hsh_data_copy (struct hsh_table *h)
418 {
419   void **copy;
420
421   assert (h != NULL);
422   copy = pool_nmalloc (h->pool, (h->used + 1), sizeof *copy);
423   copy_if (h->entries, h->size, sizeof *h->entries, copy, not_null, NULL);
424   copy[h->used] = NULL;
425   return copy;
426 }
427
428 /* Makes and returns a copy of the pointers to the data in H.
429    The returned data consists of hsh_count(H) non-null pointers,
430    sorted in order of the hash comparison function, followed by a
431    null pointer.  The hash table is not modified.  The caller is
432    responsible for freeing the allocated data.
433
434    If you don't need to search or modify the hash table, then
435    hsh_sort() is a more efficient choice. */
436 void **
437 hsh_sort_copy (struct hsh_table *h)
438 {
439   void **copy;
440
441   assert (h != NULL);
442   copy = hsh_data_copy (h);
443   sort (copy, h->used, sizeof *copy, comparison_helper, h);
444   return copy;
445 }
446 \f
447 /* Hash entries. */
448
449 /* Searches hash table H for TARGET.  If found, returns a pointer
450    to a pointer to that entry; otherwise returns a pointer to a
451    NULL entry which *must* be used to insert a new entry having
452    the same key data.  */
453 void **
454 hsh_probe (struct hsh_table *h, const void *target)
455 {
456   unsigned i;
457
458   assert (h != NULL);
459   assert (target != NULL);
460   assert (h->hash_ordered);
461
462   if (h->used > h->size / 2)
463     rehash (h, h->size * 2);
464   i = locate_matching_entry (h, target);
465   if (h->entries[i] == NULL)
466     h->used++;
467   return &h->entries[i];
468 }
469
470 /* Searches hash table H for TARGET.  If not found, inserts
471    TARGET and returns a null pointer.  If found, returns the
472    match, without replacing it in the table. */
473 void *
474 hsh_insert (struct hsh_table *h, void *target)
475 {
476   void **entry;
477
478   assert (h != NULL);
479   assert (target != NULL);
480
481   entry = hsh_probe (h, target);
482   if (*entry == NULL)
483     {
484       *entry = target;
485       return NULL;
486     }
487   else
488     return *entry;
489 }
490
491 /* Searches hash table H for TARGET.  If not found, inserts
492    TARGET and returns a null pointer.  If found, returns the
493    match, after replacing it in the table by TARGET. */
494 void *
495 hsh_replace (struct hsh_table *h, void *target)
496 {
497   void **entry = hsh_probe (h, target);
498   void *old = *entry;
499   *entry = target;
500   return old;
501 }
502
503 /* Returns the entry in hash table H that matches TARGET, or NULL
504    if there is none. */
505 void *
506 hsh_find (struct hsh_table *h, const void *target)
507 {
508   return h->entries[locate_matching_entry (h, target)];
509 }
510
511 /* Deletes the entry in hash table H that matches TARGET.
512    Returns true if an entry was deleted.
513
514    Uses Knuth's Algorithm 6.4R (Deletion with linear probing).
515    Because our load factor is at most 1/2, the average number of
516    moves that this algorithm makes should be at most 2 - ln 2 ~=
517    1.65. */
518 bool
519 hsh_delete (struct hsh_table *h, const void *target)
520 {
521   unsigned i = locate_matching_entry (h, target);
522   if (h->entries[i] != NULL)
523     {
524       h->used--;
525       if (h->free != NULL)
526         h->free (h->entries[i], h->aux);
527
528       for (;;)
529         {
530           unsigned r;
531           ptrdiff_t j;
532
533           h->entries[i] = NULL;
534           j = i;
535           do
536             {
537               i = (i - 1) & (h->size - 1);
538               if (h->entries[i] == NULL)
539                 return true;
540
541               r = h->hash (h->entries[i], h->aux) & (h->size - 1);
542             }
543           while ((i <= r && r < j) || (r < j && j < i) || (j < i && i <= r));
544           h->entries[j] = h->entries[i];
545         }
546     }
547   else
548     return false;
549 }
550 \f
551 /* Iteration. */
552
553 /* Finds and returns an entry in TABLE, and initializes ITER for
554    use with hsh_next().  If TABLE is empty, returns a null
555    pointer. */
556 void *
557 hsh_first (struct hsh_table *h, struct hsh_iterator *iter)
558 {
559   assert (h != NULL);
560   assert (iter != NULL);
561
562   iter->next = 0;
563   return hsh_next (h, iter);
564 }
565
566 /* Iterates through TABLE with iterator ITER.  Returns the next
567    entry in TABLE, or a null pointer after the last entry.
568
569    Entries are returned in an undefined order.  Modifying TABLE
570    during iteration may cause some entries to be returned
571    multiple times or not at all. */
572 void *
573 hsh_next (struct hsh_table *h, struct hsh_iterator *iter)
574 {
575   size_t i;
576
577   assert (h != NULL);
578   assert (iter != NULL);
579   assert (iter->next <= h->size);
580
581   for (i = iter->next; i < h->size; i++)
582     if (h->entries[i])
583       {
584         iter->next = i + 1;
585         return h->entries[i];
586       }
587
588   iter->next = h->size;
589   return NULL;
590 }
591 \f
592 /* Returns the number of items in H. */
593 size_t
594 hsh_count (struct hsh_table *h)
595 {
596   assert (h != NULL);
597
598   return h->used;
599 }
600 \f
601 /* Debug helpers. */
602
603 #if DEBUGGING
604 #undef NDEBUG
605 #include "message.h"
606 #include <stdio.h>
607
608 /* Displays contents of hash table H on stdout. */
609 void
610 hsh_dump (struct hsh_table *h)
611 {
612   void **entry = h->entries;
613   int i;
614
615   printf (_("hash table:"));
616   for (i = 0; i < h->size; i++)
617     printf (" %p", *entry++);
618   printf ("\n");
619 }
620
621 /* This wrapper around hsh_probe() assures that it returns a pointer
622    to a NULL pointer.  This function is used when it is known that the
623    entry to be inserted does not already exist in the table. */
624 void
625 hsh_force_insert (struct hsh_table *h, void *p)
626 {
627   void **pp = hsh_probe (h, p);
628   assert (*pp == NULL);
629   *pp = p;
630 }
631
632 /* This wrapper around hsh_find() assures that it returns non-NULL.
633    This function is for use when it is known that the entry being
634    searched for must exist in the table. */
635 void *
636 hsh_force_find (struct hsh_table *h, const void *target)
637 {
638   void *found = hsh_find (h, target);
639   assert (found != NULL);
640   return found;
641 }
642
643 /* This wrapper for hsh_delete() verifies that an item really was
644    deleted. */
645 void
646 hsh_force_delete (struct hsh_table *h, const void *target)
647 {
648   int found = hsh_delete (h, target);
649   assert (found != 0);
650 }
651 #endif