2015-01-20 Jeff Law <law@redhat.com>
[official-gcc.git] / gcc / hash-table.h
blobf201c89633ca9ed6afa3390de0c34278fe513f87
1 /* A type-safe hash table template.
2 Copyright (C) 2012-2015 Free Software Foundation, Inc.
3 Contributed by Lawrence Crowl <crowl@google.com>
5 This file is part of GCC.
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.
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.
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/>. */
22 /* This file implements a typed hash table.
23 The implementation borrows from libiberty's htab_t in hashtab.h.
26 INTRODUCTION TO TYPES
28 Users of the hash table generally need to be aware of three types.
30 1. The type being placed into the hash table. This type is called
31 the value type.
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.
37 - A typedef named 'value_type' to the value type (from above).
39 - A static member function named 'hash' that takes a value_type
40 pointer and returns a hashval_t value.
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.
47 - A static member function named 'equal' that takes a value_type
48 pointer and a compare_type pointer, and returns a bool.
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).
55 3. The type of the hash table itself. (More later.)
57 In very special circumstances, users may need to know about a fourth type.
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.
63 - A static member function named 'data_alloc'. This function
64 allocates the data elements in the table.
66 - A static member function named 'data_free'. This function
67 deallocates the data elements in the table.
69 Hash table are instantiated with two type arguments.
71 * The descriptor type, (2) above.
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.
78 DEFINING A DESCRIPTOR TYPE
80 The first task in using the hash table is to describe the element type.
81 We compose this into a few steps.
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.
87 * typed_free_remove implements the static 'remove' member function
88 by calling free().
90 * typed_noop_remove implements the static 'remove' member function
91 by doing nothing.
93 You can use these policies by simply deriving the descriptor type
94 from one of those class template, with the appropriate argument.
96 Otherwise, you need to write the static 'remove' member function
97 in the descriptor class.
99 2. Choose a hash function. Write the static 'hash' member function.
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.
106 AN EXAMPLE DESCRIPTOR TYPE
108 Suppose you want to put some_type into the hash table. You could define
109 the descriptor type as follows.
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.
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 *);
121 inline hashval_t
122 some_type_hasher::hash (const value_type *e)
123 { ... compute and return a hash value for E ... }
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' ... }
130 AN EXAMPLE HASH_TABLE DECLARATION
132 To instantiate a hash table for some_type:
134 hash_table <some_type_hasher> some_type_hash_table;
136 There is no need to mention some_type directly, as the hash table will
137 obtain it using some_type_hasher::value_type.
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.
144 EASY DESCRIPTORS FOR POINTERS
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,
150 hash_table <pointer_hash <whatever_type>> whatever_type_hash_table;
153 HASH TABLE ITERATORS
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:
158 extern void consume (some_info *);
160 We define a convenience typedef and the hash table:
162 typedef hash_table <some_info_hasher> info_table_type;
163 info_table_type info_table;
165 Then we write the loop in typical C++ style:
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);
173 Or with common sub-expression elimination:
175 for (info_table_type::iterator iter = info_table.begin ();
176 iter != info_table.end ();
177 ++iter)
179 some_info &elem = *iter;
180 if (elem.status == INFO_READY)
181 consume (&elem);
184 One can also use a more typical GCC style:
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);
196 #ifndef TYPED_HASHTAB_H
197 #define TYPED_HASHTAB_H
199 #include "ggc.h"
200 #include "hashtab.h"
201 #include <new>
203 template<typename, typename, typename> class hash_map;
204 template<typename, typename> class hash_set;
206 /* The ordinary memory allocator. */
207 /* FIXME (crowl): This allocator may be extracted for wider sharing later. */
209 template <typename Type>
210 struct xcallocator
212 static Type *data_alloc (size_t count);
213 static void data_free (Type *memory);
217 /* Allocate memory for COUNT data blocks. */
219 template <typename Type>
220 inline Type *
221 xcallocator <Type>::data_alloc (size_t count)
223 return static_cast <Type *> (xcalloc (count, sizeof (Type)));
227 /* Free memory for data blocks. */
229 template <typename Type>
230 inline void
231 xcallocator <Type>::data_free (Type *memory)
233 return ::free (memory);
237 /* Helpful type for removing with free. */
239 template <typename Type>
240 struct typed_free_remove
242 static inline void remove (Type *p);
246 /* Remove with free. */
248 template <typename Type>
249 inline void
250 typed_free_remove <Type>::remove (Type *p)
252 free (p);
256 /* Helpful type for a no-op remove. */
258 template <typename Type>
259 struct typed_noop_remove
261 static inline void remove (Type *p);
265 /* Remove doing nothing. */
267 template <typename Type>
268 inline void
269 typed_noop_remove <Type>::remove (Type *p ATTRIBUTE_UNUSED)
274 /* Pointer hash with a no-op remove method. */
276 template <typename Type>
277 struct pointer_hash : typed_noop_remove <Type>
279 typedef Type *value_type;
280 typedef Type *compare_type;
281 typedef int store_values_directly;
283 static inline hashval_t hash (const value_type &);
285 static inline bool equal (const value_type &existing,
286 const compare_type &candidate);
289 template <typename Type>
290 inline hashval_t
291 pointer_hash <Type>::hash (const value_type &candidate)
293 /* This is a really poor hash function, but it is what the current code uses,
294 so I am reusing it to avoid an additional axis in testing. */
295 return (hashval_t) ((intptr_t)candidate >> 3);
298 template <typename Type>
299 inline bool
300 pointer_hash <Type>::equal (const value_type &existing,
301 const compare_type &candidate)
303 return existing == candidate;
306 /* Hasher for entry in gc memory. */
308 template<typename T>
309 struct ggc_hasher
311 typedef T value_type;
312 typedef T compare_type;
313 typedef int store_values_directly;
315 static void remove (T) {}
317 static void
318 ggc_mx (T p)
320 extern void gt_ggc_mx (T &);
321 gt_ggc_mx (p);
324 static void
325 pch_nx (T &p)
327 extern void gt_pch_nx (T &);
328 gt_pch_nx (p);
331 static void
332 pch_nx (T &p, gt_pointer_operator op, void *cookie)
334 op (&p, cookie);
338 /* Hasher for cache entry in gc memory. */
340 template<typename T>
341 struct ggc_cache_hasher
343 typedef T value_type;
344 typedef T compare_type;
345 typedef int store_values_directly;
347 static void remove (T &) {}
349 /* Entries are weakly held because this is for caches. */
351 static void ggc_mx (T &) {}
353 static void
354 pch_nx (T &p)
356 extern void gt_pch_nx (T &);
357 gt_pch_nx (p);
360 static void
361 pch_nx (T &p, gt_pointer_operator op, void *cookie)
363 op (&p, cookie);
366 /* Clear out entries if they are about to be gc'd. */
368 static void
369 handle_cache_entry (T &e)
371 if (e != HTAB_EMPTY_ENTRY && e != HTAB_DELETED_ENTRY && !ggc_marked_p (e))
372 e = static_cast<T> (HTAB_DELETED_ENTRY);
377 /* Table of primes and their inversion information. */
379 struct prime_ent
381 hashval_t prime;
382 hashval_t inv;
383 hashval_t inv_m2; /* inverse of prime-2 */
384 hashval_t shift;
387 extern struct prime_ent const prime_tab[];
390 /* Functions for computing hash table indexes. */
392 extern unsigned int hash_table_higher_prime_index (unsigned long n)
393 ATTRIBUTE_PURE;
395 /* Return X % Y using multiplicative inverse values INV and SHIFT.
397 The multiplicative inverses computed above are for 32-bit types,
398 and requires that we be able to compute a highpart multiply.
400 FIX: I am not at all convinced that
401 3 loads, 2 multiplications, 3 shifts, and 3 additions
402 will be faster than
403 1 load and 1 modulus
404 on modern systems running a compiler. */
406 inline hashval_t
407 mul_mod (hashval_t x, hashval_t y, hashval_t inv, int shift)
409 hashval_t t1, t2, t3, t4, q, r;
411 t1 = ((uint64_t)x * inv) >> 32;
412 t2 = x - t1;
413 t3 = t2 >> 1;
414 t4 = t1 + t3;
415 q = t4 >> shift;
416 r = x - (q * y);
418 return r;
421 /* Compute the primary table index for HASH given current prime index. */
423 inline hashval_t
424 hash_table_mod1 (hashval_t hash, unsigned int index)
426 const struct prime_ent *p = &prime_tab[index];
427 gcc_checking_assert (sizeof (hashval_t) * CHAR_BIT <= 32);
428 return mul_mod (hash, p->prime, p->inv, p->shift);
431 /* Compute the secondary table index for HASH given current prime index. */
433 inline hashval_t
434 hash_table_mod2 (hashval_t hash, unsigned int index)
436 const struct prime_ent *p = &prime_tab[index];
437 gcc_checking_assert (sizeof (hashval_t) * CHAR_BIT <= 32);
438 return 1 + mul_mod (hash, p->prime - 2, p->inv_m2, p->shift);
441 /* The below is some template meta programming to decide if we should use the
442 hash table partial specialization that directly stores value_type instead of
443 pointers to value_type. If the Descriptor type defines the type
444 Descriptor::store_values_directly then values are stored directly otherwise
445 pointers to them are stored. */
446 template<typename T> struct notype { typedef void type; };
448 template<typename T, typename = void>
449 struct storage_tester
451 static const bool value = false;
454 template<typename T>
455 struct storage_tester<T, typename notype<typename
456 T::store_values_directly>::type>
458 static const bool value = true;
461 template<typename Traits>
462 struct has_is_deleted
464 template<typename U, bool (*)(U &)> struct helper {};
465 template<typename U> static char test (helper<U, U::is_deleted> *);
466 template<typename U> static int test (...);
467 static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
470 template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
471 struct is_deleted_helper
473 static inline bool
474 call (Type &v)
476 return Traits::is_deleted (v);
480 template<typename Type, typename Traits>
481 struct is_deleted_helper<Type *, Traits, false>
483 static inline bool
484 call (Type *v)
486 return v == HTAB_DELETED_ENTRY;
490 template<typename Traits>
491 struct has_is_empty
493 template<typename U, bool (*)(U &)> struct helper {};
494 template<typename U> static char test (helper<U, U::is_empty> *);
495 template<typename U> static int test (...);
496 static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
499 template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
500 struct is_empty_helper
502 static inline bool
503 call (Type &v)
505 return Traits::is_empty (v);
509 template<typename Type, typename Traits>
510 struct is_empty_helper<Type *, Traits, false>
512 static inline bool
513 call (Type *v)
515 return v == HTAB_EMPTY_ENTRY;
519 template<typename Traits>
520 struct has_mark_deleted
522 template<typename U, void (*)(U &)> struct helper {};
523 template<typename U> static char test (helper<U, U::mark_deleted> *);
524 template<typename U> static int test (...);
525 static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
528 template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
529 struct mark_deleted_helper
531 static inline void
532 call (Type &v)
534 Traits::mark_deleted (v);
538 template<typename Type, typename Traits>
539 struct mark_deleted_helper<Type *, Traits, false>
541 static inline void
542 call (Type *&v)
544 v = static_cast<Type *> (HTAB_DELETED_ENTRY);
548 template<typename Traits>
549 struct has_mark_empty
551 template<typename U, void (*)(U &)> struct helper {};
552 template<typename U> static char test (helper<U, U::mark_empty> *);
553 template<typename U> static int test (...);
554 static const bool value = sizeof (test<Traits> (0)) == sizeof (char);
557 template<typename Type, typename Traits, bool = has_is_deleted<Traits>::value>
558 struct mark_empty_helper
560 static inline void
561 call (Type &v)
563 Traits::mark_empty (v);
567 template<typename Type, typename Traits>
568 struct mark_empty_helper<Type *, Traits, false>
570 static inline void
571 call (Type *&v)
573 v = static_cast<Type *> (HTAB_EMPTY_ENTRY);
577 /* User-facing hash table type.
579 The table stores elements of type Descriptor::value_type, or pointers to
580 objects of type value_type if the descriptor does not define the type
581 store_values_directly.
583 It hashes values with the hash member function.
584 The table currently works with relatively weak hash functions.
585 Use typed_pointer_hash <Value> when hashing pointers instead of objects.
587 It compares elements with the equal member function.
588 Two elements with the same hash may not be equal.
589 Use typed_pointer_equal <Value> when hashing pointers instead of objects.
591 It removes elements with the remove member function.
592 This feature is useful for freeing memory.
593 Derive from typed_null_remove <Value> when not freeing objects.
594 Derive from typed_free_remove <Value> when doing a simple object free.
596 Specify the template Allocator to allocate and free memory.
597 The default is xcallocator.
599 Storage is an implementation detail and should not be used outside the
600 hash table code.
603 template <typename Descriptor,
604 template<typename Type> class Allocator= xcallocator,
605 bool Storage = storage_tester<Descriptor>::value>
606 class hash_table
610 template <typename Descriptor,
611 template<typename Type> class Allocator>
612 class hash_table<Descriptor, Allocator, false>
614 typedef typename Descriptor::value_type value_type;
615 typedef typename Descriptor::compare_type compare_type;
617 public:
618 hash_table (size_t);
619 ~hash_table ();
621 /* Current size (in entries) of the hash table. */
622 size_t size () const { return m_size; }
624 /* Return the current number of elements in this hash table. */
625 size_t elements () const { return m_n_elements - m_n_deleted; }
627 /* Return the current number of elements in this hash table. */
628 size_t elements_with_deleted () const { return m_n_elements; }
630 /* This function clears all entries in the given hash table. */
631 void empty ();
633 /* This function clears a specified SLOT in a hash table. It is
634 useful when you've already done the lookup and don't want to do it
635 again. */
637 void clear_slot (value_type **);
639 /* This function searches for a hash table entry equal to the given
640 COMPARABLE element starting with the given HASH value. It cannot
641 be used to insert or delete an element. */
642 value_type *find_with_hash (const compare_type *, hashval_t);
644 /* Like find_slot_with_hash, but compute the hash value from the element. */
645 value_type *find (const value_type *value)
647 return find_with_hash (value, Descriptor::hash (value));
650 value_type **find_slot (const value_type *value, insert_option insert)
652 return find_slot_with_hash (value, Descriptor::hash (value), insert);
655 /* This function searches for a hash table slot containing an entry
656 equal to the given COMPARABLE element and starting with the given
657 HASH. To delete an entry, call this with insert=NO_INSERT, then
658 call clear_slot on the slot returned (possibly after doing some
659 checks). To insert an entry, call this with insert=INSERT, then
660 write the value you want into the returned slot. When inserting an
661 entry, NULL may be returned if memory allocation fails. */
662 value_type **find_slot_with_hash (const compare_type *comparable,
663 hashval_t hash, enum insert_option insert);
665 /* This function deletes an element with the given COMPARABLE value
666 from hash table starting with the given HASH. If there is no
667 matching element in the hash table, this function does nothing. */
668 void remove_elt_with_hash (const compare_type *, hashval_t);
670 /* Like remove_elt_with_hash, but compute the hash value from the element. */
671 void remove_elt (const value_type *value)
673 remove_elt_with_hash (value, Descriptor::hash (value));
676 /* This function scans over the entire hash table calling CALLBACK for
677 each live entry. If CALLBACK returns false, the iteration stops.
678 ARGUMENT is passed as CALLBACK's second argument. */
679 template <typename Argument,
680 int (*Callback) (value_type **slot, Argument argument)>
681 void traverse_noresize (Argument argument);
683 /* Like traverse_noresize, but does resize the table when it is too empty
684 to improve effectivity of subsequent calls. */
685 template <typename Argument,
686 int (*Callback) (value_type **slot, Argument argument)>
687 void traverse (Argument argument);
689 class iterator
691 public:
692 iterator () : m_slot (NULL), m_limit (NULL) {}
694 iterator (value_type **slot, value_type **limit) :
695 m_slot (slot), m_limit (limit) {}
697 inline value_type *operator * () { return *m_slot; }
698 void slide ();
699 inline iterator &operator ++ ();
700 bool operator != (const iterator &other) const
702 return m_slot != other.m_slot || m_limit != other.m_limit;
705 private:
706 value_type **m_slot;
707 value_type **m_limit;
710 iterator begin () const
712 iterator iter (m_entries, m_entries + m_size);
713 iter.slide ();
714 return iter;
717 iterator end () const { return iterator (); }
719 double collisions () const
721 return m_searches ? static_cast <double> (m_collisions) / m_searches : 0;
724 private:
726 value_type **find_empty_slot_for_expand (hashval_t);
727 void expand ();
729 /* Table itself. */
730 typename Descriptor::value_type **m_entries;
732 size_t m_size;
734 /* Current number of elements including also deleted elements. */
735 size_t m_n_elements;
737 /* Current number of deleted elements in the table. */
738 size_t m_n_deleted;
740 /* The following member is used for debugging. Its value is number
741 of all calls of `htab_find_slot' for the hash table. */
742 unsigned int m_searches;
744 /* The following member is used for debugging. Its value is number
745 of collisions fixed for time of work with the hash table. */
746 unsigned int m_collisions;
748 /* Current size (in entries) of the hash table, as an index into the
749 table of primes. */
750 unsigned int m_size_prime_index;
753 template<typename Descriptor, template<typename Type> class Allocator>
754 hash_table<Descriptor, Allocator, false>::hash_table (size_t size) :
755 m_n_elements (0), m_n_deleted (0), m_searches (0), m_collisions (0)
757 unsigned int size_prime_index;
759 size_prime_index = hash_table_higher_prime_index (size);
760 size = prime_tab[size_prime_index].prime;
762 m_entries = Allocator <value_type*> ::data_alloc (size);
763 gcc_assert (m_entries != NULL);
764 m_size = size;
765 m_size_prime_index = size_prime_index;
768 template<typename Descriptor, template<typename Type> class Allocator>
769 hash_table<Descriptor, Allocator, false>::~hash_table ()
771 for (size_t i = m_size - 1; i < m_size; i--)
772 if (m_entries[i] != HTAB_EMPTY_ENTRY && m_entries[i] != HTAB_DELETED_ENTRY)
773 Descriptor::remove (m_entries[i]);
775 Allocator <value_type *> ::data_free (m_entries);
778 /* Similar to find_slot, but without several unwanted side effects:
779 - Does not call equal when it finds an existing entry.
780 - Does not change the count of elements/searches/collisions in the
781 hash table.
782 This function also assumes there are no deleted entries in the table.
783 HASH is the hash value for the element to be inserted. */
785 template<typename Descriptor, template<typename Type> class Allocator>
786 typename hash_table<Descriptor, Allocator, false>::value_type **
787 hash_table<Descriptor, Allocator, false>
788 ::find_empty_slot_for_expand (hashval_t hash)
790 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
791 size_t size = m_size;
792 value_type **slot = m_entries + index;
793 hashval_t hash2;
795 if (*slot == HTAB_EMPTY_ENTRY)
796 return slot;
797 gcc_checking_assert (*slot != HTAB_DELETED_ENTRY);
799 hash2 = hash_table_mod2 (hash, m_size_prime_index);
800 for (;;)
802 index += hash2;
803 if (index >= size)
804 index -= size;
806 slot = m_entries + index;
807 if (*slot == HTAB_EMPTY_ENTRY)
808 return slot;
809 gcc_checking_assert (*slot != HTAB_DELETED_ENTRY);
813 /* The following function changes size of memory allocated for the
814 entries and repeatedly inserts the table elements. The occupancy
815 of the table after the call will be about 50%. Naturally the hash
816 table must already exist. Remember also that the place of the
817 table entries is changed. If memory allocation fails, this function
818 will abort. */
820 template<typename Descriptor, template<typename Type> class Allocator>
821 void
822 hash_table<Descriptor, Allocator, false>::expand ()
824 value_type **oentries = m_entries;
825 unsigned int oindex = m_size_prime_index;
826 size_t osize = size ();
827 value_type **olimit = oentries + osize;
828 size_t elts = elements ();
830 /* Resize only when table after removal of unused elements is either
831 too full or too empty. */
832 unsigned int nindex;
833 size_t nsize;
834 if (elts * 2 > osize || (elts * 8 < osize && osize > 32))
836 nindex = hash_table_higher_prime_index (elts * 2);
837 nsize = prime_tab[nindex].prime;
839 else
841 nindex = oindex;
842 nsize = osize;
845 value_type **nentries = Allocator <value_type *> ::data_alloc (nsize);
846 gcc_assert (nentries != NULL);
847 m_entries = nentries;
848 m_size = nsize;
849 m_size_prime_index = nindex;
850 m_n_elements -= m_n_deleted;
851 m_n_deleted = 0;
853 value_type **p = oentries;
856 value_type *x = *p;
858 if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
860 value_type **q = find_empty_slot_for_expand (Descriptor::hash (x));
862 *q = x;
865 p++;
867 while (p < olimit);
869 Allocator <value_type *> ::data_free (oentries);
872 template<typename Descriptor, template<typename Type> class Allocator>
873 void
874 hash_table<Descriptor, Allocator, false>::empty ()
876 size_t size = m_size;
877 value_type **entries = m_entries;
878 int i;
880 for (i = size - 1; i >= 0; i--)
881 if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY)
882 Descriptor::remove (entries[i]);
884 /* Instead of clearing megabyte, downsize the table. */
885 if (size > 1024*1024 / sizeof (PTR))
887 int nindex = hash_table_higher_prime_index (1024 / sizeof (PTR));
888 int nsize = prime_tab[nindex].prime;
890 Allocator <value_type *> ::data_free (m_entries);
891 m_entries = Allocator <value_type *> ::data_alloc (nsize);
892 m_size = nsize;
893 m_size_prime_index = nindex;
895 else
896 memset (entries, 0, size * sizeof (value_type *));
897 m_n_deleted = 0;
898 m_n_elements = 0;
901 /* This function clears a specified SLOT in a hash table. It is
902 useful when you've already done the lookup and don't want to do it
903 again. */
905 template<typename Descriptor, template<typename Type> class Allocator>
906 void
907 hash_table<Descriptor, Allocator, false>::clear_slot (value_type **slot)
909 gcc_checking_assert (!(slot < m_entries || slot >= m_entries + size ()
910 || *slot == HTAB_EMPTY_ENTRY
911 || *slot == HTAB_DELETED_ENTRY));
913 Descriptor::remove (*slot);
915 *slot = static_cast <value_type *> (HTAB_DELETED_ENTRY);
916 m_n_deleted++;
919 /* This function searches for a hash table entry equal to the given
920 COMPARABLE element starting with the given HASH value. It cannot
921 be used to insert or delete an element. */
923 template<typename Descriptor, template<typename Type> class Allocator>
924 typename hash_table<Descriptor, Allocator, false>::value_type *
925 hash_table<Descriptor, Allocator, false>
926 ::find_with_hash (const compare_type *comparable, hashval_t hash)
928 m_searches++;
929 size_t size = m_size;
930 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
932 value_type *entry = m_entries[index];
933 if (entry == HTAB_EMPTY_ENTRY
934 || (entry != HTAB_DELETED_ENTRY && Descriptor::equal (entry, comparable)))
935 return entry;
937 hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
938 for (;;)
940 m_collisions++;
941 index += hash2;
942 if (index >= size)
943 index -= size;
945 entry = m_entries[index];
946 if (entry == HTAB_EMPTY_ENTRY
947 || (entry != HTAB_DELETED_ENTRY
948 && Descriptor::equal (entry, comparable)))
949 return entry;
953 /* This function searches for a hash table slot containing an entry
954 equal to the given COMPARABLE element and starting with the given
955 HASH. To delete an entry, call this with insert=NO_INSERT, then
956 call clear_slot on the slot returned (possibly after doing some
957 checks). To insert an entry, call this with insert=INSERT, then
958 write the value you want into the returned slot. When inserting an
959 entry, NULL may be returned if memory allocation fails. */
961 template<typename Descriptor, template<typename Type> class Allocator>
962 typename hash_table<Descriptor, Allocator, false>::value_type **
963 hash_table<Descriptor, Allocator, false>
964 ::find_slot_with_hash (const compare_type *comparable, hashval_t hash,
965 enum insert_option insert)
967 if (insert == INSERT && m_size * 3 <= m_n_elements * 4)
968 expand ();
970 m_searches++;
972 value_type **first_deleted_slot = NULL;
973 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
974 hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
975 value_type *entry = m_entries[index];
976 size_t size = m_size;
977 if (entry == HTAB_EMPTY_ENTRY)
978 goto empty_entry;
979 else if (entry == HTAB_DELETED_ENTRY)
980 first_deleted_slot = &m_entries[index];
981 else if (Descriptor::equal (entry, comparable))
982 return &m_entries[index];
984 for (;;)
986 m_collisions++;
987 index += hash2;
988 if (index >= size)
989 index -= size;
991 entry = m_entries[index];
992 if (entry == HTAB_EMPTY_ENTRY)
993 goto empty_entry;
994 else if (entry == HTAB_DELETED_ENTRY)
996 if (!first_deleted_slot)
997 first_deleted_slot = &m_entries[index];
999 else if (Descriptor::equal (entry, comparable))
1000 return &m_entries[index];
1003 empty_entry:
1004 if (insert == NO_INSERT)
1005 return NULL;
1007 if (first_deleted_slot)
1009 m_n_deleted--;
1010 *first_deleted_slot = static_cast <value_type *> (HTAB_EMPTY_ENTRY);
1011 return first_deleted_slot;
1014 m_n_elements++;
1015 return &m_entries[index];
1018 /* This function deletes an element with the given COMPARABLE value
1019 from hash table starting with the given HASH. If there is no
1020 matching element in the hash table, this function does nothing. */
1022 template<typename Descriptor, template<typename Type> class Allocator>
1023 void
1024 hash_table<Descriptor, Allocator, false>
1025 ::remove_elt_with_hash (const compare_type *comparable, hashval_t hash)
1027 value_type **slot = find_slot_with_hash (comparable, hash, NO_INSERT);
1028 if (*slot == HTAB_EMPTY_ENTRY)
1029 return;
1031 Descriptor::remove (*slot);
1033 *slot = static_cast <value_type *> (HTAB_DELETED_ENTRY);
1034 m_n_deleted++;
1037 /* This function scans over the entire hash table calling CALLBACK for
1038 each live entry. If CALLBACK returns false, the iteration stops.
1039 ARGUMENT is passed as CALLBACK's second argument. */
1041 template<typename Descriptor, template<typename Type> class Allocator>
1042 template<typename Argument,
1043 int (*Callback) (typename hash_table<Descriptor, Allocator,
1044 false>::value_type **slot,
1045 Argument argument)>
1046 void
1047 hash_table<Descriptor, Allocator, false>::traverse_noresize (Argument argument)
1049 value_type **slot = m_entries;
1050 value_type **limit = slot + size ();
1054 value_type *x = *slot;
1056 if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
1057 if (! Callback (slot, argument))
1058 break;
1060 while (++slot < limit);
1063 /* Like traverse_noresize, but does resize the table when it is too empty
1064 to improve effectivity of subsequent calls. */
1066 template <typename Descriptor,
1067 template <typename Type> class Allocator>
1068 template <typename Argument,
1069 int (*Callback) (typename hash_table<Descriptor, Allocator,
1070 false>::value_type **slot,
1071 Argument argument)>
1072 void
1073 hash_table<Descriptor, Allocator, false>::traverse (Argument argument)
1075 size_t size = m_size;
1076 if (elements () * 8 < size && size > 32)
1077 expand ();
1079 traverse_noresize <Argument, Callback> (argument);
1082 /* Slide down the iterator slots until an active entry is found. */
1084 template<typename Descriptor, template<typename Type> class Allocator>
1085 void
1086 hash_table<Descriptor, Allocator, false>::iterator::slide ()
1088 for ( ; m_slot < m_limit; ++m_slot )
1090 value_type *x = *m_slot;
1091 if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
1092 return;
1094 m_slot = NULL;
1095 m_limit = NULL;
1098 /* Bump the iterator. */
1100 template<typename Descriptor, template<typename Type> class Allocator>
1101 inline typename hash_table<Descriptor, Allocator, false>::iterator &
1102 hash_table<Descriptor, Allocator, false>::iterator::operator ++ ()
1104 ++m_slot;
1105 slide ();
1106 return *this;
1109 /* A partial specialization used when values should be stored directly. */
1111 template <typename Descriptor,
1112 template<typename Type> class Allocator>
1113 class hash_table<Descriptor, Allocator, true>
1115 typedef typename Descriptor::value_type value_type;
1116 typedef typename Descriptor::compare_type compare_type;
1118 public:
1119 explicit hash_table (size_t, bool ggc = false);
1120 ~hash_table ();
1122 /* Create a hash_table in gc memory. */
1124 static hash_table *
1125 create_ggc (size_t n)
1127 hash_table *table = ggc_alloc<hash_table> ();
1128 new (table) hash_table (n, true);
1129 return table;
1132 /* Current size (in entries) of the hash table. */
1133 size_t size () const { return m_size; }
1135 /* Return the current number of elements in this hash table. */
1136 size_t elements () const { return m_n_elements - m_n_deleted; }
1138 /* Return the current number of elements in this hash table. */
1139 size_t elements_with_deleted () const { return m_n_elements; }
1141 /* This function clears all entries in the given hash table. */
1142 void empty ();
1144 /* This function clears a specified SLOT in a hash table. It is
1145 useful when you've already done the lookup and don't want to do it
1146 again. */
1148 void clear_slot (value_type *);
1150 /* This function searches for a hash table entry equal to the given
1151 COMPARABLE element starting with the given HASH value. It cannot
1152 be used to insert or delete an element. */
1153 value_type &find_with_hash (const compare_type &, hashval_t);
1155 /* Like find_slot_with_hash, but compute the hash value from the element. */
1156 value_type &find (const value_type &value)
1158 return find_with_hash (value, Descriptor::hash (value));
1161 value_type *find_slot (const value_type &value, insert_option insert)
1163 return find_slot_with_hash (value, Descriptor::hash (value), insert);
1166 /* This function searches for a hash table slot containing an entry
1167 equal to the given COMPARABLE element and starting with the given
1168 HASH. To delete an entry, call this with insert=NO_INSERT, then
1169 call clear_slot on the slot returned (possibly after doing some
1170 checks). To insert an entry, call this with insert=INSERT, then
1171 write the value you want into the returned slot. When inserting an
1172 entry, NULL may be returned if memory allocation fails. */
1173 value_type *find_slot_with_hash (const compare_type &comparable,
1174 hashval_t hash, enum insert_option insert);
1176 /* This function deletes an element with the given COMPARABLE value
1177 from hash table starting with the given HASH. If there is no
1178 matching element in the hash table, this function does nothing. */
1179 void remove_elt_with_hash (const compare_type &, hashval_t);
1181 /* Like remove_elt_with_hash, but compute the hash value from the element. */
1182 void remove_elt (const value_type &value)
1184 remove_elt_with_hash (value, Descriptor::hash (value));
1187 /* This function scans over the entire hash table calling CALLBACK for
1188 each live entry. If CALLBACK returns false, the iteration stops.
1189 ARGUMENT is passed as CALLBACK's second argument. */
1190 template <typename Argument,
1191 int (*Callback) (value_type *slot, Argument argument)>
1192 void traverse_noresize (Argument argument);
1194 /* Like traverse_noresize, but does resize the table when it is too empty
1195 to improve effectivity of subsequent calls. */
1196 template <typename Argument,
1197 int (*Callback) (value_type *slot, Argument argument)>
1198 void traverse (Argument argument);
1200 class iterator
1202 public:
1203 iterator () : m_slot (NULL), m_limit (NULL) {}
1205 iterator (value_type *slot, value_type *limit) :
1206 m_slot (slot), m_limit (limit) {}
1208 inline value_type &operator * () { return *m_slot; }
1209 void slide ();
1210 inline iterator &operator ++ ();
1211 bool operator != (const iterator &other) const
1213 return m_slot != other.m_slot || m_limit != other.m_limit;
1216 private:
1217 value_type *m_slot;
1218 value_type *m_limit;
1221 iterator begin () const
1223 iterator iter (m_entries, m_entries + m_size);
1224 iter.slide ();
1225 return iter;
1228 iterator end () const { return iterator (); }
1230 double collisions () const
1232 return m_searches ? static_cast <double> (m_collisions) / m_searches : 0;
1235 private:
1236 template<typename T> friend void gt_ggc_mx (hash_table<T> *);
1237 template<typename T> friend void gt_pch_nx (hash_table<T> *);
1238 template<typename T> friend void
1239 hashtab_entry_note_pointers (void *, void *, gt_pointer_operator, void *);
1240 template<typename T, typename U, typename V> friend void
1241 gt_pch_nx (hash_map<T, U, V> *, gt_pointer_operator, void *);
1242 template<typename T, typename U> friend void gt_pch_nx (hash_set<T, U> *,
1243 gt_pointer_operator,
1244 void *);
1245 template<typename T> friend void gt_pch_nx (hash_table<T> *,
1246 gt_pointer_operator, void *);
1248 value_type *alloc_entries (size_t n) const;
1249 value_type *find_empty_slot_for_expand (hashval_t);
1250 void expand ();
1251 static bool is_deleted (value_type &v)
1253 return is_deleted_helper<value_type, Descriptor>::call (v);
1255 static bool is_empty (value_type &v)
1257 return is_empty_helper<value_type, Descriptor>::call (v);
1260 static void mark_deleted (value_type &v)
1262 return mark_deleted_helper<value_type, Descriptor>::call (v);
1265 static void mark_empty (value_type &v)
1267 return mark_empty_helper<value_type, Descriptor>::call (v);
1270 /* Table itself. */
1271 typename Descriptor::value_type *m_entries;
1273 size_t m_size;
1275 /* Current number of elements including also deleted elements. */
1276 size_t m_n_elements;
1278 /* Current number of deleted elements in the table. */
1279 size_t m_n_deleted;
1281 /* The following member is used for debugging. Its value is number
1282 of all calls of `htab_find_slot' for the hash table. */
1283 unsigned int m_searches;
1285 /* The following member is used for debugging. Its value is number
1286 of collisions fixed for time of work with the hash table. */
1287 unsigned int m_collisions;
1289 /* Current size (in entries) of the hash table, as an index into the
1290 table of primes. */
1291 unsigned int m_size_prime_index;
1293 /* if m_entries is stored in ggc memory. */
1294 bool m_ggc;
1297 template<typename Descriptor, template<typename Type> class Allocator>
1298 hash_table<Descriptor, Allocator, true>::hash_table (size_t size, bool ggc) :
1299 m_n_elements (0), m_n_deleted (0), m_searches (0), m_collisions (0),
1300 m_ggc (ggc)
1302 unsigned int size_prime_index;
1304 size_prime_index = hash_table_higher_prime_index (size);
1305 size = prime_tab[size_prime_index].prime;
1307 m_entries = alloc_entries (size);
1308 m_size = size;
1309 m_size_prime_index = size_prime_index;
1312 template<typename Descriptor, template<typename Type> class Allocator>
1313 hash_table<Descriptor, Allocator, true>::~hash_table ()
1315 for (size_t i = m_size - 1; i < m_size; i--)
1316 if (!is_empty (m_entries[i]) && !is_deleted (m_entries[i]))
1317 Descriptor::remove (m_entries[i]);
1319 if (!m_ggc)
1320 Allocator <value_type> ::data_free (m_entries);
1321 else
1322 ggc_free (m_entries);
1325 /* This function returns an array of empty hash table elements. */
1327 template<typename Descriptor, template<typename Type> class Allocator>
1328 inline typename hash_table<Descriptor, Allocator, true>::value_type *
1329 hash_table<Descriptor, Allocator, true>::alloc_entries (size_t n) const
1331 value_type *nentries;
1333 if (!m_ggc)
1334 nentries = Allocator <value_type> ::data_alloc (n);
1335 else
1336 nentries = ::ggc_cleared_vec_alloc<value_type> (n);
1338 gcc_assert (nentries != NULL);
1339 for (size_t i = 0; i < n; i++)
1340 mark_empty (nentries[i]);
1342 return nentries;
1345 /* Similar to find_slot, but without several unwanted side effects:
1346 - Does not call equal when it finds an existing entry.
1347 - Does not change the count of elements/searches/collisions in the
1348 hash table.
1349 This function also assumes there are no deleted entries in the table.
1350 HASH is the hash value for the element to be inserted. */
1352 template<typename Descriptor, template<typename Type> class Allocator>
1353 typename hash_table<Descriptor, Allocator, true>::value_type *
1354 hash_table<Descriptor, Allocator, true>
1355 ::find_empty_slot_for_expand (hashval_t hash)
1357 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
1358 size_t size = m_size;
1359 value_type *slot = m_entries + index;
1360 hashval_t hash2;
1362 if (is_empty (*slot))
1363 return slot;
1364 #ifdef ENABLE_CHECKING
1365 gcc_checking_assert (!is_deleted (*slot));
1366 #endif
1368 hash2 = hash_table_mod2 (hash, m_size_prime_index);
1369 for (;;)
1371 index += hash2;
1372 if (index >= size)
1373 index -= size;
1375 slot = m_entries + index;
1376 if (is_empty (*slot))
1377 return slot;
1378 #ifdef ENABLE_CHECKING
1379 gcc_checking_assert (!is_deleted (*slot));
1380 #endif
1384 /* The following function changes size of memory allocated for the
1385 entries and repeatedly inserts the table elements. The occupancy
1386 of the table after the call will be about 50%. Naturally the hash
1387 table must already exist. Remember also that the place of the
1388 table entries is changed. If memory allocation fails, this function
1389 will abort. */
1391 template<typename Descriptor, template<typename Type> class Allocator>
1392 void
1393 hash_table<Descriptor, Allocator, true>::expand ()
1395 value_type *oentries = m_entries;
1396 unsigned int oindex = m_size_prime_index;
1397 size_t osize = size ();
1398 value_type *olimit = oentries + osize;
1399 size_t elts = elements ();
1401 /* Resize only when table after removal of unused elements is either
1402 too full or too empty. */
1403 unsigned int nindex;
1404 size_t nsize;
1405 if (elts * 2 > osize || (elts * 8 < osize && osize > 32))
1407 nindex = hash_table_higher_prime_index (elts * 2);
1408 nsize = prime_tab[nindex].prime;
1410 else
1412 nindex = oindex;
1413 nsize = osize;
1416 value_type *nentries = alloc_entries (nsize);
1417 m_entries = nentries;
1418 m_size = nsize;
1419 m_size_prime_index = nindex;
1420 m_n_elements -= m_n_deleted;
1421 m_n_deleted = 0;
1423 value_type *p = oentries;
1426 value_type &x = *p;
1428 if (!is_empty (x) && !is_deleted (x))
1430 value_type *q = find_empty_slot_for_expand (Descriptor::hash (x));
1432 *q = x;
1435 p++;
1437 while (p < olimit);
1439 if (!m_ggc)
1440 Allocator <value_type> ::data_free (oentries);
1441 else
1442 ggc_free (oentries);
1445 template<typename Descriptor, template<typename Type> class Allocator>
1446 void
1447 hash_table<Descriptor, Allocator, true>::empty ()
1449 size_t size = m_size;
1450 value_type *entries = m_entries;
1451 int i;
1453 for (i = size - 1; i >= 0; i--)
1454 if (!is_empty (entries[i]) && !is_deleted (entries[i]))
1455 Descriptor::remove (entries[i]);
1457 /* Instead of clearing megabyte, downsize the table. */
1458 if (size > 1024*1024 / sizeof (PTR))
1460 int nindex = hash_table_higher_prime_index (1024 / sizeof (PTR));
1461 int nsize = prime_tab[nindex].prime;
1463 if (!m_ggc)
1464 Allocator <value_type> ::data_free (m_entries);
1465 else
1466 ggc_free (m_entries);
1468 m_entries = alloc_entries (nsize);
1469 m_size = nsize;
1470 m_size_prime_index = nindex;
1472 else
1473 memset (entries, 0, size * sizeof (value_type));
1474 m_n_deleted = 0;
1475 m_n_elements = 0;
1478 /* This function clears a specified SLOT in a hash table. It is
1479 useful when you've already done the lookup and don't want to do it
1480 again. */
1482 template<typename Descriptor, template<typename Type> class Allocator>
1483 void
1484 hash_table<Descriptor, Allocator, true>::clear_slot (value_type *slot)
1486 gcc_checking_assert (!(slot < m_entries || slot >= m_entries + size ()
1487 || is_empty (*slot) || is_deleted (*slot)));
1489 Descriptor::remove (*slot);
1491 mark_deleted (*slot);
1492 m_n_deleted++;
1495 /* This function searches for a hash table entry equal to the given
1496 COMPARABLE element starting with the given HASH value. It cannot
1497 be used to insert or delete an element. */
1499 template<typename Descriptor, template<typename Type> class Allocator>
1500 typename hash_table<Descriptor, Allocator, true>::value_type &
1501 hash_table<Descriptor, Allocator, true>
1502 ::find_with_hash (const compare_type &comparable, hashval_t hash)
1504 m_searches++;
1505 size_t size = m_size;
1506 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
1508 value_type *entry = &m_entries[index];
1509 if (is_empty (*entry)
1510 || (!is_deleted (*entry) && Descriptor::equal (*entry, comparable)))
1511 return *entry;
1513 hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
1514 for (;;)
1516 m_collisions++;
1517 index += hash2;
1518 if (index >= size)
1519 index -= size;
1521 entry = &m_entries[index];
1522 if (is_empty (*entry)
1523 || (!is_deleted (*entry) && Descriptor::equal (*entry, comparable)))
1524 return *entry;
1528 /* This function searches for a hash table slot containing an entry
1529 equal to the given COMPARABLE element and starting with the given
1530 HASH. To delete an entry, call this with insert=NO_INSERT, then
1531 call clear_slot on the slot returned (possibly after doing some
1532 checks). To insert an entry, call this with insert=INSERT, then
1533 write the value you want into the returned slot. When inserting an
1534 entry, NULL may be returned if memory allocation fails. */
1536 template<typename Descriptor, template<typename Type> class Allocator>
1537 typename hash_table<Descriptor, Allocator, true>::value_type *
1538 hash_table<Descriptor, Allocator, true>
1539 ::find_slot_with_hash (const compare_type &comparable, hashval_t hash,
1540 enum insert_option insert)
1542 if (insert == INSERT && m_size * 3 <= m_n_elements * 4)
1543 expand ();
1545 m_searches++;
1547 value_type *first_deleted_slot = NULL;
1548 hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
1549 hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
1550 value_type *entry = &m_entries[index];
1551 size_t size = m_size;
1552 if (is_empty (*entry))
1553 goto empty_entry;
1554 else if (is_deleted (*entry))
1555 first_deleted_slot = &m_entries[index];
1556 else if (Descriptor::equal (*entry, comparable))
1557 return &m_entries[index];
1559 for (;;)
1561 m_collisions++;
1562 index += hash2;
1563 if (index >= size)
1564 index -= size;
1566 entry = &m_entries[index];
1567 if (is_empty (*entry))
1568 goto empty_entry;
1569 else if (is_deleted (*entry))
1571 if (!first_deleted_slot)
1572 first_deleted_slot = &m_entries[index];
1574 else if (Descriptor::equal (*entry, comparable))
1575 return &m_entries[index];
1578 empty_entry:
1579 if (insert == NO_INSERT)
1580 return NULL;
1582 if (first_deleted_slot)
1584 m_n_deleted--;
1585 mark_empty (*first_deleted_slot);
1586 return first_deleted_slot;
1589 m_n_elements++;
1590 return &m_entries[index];
1593 /* This function deletes an element with the given COMPARABLE value
1594 from hash table starting with the given HASH. If there is no
1595 matching element in the hash table, this function does nothing. */
1597 template<typename Descriptor, template<typename Type> class Allocator>
1598 void
1599 hash_table<Descriptor, Allocator, true>
1600 ::remove_elt_with_hash (const compare_type &comparable, hashval_t hash)
1602 value_type *slot = find_slot_with_hash (comparable, hash, NO_INSERT);
1603 if (is_empty (*slot))
1604 return;
1606 Descriptor::remove (*slot);
1608 mark_deleted (*slot);
1609 m_n_deleted++;
1612 /* This function scans over the entire hash table calling CALLBACK for
1613 each live entry. If CALLBACK returns false, the iteration stops.
1614 ARGUMENT is passed as CALLBACK's second argument. */
1616 template<typename Descriptor,
1617 template<typename Type> class Allocator>
1618 template<typename Argument,
1619 int (*Callback) (typename hash_table<Descriptor, Allocator,
1620 true>::value_type *slot,
1621 Argument argument)>
1622 void
1623 hash_table<Descriptor, Allocator, true>::traverse_noresize (Argument argument)
1625 value_type *slot = m_entries;
1626 value_type *limit = slot + size ();
1630 value_type &x = *slot;
1632 if (!is_empty (x) && !is_deleted (x))
1633 if (! Callback (slot, argument))
1634 break;
1636 while (++slot < limit);
1639 /* Like traverse_noresize, but does resize the table when it is too empty
1640 to improve effectivity of subsequent calls. */
1642 template <typename Descriptor,
1643 template <typename Type> class Allocator>
1644 template <typename Argument,
1645 int (*Callback) (typename hash_table<Descriptor, Allocator,
1646 true>::value_type *slot,
1647 Argument argument)>
1648 void
1649 hash_table<Descriptor, Allocator, true>::traverse (Argument argument)
1651 size_t size = m_size;
1652 if (elements () * 8 < size && size > 32)
1653 expand ();
1655 traverse_noresize <Argument, Callback> (argument);
1658 /* Slide down the iterator slots until an active entry is found. */
1660 template<typename Descriptor, template<typename Type> class Allocator>
1661 void
1662 hash_table<Descriptor, Allocator, true>::iterator::slide ()
1664 for ( ; m_slot < m_limit; ++m_slot )
1666 value_type &x = *m_slot;
1667 if (!is_empty (x) && !is_deleted (x))
1668 return;
1670 m_slot = NULL;
1671 m_limit = NULL;
1674 /* Bump the iterator. */
1676 template<typename Descriptor, template<typename Type> class Allocator>
1677 inline typename hash_table<Descriptor, Allocator, true>::iterator &
1678 hash_table<Descriptor, Allocator, true>::iterator::operator ++ ()
1680 ++m_slot;
1681 slide ();
1682 return *this;
1686 /* Iterate through the elements of hash_table HTAB,
1687 using hash_table <....>::iterator ITER,
1688 storing each element in RESULT, which is of type TYPE. */
1690 #define FOR_EACH_HASH_TABLE_ELEMENT(HTAB, RESULT, TYPE, ITER) \
1691 for ((ITER) = (HTAB).begin (); \
1692 (ITER) != (HTAB).end () ? (RESULT = *(ITER) , true) : false; \
1693 ++(ITER))
1695 /* ggc walking routines. */
1697 template<typename E>
1698 static inline void
1699 gt_ggc_mx (hash_table<E> *h)
1701 typedef hash_table<E> table;
1703 if (!ggc_test_and_set_mark (h->m_entries))
1704 return;
1706 for (size_t i = 0; i < h->m_size; i++)
1708 if (table::is_empty (h->m_entries[i])
1709 || table::is_deleted (h->m_entries[i]))
1710 continue;
1712 E::ggc_mx (h->m_entries[i]);
1716 template<typename D>
1717 static inline void
1718 hashtab_entry_note_pointers (void *obj, void *h, gt_pointer_operator op,
1719 void *cookie)
1721 hash_table<D> *map = static_cast<hash_table<D> *> (h);
1722 gcc_checking_assert (map->m_entries == obj);
1723 for (size_t i = 0; i < map->m_size; i++)
1725 typedef hash_table<D> table;
1726 if (table::is_empty (map->m_entries[i])
1727 || table::is_deleted (map->m_entries[i]))
1728 continue;
1730 D::pch_nx (map->m_entries[i], op, cookie);
1734 template<typename D>
1735 static void
1736 gt_pch_nx (hash_table<D> *h)
1738 bool success
1739 = gt_pch_note_object (h->m_entries, h, hashtab_entry_note_pointers<D>);
1740 gcc_checking_assert (success);
1741 for (size_t i = 0; i < h->m_size; i++)
1743 if (hash_table<D>::is_empty (h->m_entries[i])
1744 || hash_table<D>::is_deleted (h->m_entries[i]))
1745 continue;
1747 D::pch_nx (h->m_entries[i]);
1751 template<typename D>
1752 static inline void
1753 gt_pch_nx (hash_table<D> *h, gt_pointer_operator op, void *cookie)
1755 op (&h->m_entries, cookie);
1758 template<typename H>
1759 inline void
1760 gt_cleare_cache (hash_table<H> *h)
1762 if (!h)
1763 return;
1765 for (typename hash_table<H>::iterator iter = h->begin (); iter != h->end ();
1766 ++iter)
1767 H::handle_cache_entry (*iter);
1770 #endif /* TYPED_HASHTAB_H */