Daily bump.
[gcc.git] / gcc / hash-table.h
1 /* A type-safe hash table template.
2 Copyright (C) 2012-2014 Free Software Foundation, Inc.
3 Contributed by Lawrence Crowl <crowl@google.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21
22 /* This file implements a typed hash table.
23 The implementation borrows from libiberty's htab_t in hashtab.h.
24
25
26 INTRODUCTION TO TYPES
27
28 Users of the hash table generally need to be aware of three types.
29
30 1. The type being placed into the hash table. This type is called
31 the value type.
32
33 2. The type used to describe how to handle the value type within
34 the hash table. This descriptor type provides the hash table with
35 several things.
36
37 - A typedef named 'value_type' to the value type (from above).
38
39 - A static member function named 'hash' that takes a value_type
40 pointer and returns a hashval_t value.
41
42 - A typedef named 'compare_type' that is used to test when an value
43 is found. This type is the comparison type. Usually, it will be the
44 same as value_type. If it is not the same type, you must generally
45 explicitly compute hash values and pass them to the hash table.
46
47 - A static member function named 'equal' that takes a value_type
48 pointer and a compare_type pointer, and returns a bool.
49
50 - A static function named 'remove' that takes an value_type pointer
51 and frees the memory allocated by it. This function is used when
52 individual elements of the table need to be disposed of (e.g.,
53 when deleting a hash table, removing elements from the table, etc).
54
55 3. The type of the hash table itself. (More later.)
56
57 In very special circumstances, users may need to know about a fourth type.
58
59 4. The template type used to describe how hash table memory
60 is allocated. This type is called the allocator type. It is
61 parameterized on the value type. It provides four functions.
62
63 - A static member function named 'data_alloc'. This function
64 allocates the data elements in the table.
65
66 - A static member function named 'data_free'. This function
67 deallocates the data elements in the table.
68
69 Hash table are instantiated with two type arguments.
70
71 * The descriptor type, (2) above.
72
73 * The allocator type, (4) above. In general, you will not need to
74 provide your own allocator type. By default, hash tables will use
75 the class template xcallocator, which uses malloc/free for allocation.
76
77
78 DEFINING A DESCRIPTOR TYPE
79
80 The first task in using the hash table is to describe the element type.
81 We compose this into a few steps.
82
83 1. Decide on a removal policy for values stored in the table.
84 This header provides class templates for the two most common
85 policies.
86
87 * typed_free_remove implements the static 'remove' member function
88 by calling free().
89
90 * typed_noop_remove implements the static 'remove' member function
91 by doing nothing.
92
93 You can use these policies by simply deriving the descriptor type
94 from one of those class template, with the appropriate argument.
95
96 Otherwise, you need to write the static 'remove' member function
97 in the descriptor class.
98
99 2. Choose a hash function. Write the static 'hash' member function.
100
101 3. Choose an equality testing function. In most cases, its two
102 arguments will be value_type pointers. If not, the first argument must
103 be a value_type pointer, and the second argument a compare_type pointer.
104
105
106 AN EXAMPLE DESCRIPTOR TYPE
107
108 Suppose you want to put some_type into the hash table. You could define
109 the descriptor type as follows.
110
111 struct some_type_hasher : typed_noop_remove <some_type>
112 // Deriving from typed_noop_remove means that we get a 'remove' that does
113 // nothing. This choice is good for raw values.
114 {
115 typedef some_type value_type;
116 typedef some_type compare_type;
117 static inline hashval_t hash (const value_type *);
118 static inline bool equal (const value_type *, const compare_type *);
119 };
120
121 inline hashval_t
122 some_type_hasher::hash (const value_type *e)
123 { ... compute and return a hash value for E ... }
124
125 inline bool
126 some_type_hasher::equal (const value_type *p1, const compare_type *p2)
127 { ... compare P1 vs P2. Return true if they are the 'same' ... }
128
129
130 AN EXAMPLE HASH_TABLE DECLARATION
131
132 To instantiate a hash table for some_type:
133
134 hash_table <some_type_hasher> some_type_hash_table;
135
136 There is no need to mention some_type directly, as the hash table will
137 obtain it using some_type_hasher::value_type.
138
139 You can then used any of the functions in hash_table's public interface.
140 See hash_table for details. The interface is very similar to libiberty's
141 htab_t.
142
143
144 EASY DESCRIPTORS FOR POINTERS
145
146 The class template pointer_hash provides everything you need to hash
147 pointers (as opposed to what they point to). So, to instantiate a hash
148 table over pointers to whatever_type,
149
150 hash_table <pointer_hash <whatever_type>> whatever_type_hash_table;
151
152
153 HASH TABLE ITERATORS
154
155 The hash table provides standard C++ iterators. For example, consider a
156 hash table of some_info. We wish to consume each element of the table:
157
158 extern void consume (some_info *);
159
160 We define a convenience typedef and the hash table:
161
162 typedef hash_table <some_info_hasher> info_table_type;
163 info_table_type info_table;
164
165 Then we write the loop in typical C++ style:
166
167 for (info_table_type::iterator iter = info_table.begin ();
168 iter != info_table.end ();
169 ++iter)
170 if ((*iter).status == INFO_READY)
171 consume (&*iter);
172
173 Or with common sub-expression elimination:
174
175 for (info_table_type::iterator iter = info_table.begin ();
176 iter != info_table.end ();
177 ++iter)
178 {
179 some_info &elem = *iter;
180 if (elem.status == INFO_READY)
181 consume (&elem);
182 }
183
184 One can also use a more typical GCC style:
185
186 typedef some_info *some_info_p;
187 some_info *elem_ptr;
188 info_table_type::iterator iter;
189 FOR_EACH_HASH_TABLE_ELEMENT (info_table, elem_ptr, some_info_p, iter)
190 if (elem_ptr->status == INFO_READY)
191 consume (elem_ptr);
192
193 */
194
195
196 #ifndef TYPED_HASHTAB_H
197 #define TYPED_HASHTAB_H
198
199 #include "hashtab.h"
200
201
202 /* The ordinary memory allocator. */
203 /* FIXME (crowl): This allocator may be extracted for wider sharing later. */
204
205 template <typename Type>
206 struct xcallocator
207 {
208 static Type *data_alloc (size_t count);
209 static void data_free (Type *memory);
210 };
211
212
213 /* Allocate memory for COUNT data blocks. */
214
215 template <typename Type>
216 inline Type *
217 xcallocator <Type>::data_alloc (size_t count)
218 {
219 return static_cast <Type *> (xcalloc (count, sizeof (Type)));
220 }
221
222
223 /* Free memory for data blocks. */
224
225 template <typename Type>
226 inline void
227 xcallocator <Type>::data_free (Type *memory)
228 {
229 return ::free (memory);
230 }
231
232
233 /* Helpful type for removing with free. */
234
235 template <typename Type>
236 struct typed_free_remove
237 {
238 static inline void remove (Type *p);
239 };
240
241
242 /* Remove with free. */
243
244 template <typename Type>
245 inline void
246 typed_free_remove <Type>::remove (Type *p)
247 {
248 free (p);
249 }
250
251
252 /* Helpful type for a no-op remove. */
253
254 template <typename Type>
255 struct typed_noop_remove
256 {
257 static inline void remove (Type *p);
258 };
259
260
261 /* Remove doing nothing. */
262
263 template <typename Type>
264 inline void
265 typed_noop_remove <Type>::remove (Type *p ATTRIBUTE_UNUSED)
266 {
267 }
268
269
270 /* Pointer hash with a no-op remove method. */
271
272 template <typename Type>
273 struct pointer_hash : typed_noop_remove <Type>
274 {
275 typedef Type *value_type;
276 typedef Type *compare_type;
277 typedef int store_values_directly;
278
279 static inline hashval_t hash (const value_type &);
280
281 static inline bool equal (const value_type &existing, const compare_type &candidate);
282 };
283
284 template <typename Type>
285 inline hashval_t
286 pointer_hash <Type>::hash (const value_type &candidate)
287 {
288 /* This is a really poor hash function, but it is what the current code uses,
289 so I am reusing it to avoid an additional axis in testing. */
290 return (hashval_t) ((intptr_t)candidate >> 3);
291 }
292
293 template <typename Type>
294 inline bool
295 pointer_hash <Type>::equal (const value_type &existing,
296 const compare_type &candidate)
297 {
298 return existing == candidate;
299 }
300
301
302 /* Table of primes and their inversion information. */
303
304 struct prime_ent
305 {
306 hashval_t prime;
307 hashval_t inv;
308 hashval_t inv_m2; /* inverse of prime-2 */
309 hashval_t shift;
310 };
311
312 extern struct prime_ent const prime_tab[];
313
314
315 /* Functions for computing hash table indexes. */
316
317 extern unsigned int hash_table_higher_prime_index (unsigned long n);
318 extern hashval_t hash_table_mod1 (hashval_t hash, unsigned int index);
319 extern hashval_t hash_table_mod2 (hashval_t hash, unsigned int index);
320
321 /* The below is some template meta programming to decide if we should use the
322 hash table partial specialization that directly stores value_type instead of
323 pointers to value_type. If the Descriptor type defines the type
324 Descriptor::store_values_directly then values are stored directly otherwise
325 pointers to them are stored. */
326 template<typename T> struct notype { typedef void type; };
327
328 template<typename T, typename = void>
329 struct storage_tester
330 {
331 static const bool value = false;
332 };
333
334 template<typename T>
335 struct storage_tester<T, typename notype<typename
336 T::store_values_directly>::type>
337 {
338 static const bool value = true;
339 };
340
341 template<typename Traits>
342 struct has_is_deleted
343 {
344 template<typename U, bool (*)(U &)> struct helper {};
345 template<typename U> static char test (helper<U, U::is_deleted> *);
346 template<typename U> static int test (...);
347 static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
348 };
349
350 template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
351 struct is_deleted_helper
352 {
353 static inline bool
354 call (Type &v)
355 {
356 return Traits::is_deleted (v);
357 }
358 };
359
360 template<typename Type, typename Traits>
361 struct is_deleted_helper<Type *, Traits, false>
362 {
363 static inline bool
364 call (Type *v)
365 {
366 return v == HTAB_DELETED_ENTRY;
367 }
368 };
369
370 template<typename Traits>
371 struct has_is_empty
372 {
373 template<typename U, bool (*)(U &)> struct helper {};
374 template<typename U> static char test (helper<U, U::is_empty> *);
375 template<typename U> static int test (...);
376 static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
377 };
378
379 template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
380 struct is_empty_helper
381 {
382 static inline bool
383 call (Type &v)
384 {
385 return Traits::is_empty (v);
386 }
387 };
388
389 template<typename Type, typename Traits>
390 struct is_empty_helper<Type *, Traits, false>
391 {
392 static inline bool
393 call (Type *v)
394 {
395 return v == HTAB_EMPTY_ENTRY;
396 }
397 };
398
399 template<typename Traits>
400 struct has_mark_deleted
401 {
402 template<typename U, void (*)(U &)> struct helper {};
403 template<typename U> static char test (helper<U, U::mark_deleted> *);
404 template<typename U> static int test (...);
405 static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
406 };
407
408 template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
409 struct mark_deleted_helper
410 {
411 static inline void
412 call (Type &v)
413 {
414 Traits::mark_deleted (v);
415 }
416 };
417
418 template<typename Type, typename Traits>
419 struct mark_deleted_helper<Type *, Traits, false>
420 {
421 static inline void
422 call (Type *&v)
423 {
424 v = static_cast<Type *> (HTAB_DELETED_ENTRY);
425 }
426 };
427
428 template<typename Traits>
429 struct has_mark_empty
430 {
431 template<typename U, void (*)(U &)> struct helper {};
432 template<typename U> static char test (helper<U, U::mark_empty> *);
433 template<typename U> static int test (...);
434 static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
435 };
436
437 template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
438 struct mark_empty_helper
439 {
440 static inline void
441 call (Type &v)
442 {
443 Traits::mark_empty (v);
444 }
445 };
446
447 template<typename Type, typename Traits>
448 struct mark_empty_helper<Type *, Traits, false>
449 {
450 static inline void
451 call (Type *&v)
452 {
453 v = static_cast<Type *> (HTAB_EMPTY_ENTRY);
454 }
455 };
456
457 /* User-facing hash table type.
458
459 The table stores elements of type Descriptor::value_type, or pointers to
460 objects of type value_type if the descriptor does not define the type
461 store_values_directly.
462
463 It hashes values with the hash member function.
464 The table currently works with relatively weak hash functions.
465 Use typed_pointer_hash <Value> when hashing pointers instead of objects.
466
467 It compares elements with the equal member function.
468 Two elements with the same hash may not be equal.
469 Use typed_pointer_equal <Value> when hashing pointers instead of objects.
470
471 It removes elements with the remove member function.
472 This feature is useful for freeing memory.
473 Derive from typed_null_remove <Value> when not freeing objects.
474 Derive from typed_free_remove <Value> when doing a simple object free.
475
476 Specify the template Allocator to allocate and free memory.
477 The default is xcallocator.
478
479 Storage is an implementation detail and should not be used outside the
480 hash table code.
481
482 */
483 template <typename Descriptor,
484 template<typename Type> class Allocator= xcallocator,
485 bool Storage = storage_tester<Descriptor>::value>
486 class hash_table
487 {
488 };
489
490 template <typename Descriptor,
491 template<typename Type> class Allocator>
492 class hash_table<Descriptor, Allocator, false>
493 {
494 typedef typename Descriptor::value_type value_type;
495 typedef typename Descriptor::compare_type compare_type;
496
497 public:
498 hash_table (size_t);
499 ~hash_table ();
500
501 /* Current size (in entries) of the hash table. */
502 size_t size () const { return m_size; }
503
504 /* Return the current number of elements in this hash table. */
505 size_t elements () const { return m_n_elements - m_n_deleted; }
506
507 /* Return the current number of elements in this hash table. */
508 size_t elements_with_deleted () const { return m_n_elements; }
509
510 /* This function clears all entries in the given hash table. */
511 void empty ();
512
513 /* This function clears a specified SLOT in a hash table. It is
514 useful when you've already done the lookup and don't want to do it
515 again. */
516
517 void clear_slot (value_type **);
518
519 /* This function searches for a hash table entry equal to the given
520 COMPARABLE element starting with the given HASH value. It cannot
521 be used to insert or delete an element. */
522 value_type *find_with_hash (const compare_type *, hashval_t);
523
524 /* Like find_slot_with_hash, but compute the hash value from the element. */
525 value_type *find (const value_type *value)
526 {
527 return find_with_hash (value, Descriptor::hash (value));
528 }
529
530 value_type **find_slot (const value_type *value, insert_option insert)
531 {
532 return find_slot_with_hash (value, Descriptor::hash (value), insert);
533 }
534
535 /* This function searches for a hash table slot containing an entry
536 equal to the given COMPARABLE element and starting with the given
537 HASH. To delete an entry, call this with insert=NO_INSERT, then
538 call clear_slot on the slot returned (possibly after doing some
539 checks). To insert an entry, call this with insert=INSERT, then
540 write the value you want into the returned slot. When inserting an
541 entry, NULL may be returned if memory allocation fails. */
542 value_type **find_slot_with_hash (const compare_type *comparable,
543 hashval_t hash, enum insert_option insert);
544
545 /* This function deletes an element with the given COMPARABLE value
546 from hash table starting with the given HASH. If there is no
547 matching element in the hash table, this function does nothing. */
548 void remove_elt_with_hash (const compare_type *, hashval_t);
549
550 /* Like remove_elt_with_hash, but compute the hash value from the element. */
551 void remove_elt (const value_type *value)
552 {
553 remove_elt_with_hash (value, Descriptor::hash (value));
554 }
555
556 /* This function scans over the entire hash table calling CALLBACK for
557 each live entry. If CALLBACK returns false, the iteration stops.
558 ARGUMENT is passed as CALLBACK's second argument. */
559 template <typename Argument,
560 int (*Callback) (value_type **slot, Argument argument)>
561 void traverse_noresize (Argument argument);
562
563 /* Like traverse_noresize, but does resize the table when it is too empty
564 to improve effectivity of subsequent calls. */
565 template <typename Argument,
566 int (*Callback) (value_type **slot, Argument argument)>
567 void traverse (Argument argument);
568
569 class iterator
570 {
571 public:
572 iterator () : m_slot (NULL), m_limit (NULL) {}
573
574 iterator (value_type **slot, value_type **limit) :
575 m_slot (slot), m_limit (limit) {}
576
577 inline value_type *operator * () { return *m_slot; }
578 void slide ();
579 inline iterator &operator ++ ();
580 bool operator != (const iterator &other) const
581 {
582 return m_slot != other.m_slot || m_limit != other.m_limit;
583 }
584
585 private:
586 value_type **m_slot;
587 value_type **m_limit;
588 };
589
590 iterator begin () const
591 {
592 iterator iter (m_entries, m_entries + m_size);
593 iter.slide ();
594 return iter;
595 }
596
597 iterator end () const { return iterator (); }
598
599 double collisions () const
600 {
601 return m_searches ? static_cast <double> (m_collisions) / m_searches : 0;
602 }
603
604 private:
605
606 value_type **find_empty_slot_for_expand (hashval_t);
607 void expand ();
608
609 /* Table itself. */
610 typename Descriptor::value_type **m_entries;
611
612 size_t m_size;
613
614 /* Current number of elements including also deleted elements. */
615 size_t m_n_elements;
616
617 /* Current number of deleted elements in the table. */
618 size_t m_n_deleted;
619
620 /* The following member is used for debugging. Its value is number
621 of all calls of `htab_find_slot' for the hash table. */
622 unsigned int m_searches;
623
624 /* The following member is used for debugging. Its value is number
625 of collisions fixed for time of work with the hash table. */
626 unsigned int m_collisions;
627
628 /* Current size (in entries) of the hash table, as an index into the
629 table of primes. */
630 unsigned int m_size_prime_index;
631 };
632
633 template<typename Descriptor, template<typename Type> class Allocator>
634 hash_table<Descriptor, Allocator, false>::hash_table (size_t size) :
635 m_n_elements (0), m_n_deleted (0), m_searches (0), m_collisions (0)
636 {
637 unsigned int size_prime_index;
638
639 size_prime_index = hash_table_higher_prime_index (size);
640 size = prime_tab[size_prime_index].prime;
641
642 m_entries = Allocator <value_type*> ::data_alloc (size);
643 gcc_assert (m_entries != NULL);
644 m_size = size;
645 m_size_prime_index = size_prime_index;
646 }
647
648 template<typename Descriptor, template<typename Type> class Allocator>
649 hash_table<Descriptor, Allocator, false>::~hash_table ()
650 {
651 for (size_t i = m_size - 1; i < m_size; i--)
652 if (m_entries[i] != HTAB_EMPTY_ENTRY && m_entries[i] != HTAB_DELETED_ENTRY)
653 Descriptor::remove (m_entries[i]);
654
655 Allocator <value_type *> ::data_free (m_entries);
656 }
657
658 /* Similar to find_slot, but without several unwanted side effects:
659 - Does not call equal when it finds an existing entry.
660 - Does not change the count of elements/searches/collisions in the
661 hash table.
662 This function also assumes there are no deleted entries in the table.
663 HASH is the hash value for the element to be inserted. */
664
665 template<typename Descriptor, template<typename Type> class Allocator>
666 typename Descriptor::value_type **
667 hash_table<Descriptor, Allocator, false>
668 ::find_empty_slot_for_expand (hashval_t hash)
669 {
670 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
671 size_t size = m_size;
672 value_type **slot = m_entries + index;
673 hashval_t hash2;
674
675 if (*slot == HTAB_EMPTY_ENTRY)
676 return slot;
677 else if (*slot == HTAB_DELETED_ENTRY)
678 abort ();
679
680 hash2 = hash_table_mod2 (hash, m_size_prime_index);
681 for (;;)
682 {
683 index += hash2;
684 if (index >= size)
685 index -= size;
686
687 slot = m_entries + index;
688 if (*slot == HTAB_EMPTY_ENTRY)
689 return slot;
690 else if (*slot == HTAB_DELETED_ENTRY)
691 abort ();
692 }
693 }
694
695 /* The following function changes size of memory allocated for the
696 entries and repeatedly inserts the table elements. The occupancy
697 of the table after the call will be about 50%. Naturally the hash
698 table must already exist. Remember also that the place of the
699 table entries is changed. If memory allocation fails, this function
700 will abort. */
701
702 template<typename Descriptor, template<typename Type> class Allocator>
703 void
704 hash_table<Descriptor, Allocator, false>::expand ()
705 {
706 value_type **oentries = m_entries;
707 unsigned int oindex = m_size_prime_index;
708 size_t osize = size ();
709 value_type **olimit = oentries + osize;
710 size_t elts = elements ();
711
712 /* Resize only when table after removal of unused elements is either
713 too full or too empty. */
714 unsigned int nindex;
715 size_t nsize;
716 if (elts * 2 > osize || (elts * 8 < osize && osize > 32))
717 {
718 nindex = hash_table_higher_prime_index (elts * 2);
719 nsize = prime_tab[nindex].prime;
720 }
721 else
722 {
723 nindex = oindex;
724 nsize = osize;
725 }
726
727 value_type **nentries = Allocator <value_type *> ::data_alloc (nsize);
728 gcc_assert (nentries != NULL);
729 m_entries = nentries;
730 m_size = nsize;
731 m_size_prime_index = nindex;
732 m_n_elements -= m_n_deleted;
733 m_n_deleted = 0;
734
735 value_type **p = oentries;
736 do
737 {
738 value_type *x = *p;
739
740 if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
741 {
742 value_type **q = find_empty_slot_for_expand (Descriptor::hash (x));
743
744 *q = x;
745 }
746
747 p++;
748 }
749 while (p < olimit);
750
751 Allocator <value_type *> ::data_free (oentries);
752 }
753
754 template<typename Descriptor, template<typename Type> class Allocator>
755 void
756 hash_table<Descriptor, Allocator, false>::empty ()
757 {
758 size_t size = m_size;
759 value_type **entries = m_entries;
760 int i;
761
762 for (i = size - 1; i >= 0; i--)
763 if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY)
764 Descriptor::remove (entries[i]);
765
766 /* Instead of clearing megabyte, downsize the table. */
767 if (size > 1024*1024 / sizeof (PTR))
768 {
769 int nindex = hash_table_higher_prime_index (1024 / sizeof (PTR));
770 int nsize = prime_tab[nindex].prime;
771
772 Allocator <value_type *> ::data_free (m_entries);
773 m_entries = Allocator <value_type *> ::data_alloc (nsize);
774 m_size = nsize;
775 m_size_prime_index = nindex;
776 }
777 else
778 memset (entries, 0, size * sizeof (value_type *));
779 m_n_deleted = 0;
780 m_n_elements = 0;
781 }
782
783 /* This function clears a specified SLOT in a hash table. It is
784 useful when you've already done the lookup and don't want to do it
785 again. */
786
787 template<typename Descriptor, template<typename Type> class Allocator>
788 void
789 hash_table<Descriptor, Allocator, false>::clear_slot (value_type **slot)
790 {
791 if (slot < m_entries || slot >= m_entries + size ()
792 || *slot == HTAB_EMPTY_ENTRY || *slot == HTAB_DELETED_ENTRY)
793 abort ();
794
795 Descriptor::remove (*slot);
796
797 *slot = static_cast <value_type *> (HTAB_DELETED_ENTRY);
798 m_n_deleted++;
799 }
800
801 /* This function searches for a hash table entry equal to the given
802 COMPARABLE element starting with the given HASH value. It cannot
803 be used to insert or delete an element. */
804
805 template<typename Descriptor, template<typename Type> class Allocator>
806 typename Descriptor::value_type *
807 hash_table<Descriptor, Allocator, false>
808 ::find_with_hash (const compare_type *comparable, hashval_t hash)
809 {
810 m_searches++;
811 size_t size = m_size;
812 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
813
814 value_type *entry = m_entries[index];
815 if (entry == HTAB_EMPTY_ENTRY
816 || (entry != HTAB_DELETED_ENTRY && Descriptor::equal (entry, comparable)))
817 return entry;
818
819 hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
820 for (;;)
821 {
822 m_collisions++;
823 index += hash2;
824 if (index >= size)
825 index -= size;
826
827 entry = m_entries[index];
828 if (entry == HTAB_EMPTY_ENTRY
829 || (entry != HTAB_DELETED_ENTRY
830 && Descriptor::equal (entry, comparable)))
831 return entry;
832 }
833 }
834
835 /* This function searches for a hash table slot containing an entry
836 equal to the given COMPARABLE element and starting with the given
837 HASH. To delete an entry, call this with insert=NO_INSERT, then
838 call clear_slot on the slot returned (possibly after doing some
839 checks). To insert an entry, call this with insert=INSERT, then
840 write the value you want into the returned slot. When inserting an
841 entry, NULL may be returned if memory allocation fails. */
842
843 template<typename Descriptor, template<typename Type> class Allocator>
844 typename Descriptor::value_type **
845 hash_table<Descriptor, Allocator, false>
846 ::find_slot_with_hash (const compare_type *comparable, hashval_t hash,
847 enum insert_option insert)
848 {
849 if (insert == INSERT && m_size * 3 <= m_n_elements * 4)
850 expand ();
851
852 m_searches++;
853
854 value_type **first_deleted_slot = NULL;
855 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
856 hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
857 value_type *entry = m_entries[index];
858 size_t size = m_size;
859 if (entry == HTAB_EMPTY_ENTRY)
860 goto empty_entry;
861 else if (entry == HTAB_DELETED_ENTRY)
862 first_deleted_slot = &m_entries[index];
863 else if (Descriptor::equal (entry, comparable))
864 return &m_entries[index];
865
866 for (;;)
867 {
868 m_collisions++;
869 index += hash2;
870 if (index >= size)
871 index -= size;
872
873 entry = m_entries[index];
874 if (entry == HTAB_EMPTY_ENTRY)
875 goto empty_entry;
876 else if (entry == HTAB_DELETED_ENTRY)
877 {
878 if (!first_deleted_slot)
879 first_deleted_slot = &m_entries[index];
880 }
881 else if (Descriptor::equal (entry, comparable))
882 return &m_entries[index];
883 }
884
885 empty_entry:
886 if (insert == NO_INSERT)
887 return NULL;
888
889 if (first_deleted_slot)
890 {
891 m_n_deleted--;
892 *first_deleted_slot = static_cast <value_type *> (HTAB_EMPTY_ENTRY);
893 return first_deleted_slot;
894 }
895
896 m_n_elements++;
897 return &m_entries[index];
898 }
899
900 /* This function deletes an element with the given COMPARABLE value
901 from hash table starting with the given HASH. If there is no
902 matching element in the hash table, this function does nothing. */
903
904 template<typename Descriptor, template<typename Type> class Allocator>
905 void
906 hash_table<Descriptor, Allocator, false>
907 ::remove_elt_with_hash (const compare_type *comparable, hashval_t hash)
908 {
909 value_type **slot = find_slot_with_hash (comparable, hash, NO_INSERT);
910 if (*slot == HTAB_EMPTY_ENTRY)
911 return;
912
913 Descriptor::remove (*slot);
914
915 *slot = static_cast <value_type *> (HTAB_DELETED_ENTRY);
916 m_n_deleted++;
917 }
918
919 /* This function scans over the entire hash table calling CALLBACK for
920 each live entry. If CALLBACK returns false, the iteration stops.
921 ARGUMENT is passed as CALLBACK's second argument. */
922
923 template<typename Descriptor, template<typename Type> class Allocator>
924 template<typename Argument,
925 int (*Callback) (typename Descriptor::value_type **slot, Argument argument)>
926 void
927 hash_table<Descriptor, Allocator, false>::traverse_noresize (Argument argument)
928 {
929 value_type **slot = m_entries;
930 value_type **limit = slot + size ();
931
932 do
933 {
934 value_type *x = *slot;
935
936 if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
937 if (! Callback (slot, argument))
938 break;
939 }
940 while (++slot < limit);
941 }
942
943 /* Like traverse_noresize, but does resize the table when it is too empty
944 to improve effectivity of subsequent calls. */
945
946 template <typename Descriptor,
947 template <typename Type> class Allocator>
948 template <typename Argument,
949 int (*Callback) (typename Descriptor::value_type **slot,
950 Argument argument)>
951 void
952 hash_table<Descriptor, Allocator, false>::traverse (Argument argument)
953 {
954 size_t size = m_size;
955 if (elements () * 8 < size && size > 32)
956 expand ();
957
958 traverse_noresize <Argument, Callback> (argument);
959 }
960
961 /* Slide down the iterator slots until an active entry is found. */
962
963 template<typename Descriptor, template<typename Type> class Allocator>
964 void
965 hash_table<Descriptor, Allocator, false>::iterator::slide ()
966 {
967 for ( ; m_slot < m_limit; ++m_slot )
968 {
969 value_type *x = *m_slot;
970 if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
971 return;
972 }
973 m_slot = NULL;
974 m_limit = NULL;
975 }
976
977 /* Bump the iterator. */
978
979 template<typename Descriptor, template<typename Type> class Allocator>
980 inline typename hash_table<Descriptor, Allocator, false>::iterator &
981 hash_table<Descriptor, Allocator, false>::iterator::operator ++ ()
982 {
983 ++m_slot;
984 slide ();
985 return *this;
986 }
987
988 /* A partial specialization used when values should be stored directly. */
989
990 template <typename Descriptor,
991 template<typename Type> class Allocator>
992 class hash_table<Descriptor, Allocator, true>
993 {
994 typedef typename Descriptor::value_type value_type;
995 typedef typename Descriptor::compare_type compare_type;
996
997 public:
998 hash_table (size_t);
999 ~hash_table ();
1000
1001 /* Current size (in entries) of the hash table. */
1002 size_t size () const { return m_size; }
1003
1004 /* Return the current number of elements in this hash table. */
1005 size_t elements () const { return m_n_elements - m_n_deleted; }
1006
1007 /* Return the current number of elements in this hash table. */
1008 size_t elements_with_deleted () const { return m_n_elements; }
1009
1010 /* This function clears all entries in the given hash table. */
1011 void empty ();
1012
1013 /* This function clears a specified SLOT in a hash table. It is
1014 useful when you've already done the lookup and don't want to do it
1015 again. */
1016
1017 void clear_slot (value_type *);
1018
1019 /* This function searches for a hash table entry equal to the given
1020 COMPARABLE element starting with the given HASH value. It cannot
1021 be used to insert or delete an element. */
1022 value_type &find_with_hash (const compare_type &, hashval_t);
1023
1024 /* Like find_slot_with_hash, but compute the hash value from the element. */
1025 value_type &find (const value_type &value)
1026 {
1027 return find_with_hash (value, Descriptor::hash (value));
1028 }
1029
1030 value_type *find_slot (const value_type &value, insert_option insert)
1031 {
1032 return find_slot_with_hash (value, Descriptor::hash (value), insert);
1033 }
1034
1035 /* This function searches for a hash table slot containing an entry
1036 equal to the given COMPARABLE element and starting with the given
1037 HASH. To delete an entry, call this with insert=NO_INSERT, then
1038 call clear_slot on the slot returned (possibly after doing some
1039 checks). To insert an entry, call this with insert=INSERT, then
1040 write the value you want into the returned slot. When inserting an
1041 entry, NULL may be returned if memory allocation fails. */
1042 value_type *find_slot_with_hash (const compare_type &comparable,
1043 hashval_t hash, enum insert_option insert);
1044
1045 /* This function deletes an element with the given COMPARABLE value
1046 from hash table starting with the given HASH. If there is no
1047 matching element in the hash table, this function does nothing. */
1048 void remove_elt_with_hash (const compare_type &, hashval_t);
1049
1050 /* Like remove_elt_with_hash, but compute the hash value from the element. */
1051 void remove_elt (const value_type &value)
1052 {
1053 remove_elt_with_hash (value, Descriptor::hash (value));
1054 }
1055
1056 /* This function scans over the entire hash table calling CALLBACK for
1057 each live entry. If CALLBACK returns false, the iteration stops.
1058 ARGUMENT is passed as CALLBACK's second argument. */
1059 template <typename Argument,
1060 int (*Callback) (value_type *slot, Argument argument)>
1061 void traverse_noresize (Argument argument);
1062
1063 /* Like traverse_noresize, but does resize the table when it is too empty
1064 to improve effectivity of subsequent calls. */
1065 template <typename Argument,
1066 int (*Callback) (value_type *slot, Argument argument)>
1067 void traverse (Argument argument);
1068
1069 class iterator
1070 {
1071 public:
1072 iterator () : m_slot (NULL), m_limit (NULL) {}
1073
1074 iterator (value_type *slot, value_type *limit) :
1075 m_slot (slot), m_limit (limit) {}
1076
1077 inline value_type &operator * () { return *m_slot; }
1078 void slide ();
1079 inline iterator &operator ++ ();
1080 bool operator != (const iterator &other) const
1081 {
1082 return m_slot != other.m_slot || m_limit != other.m_limit;
1083 }
1084
1085 private:
1086 value_type *m_slot;
1087 value_type *m_limit;
1088 };
1089
1090 iterator begin () const
1091 {
1092 iterator iter (m_entries, m_entries + m_size);
1093 iter.slide ();
1094 return iter;
1095 }
1096
1097 iterator end () const { return iterator (); }
1098
1099 double collisions () const
1100 {
1101 return m_searches ? static_cast <double> (m_collisions) / m_searches : 0;
1102 }
1103
1104 private:
1105
1106 value_type *find_empty_slot_for_expand (hashval_t);
1107 void expand ();
1108 static bool is_deleted (value_type &v)
1109 {
1110 return is_deleted_helper<value_type, Descriptor>::call (v);
1111 }
1112 static bool is_empty (value_type &v)
1113 {
1114 return is_empty_helper<value_type, Descriptor>::call (v);
1115 }
1116
1117 static void mark_deleted (value_type &v)
1118 {
1119 return mark_deleted_helper<value_type, Descriptor>::call (v);
1120 }
1121
1122 static void mark_empty (value_type &v)
1123 {
1124 return mark_empty_helper<value_type, Descriptor>::call (v);
1125 }
1126
1127 /* Table itself. */
1128 typename Descriptor::value_type *m_entries;
1129
1130 size_t m_size;
1131
1132 /* Current number of elements including also deleted elements. */
1133 size_t m_n_elements;
1134
1135 /* Current number of deleted elements in the table. */
1136 size_t m_n_deleted;
1137
1138 /* The following member is used for debugging. Its value is number
1139 of all calls of `htab_find_slot' for the hash table. */
1140 unsigned int m_searches;
1141
1142 /* The following member is used for debugging. Its value is number
1143 of collisions fixed for time of work with the hash table. */
1144 unsigned int m_collisions;
1145
1146 /* Current size (in entries) of the hash table, as an index into the
1147 table of primes. */
1148 unsigned int m_size_prime_index;
1149 };
1150
1151 template<typename Descriptor, template<typename Type> class Allocator>
1152 hash_table<Descriptor, Allocator, true>::hash_table (size_t size) :
1153 m_n_elements (0), m_n_deleted (0), m_searches (0), m_collisions (0)
1154 {
1155 unsigned int size_prime_index;
1156
1157 size_prime_index = hash_table_higher_prime_index (size);
1158 size = prime_tab[size_prime_index].prime;
1159
1160 m_entries = Allocator <value_type> ::data_alloc (size);
1161 gcc_assert (m_entries != NULL);
1162 m_size = size;
1163 m_size_prime_index = size_prime_index;
1164 }
1165
1166 template<typename Descriptor, template<typename Type> class Allocator>
1167 hash_table<Descriptor, Allocator, true>::~hash_table ()
1168 {
1169 for (size_t i = m_size - 1; i < m_size; i--)
1170 if (!is_empty (m_entries[i]) && !is_deleted (m_entries[i]))
1171 Descriptor::remove (m_entries[i]);
1172
1173 Allocator <value_type> ::data_free (m_entries);
1174 }
1175
1176 /* Similar to find_slot, but without several unwanted side effects:
1177 - Does not call equal when it finds an existing entry.
1178 - Does not change the count of elements/searches/collisions in the
1179 hash table.
1180 This function also assumes there are no deleted entries in the table.
1181 HASH is the hash value for the element to be inserted. */
1182
1183 template<typename Descriptor, template<typename Type> class Allocator>
1184 typename Descriptor::value_type *
1185 hash_table<Descriptor, Allocator, true>
1186 ::find_empty_slot_for_expand (hashval_t hash)
1187 {
1188 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
1189 size_t size = m_size;
1190 value_type *slot = m_entries + index;
1191 hashval_t hash2;
1192
1193 if (is_empty (*slot))
1194 return slot;
1195 else if (is_deleted (*slot))
1196 abort ();
1197
1198 hash2 = hash_table_mod2 (hash, m_size_prime_index);
1199 for (;;)
1200 {
1201 index += hash2;
1202 if (index >= size)
1203 index -= size;
1204
1205 slot = m_entries + index;
1206 if (is_empty (*slot))
1207 return slot;
1208 else if (is_deleted (*slot))
1209 abort ();
1210 }
1211 }
1212
1213 /* The following function changes size of memory allocated for the
1214 entries and repeatedly inserts the table elements. The occupancy
1215 of the table after the call will be about 50%. Naturally the hash
1216 table must already exist. Remember also that the place of the
1217 table entries is changed. If memory allocation fails, this function
1218 will abort. */
1219
1220 template<typename Descriptor, template<typename Type> class Allocator>
1221 void
1222 hash_table<Descriptor, Allocator, true>::expand ()
1223 {
1224 value_type *oentries = m_entries;
1225 unsigned int oindex = m_size_prime_index;
1226 size_t osize = size ();
1227 value_type *olimit = oentries + osize;
1228 size_t elts = elements ();
1229
1230 /* Resize only when table after removal of unused elements is either
1231 too full or too empty. */
1232 unsigned int nindex;
1233 size_t nsize;
1234 if (elts * 2 > osize || (elts * 8 < osize && osize > 32))
1235 {
1236 nindex = hash_table_higher_prime_index (elts * 2);
1237 nsize = prime_tab[nindex].prime;
1238 }
1239 else
1240 {
1241 nindex = oindex;
1242 nsize = osize;
1243 }
1244
1245 value_type *nentries = Allocator <value_type> ::data_alloc (nsize);
1246 gcc_assert (nentries != NULL);
1247 m_entries = nentries;
1248 m_size = nsize;
1249 m_size_prime_index = nindex;
1250 m_n_elements -= m_n_deleted;
1251 m_n_deleted = 0;
1252
1253 value_type *p = oentries;
1254 do
1255 {
1256 value_type &x = *p;
1257
1258 if (!is_empty (x) && !is_deleted (x))
1259 {
1260 value_type *q = find_empty_slot_for_expand (Descriptor::hash (x));
1261
1262 *q = x;
1263 }
1264
1265 p++;
1266 }
1267 while (p < olimit);
1268
1269 Allocator <value_type> ::data_free (oentries);
1270 }
1271
1272 template<typename Descriptor, template<typename Type> class Allocator>
1273 void
1274 hash_table<Descriptor, Allocator, true>::empty ()
1275 {
1276 size_t size = m_size;
1277 value_type *entries = m_entries;
1278 int i;
1279
1280 for (i = size - 1; i >= 0; i--)
1281 if (!is_empty (entries[i]) && !is_deleted (entries[i]))
1282 Descriptor::remove (entries[i]);
1283
1284 /* Instead of clearing megabyte, downsize the table. */
1285 if (size > 1024*1024 / sizeof (PTR))
1286 {
1287 int nindex = hash_table_higher_prime_index (1024 / sizeof (PTR));
1288 int nsize = prime_tab[nindex].prime;
1289
1290 Allocator <value_type> ::data_free (m_entries);
1291 m_entries = Allocator <value_type> ::data_alloc (nsize);
1292 m_size = nsize;
1293 m_size_prime_index = nindex;
1294 }
1295 else
1296 memset (entries, 0, size * sizeof (value_type));
1297 m_n_deleted = 0;
1298 m_n_elements = 0;
1299 }
1300
1301 /* This function clears a specified SLOT in a hash table. It is
1302 useful when you've already done the lookup and don't want to do it
1303 again. */
1304
1305 template<typename Descriptor, template<typename Type> class Allocator>
1306 void
1307 hash_table<Descriptor, Allocator, true>::clear_slot (value_type *slot)
1308 {
1309 if (slot < m_entries || slot >= m_entries + size ()
1310 || is_empty (*slot) || is_deleted (*slot))
1311 abort ();
1312
1313 Descriptor::remove (*slot);
1314
1315 mark_deleted (*slot);
1316 m_n_deleted++;
1317 }
1318
1319 /* This function searches for a hash table entry equal to the given
1320 COMPARABLE element starting with the given HASH value. It cannot
1321 be used to insert or delete an element. */
1322
1323 template<typename Descriptor, template<typename Type> class Allocator>
1324 typename Descriptor::value_type &
1325 hash_table<Descriptor, Allocator, true>
1326 ::find_with_hash (const compare_type &comparable, hashval_t hash)
1327 {
1328 m_searches++;
1329 size_t size = m_size;
1330 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
1331
1332 value_type *entry = &m_entries[index];
1333 if (is_empty (*entry)
1334 || (!is_deleted (*entry) && Descriptor::equal (*entry, comparable)))
1335 return *entry;
1336
1337 hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
1338 for (;;)
1339 {
1340 m_collisions++;
1341 index += hash2;
1342 if (index >= size)
1343 index -= size;
1344
1345 entry = &m_entries[index];
1346 if (is_empty (*entry)
1347 || (!is_deleted (*entry) && Descriptor::equal (*entry, comparable)))
1348 return *entry;
1349 }
1350 }
1351
1352 /* This function searches for a hash table slot containing an entry
1353 equal to the given COMPARABLE element and starting with the given
1354 HASH. To delete an entry, call this with insert=NO_INSERT, then
1355 call clear_slot on the slot returned (possibly after doing some
1356 checks). To insert an entry, call this with insert=INSERT, then
1357 write the value you want into the returned slot. When inserting an
1358 entry, NULL may be returned if memory allocation fails. */
1359
1360 template<typename Descriptor, template<typename Type> class Allocator>
1361 typename Descriptor::value_type *
1362 hash_table<Descriptor, Allocator, true>
1363 ::find_slot_with_hash (const compare_type &comparable, hashval_t hash,
1364 enum insert_option insert)
1365 {
1366 if (insert == INSERT && m_size * 3 <= m_n_elements * 4)
1367 expand ();
1368
1369 m_searches++;
1370
1371 value_type *first_deleted_slot = NULL;
1372 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
1373 hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
1374 value_type *entry = &m_entries[index];
1375 size_t size = m_size;
1376 if (is_empty (*entry))
1377 goto empty_entry;
1378 else if (is_deleted (*entry))
1379 first_deleted_slot = &m_entries[index];
1380 else if (Descriptor::equal (*entry, comparable))
1381 return &m_entries[index];
1382
1383 for (;;)
1384 {
1385 m_collisions++;
1386 index += hash2;
1387 if (index >= size)
1388 index -= size;
1389
1390 entry = &m_entries[index];
1391 if (is_empty (*entry))
1392 goto empty_entry;
1393 else if (is_deleted (*entry))
1394 {
1395 if (!first_deleted_slot)
1396 first_deleted_slot = &m_entries[index];
1397 }
1398 else if (Descriptor::equal (*entry, comparable))
1399 return &m_entries[index];
1400 }
1401
1402 empty_entry:
1403 if (insert == NO_INSERT)
1404 return NULL;
1405
1406 if (first_deleted_slot)
1407 {
1408 m_n_deleted--;
1409 mark_empty (*first_deleted_slot);
1410 return first_deleted_slot;
1411 }
1412
1413 m_n_elements++;
1414 return &m_entries[index];
1415 }
1416
1417 /* This function deletes an element with the given COMPARABLE value
1418 from hash table starting with the given HASH. If there is no
1419 matching element in the hash table, this function does nothing. */
1420
1421 template<typename Descriptor, template<typename Type> class Allocator>
1422 void
1423 hash_table<Descriptor, Allocator, true>
1424 ::remove_elt_with_hash (const compare_type &comparable, hashval_t hash)
1425 {
1426 value_type *slot = find_slot_with_hash (comparable, hash, NO_INSERT);
1427 if (is_empty (*slot))
1428 return;
1429
1430 Descriptor::remove (*slot);
1431
1432 mark_deleted (*slot);
1433 m_n_deleted++;
1434 }
1435
1436 /* This function scans over the entire hash table calling CALLBACK for
1437 each live entry. If CALLBACK returns false, the iteration stops.
1438 ARGUMENT is passed as CALLBACK's second argument. */
1439
1440 template<typename Descriptor,
1441 template<typename Type> class Allocator>
1442 template<typename Argument,
1443 int (*Callback) (typename Descriptor::value_type *slot,
1444 Argument argument)>
1445 void
1446 hash_table<Descriptor, Allocator, true>::traverse_noresize (Argument argument)
1447 {
1448 value_type *slot = m_entries;
1449 value_type *limit = slot + size ();
1450
1451 do
1452 {
1453 value_type &x = *slot;
1454
1455 if (!is_empty (x) && !is_deleted (x))
1456 if (! Callback (slot, argument))
1457 break;
1458 }
1459 while (++slot < limit);
1460 }
1461
1462 /* Like traverse_noresize, but does resize the table when it is too empty
1463 to improve effectivity of subsequent calls. */
1464
1465 template <typename Descriptor,
1466 template <typename Type> class Allocator>
1467 template <typename Argument,
1468 int (*Callback) (typename Descriptor::value_type *slot,
1469 Argument argument)>
1470 void
1471 hash_table<Descriptor, Allocator, true>::traverse (Argument argument)
1472 {
1473 size_t size = m_size;
1474 if (elements () * 8 < size && size > 32)
1475 expand ();
1476
1477 traverse_noresize <Argument, Callback> (argument);
1478 }
1479
1480 /* Slide down the iterator slots until an active entry is found. */
1481
1482 template<typename Descriptor, template<typename Type> class Allocator>
1483 void
1484 hash_table<Descriptor, Allocator, true>::iterator::slide ()
1485 {
1486 for ( ; m_slot < m_limit; ++m_slot )
1487 {
1488 value_type &x = *m_slot;
1489 if (!is_empty (x) && !is_deleted (x))
1490 return;
1491 }
1492 m_slot = NULL;
1493 m_limit = NULL;
1494 }
1495
1496 /* Bump the iterator. */
1497
1498 template<typename Descriptor, template<typename Type> class Allocator>
1499 inline typename hash_table<Descriptor, Allocator, true>::iterator &
1500 hash_table<Descriptor, Allocator, true>::iterator::operator ++ ()
1501 {
1502 ++m_slot;
1503 slide ();
1504 return *this;
1505 }
1506
1507
1508 /* Iterate through the elements of hash_table HTAB,
1509 using hash_table <....>::iterator ITER,
1510 storing each element in RESULT, which is of type TYPE. */
1511
1512 #define FOR_EACH_HASH_TABLE_ELEMENT(HTAB, RESULT, TYPE, ITER) \
1513 for ((ITER) = (HTAB).begin (); \
1514 (ITER) != (HTAB).end () ? (RESULT = *(ITER) , true) : false; \
1515 ++(ITER))
1516
1517 #endif /* TYPED_HASHTAB_H */