1 /* A type-safe hash table template.
2 Copyright (C) 2012-2014 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
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
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.
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
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
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
87 * typed_free_remove implements the static 'remove' member function
90 * typed_noop_remove implements the static 'remove' member function
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 *);
122 some_type_hasher::hash (const value_type *e)
123 { ... compute and return a hash value for E ... }
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
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;
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 ();
170 if ((*iter).status == INFO_READY)
173 Or with common sub-expression elimination:
175 for (info_table_type::iterator iter = info_table.begin ();
176 iter != info_table.end ();
179 some_info &elem = *iter;
180 if (elem.status == INFO_READY)
184 One can also use a more typical GCC style:
186 typedef some_info *some_info_p;
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)
196 #ifndef TYPED_HASHTAB_H
197 #define TYPED_HASHTAB_H
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
>
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
>
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
>
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
>
250 typed_free_remove
<Type
>::remove (Type
*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
>
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
>
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
>
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. */
311 typedef T value_type
;
312 typedef T compare_type
;
313 typedef int store_values_directly
;
315 static void remove (T
) {}
320 extern void gt_ggc_mx (T
&);
327 extern void gt_pch_nx (T
&);
332 pch_nx (T
&p
, gt_pointer_operator op
, void *cookie
)
338 /* Hasher for cache entry in gc memory. */
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
&) {}
356 extern void gt_pch_nx (T
&);
361 pch_nx (T
&p
, gt_pointer_operator op
, void *cookie
)
366 /* Clear out entries if they are about to be gc'd. */
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. */
383 hashval_t inv_m2
; /* inverse of prime-2 */
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
)
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
404 on modern systems running a compiler. */
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;
421 /* Compute the primary table index for HASH given current prime index. */
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. */
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;
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
476 return Traits::is_deleted (v
);
480 template<typename Type
, typename Traits
>
481 struct is_deleted_helper
<Type
*, Traits
, false>
486 return v
== HTAB_DELETED_ENTRY
;
490 template<typename Traits
>
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
505 return Traits::is_empty (v
);
509 template<typename Type
, typename Traits
>
510 struct is_empty_helper
<Type
*, Traits
, false>
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
534 Traits::mark_deleted (v
);
538 template<typename Type
, typename Traits
>
539 struct mark_deleted_helper
<Type
*, Traits
, false>
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
563 Traits::mark_empty (v
);
567 template<typename Type
, typename Traits
>
568 struct mark_empty_helper
<Type
*, Traits
, false>
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
603 template <typename Descriptor
,
604 template<typename Type
> class Allocator
= xcallocator
,
605 bool Storage
= storage_tester
<Descriptor
>::value
>
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
;
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. */
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
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
);
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
; }
699 inline iterator
&operator ++ ();
700 bool operator != (const iterator
&other
) const
702 return m_slot
!= other
.m_slot
|| m_limit
!= other
.m_limit
;
707 value_type
**m_limit
;
710 iterator
begin () const
712 iterator
iter (m_entries
, m_entries
+ m_size
);
717 iterator
end () const { return iterator (); }
719 double collisions () const
721 return m_searches
? static_cast <double> (m_collisions
) / m_searches
: 0;
726 value_type
**find_empty_slot_for_expand (hashval_t
);
730 typename
Descriptor::value_type
**m_entries
;
734 /* Current number of elements including also deleted elements. */
737 /* Current number of deleted elements in the table. */
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
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
);
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
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
;
795 if (*slot
== HTAB_EMPTY_ENTRY
)
797 gcc_checking_assert (*slot
!= HTAB_DELETED_ENTRY
);
799 hash2
= hash_table_mod2 (hash
, m_size_prime_index
);
806 slot
= m_entries
+ index
;
807 if (*slot
== HTAB_EMPTY_ENTRY
)
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
820 template<typename Descriptor
, template<typename Type
> class Allocator
>
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. */
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
;
845 value_type
**nentries
= Allocator
<value_type
*> ::data_alloc (nsize
);
846 gcc_assert (nentries
!= NULL
);
847 m_entries
= nentries
;
849 m_size_prime_index
= nindex
;
850 m_n_elements
-= m_n_deleted
;
853 value_type
**p
= oentries
;
858 if (x
!= HTAB_EMPTY_ENTRY
&& x
!= HTAB_DELETED_ENTRY
)
860 value_type
**q
= find_empty_slot_for_expand (Descriptor::hash (x
));
869 Allocator
<value_type
*> ::data_free (oentries
);
872 template<typename Descriptor
, template<typename Type
> class Allocator
>
874 hash_table
<Descriptor
, Allocator
, false>::empty ()
876 size_t size
= m_size
;
877 value_type
**entries
= m_entries
;
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
);
893 m_size_prime_index
= nindex
;
896 memset (entries
, 0, size
* sizeof (value_type
*));
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
905 template<typename Descriptor
, template<typename Type
> class Allocator
>
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
);
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
)
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
)))
937 hashval_t hash2
= hash_table_mod2 (hash
, m_size_prime_index
);
945 entry
= m_entries
[index
];
946 if (entry
== HTAB_EMPTY_ENTRY
947 || (entry
!= HTAB_DELETED_ENTRY
948 && Descriptor::equal (entry
, comparable
)))
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)
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
)
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
];
991 entry
= m_entries
[index
];
992 if (entry
== HTAB_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
];
1004 if (insert
== NO_INSERT
)
1007 if (first_deleted_slot
)
1010 *first_deleted_slot
= static_cast <value_type
*> (HTAB_EMPTY_ENTRY
);
1011 return first_deleted_slot
;
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
>
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
)
1031 Descriptor::remove (*slot
);
1033 *slot
= static_cast <value_type
*> (HTAB_DELETED_ENTRY
);
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
,
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
))
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
,
1073 hash_table
<Descriptor
, Allocator
, false>::traverse (Argument argument
)
1075 size_t size
= m_size
;
1076 if (elements () * 8 < size
&& size
> 32)
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
>
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
)
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 ++ ()
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
;
1119 explicit hash_table (size_t, bool ggc
= false);
1122 /* Create a hash_table in gc memory. */
1125 create_ggc (size_t n
)
1127 hash_table
*table
= ggc_alloc
<hash_table
> ();
1128 new (table
) hash_table (n
, true);
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. */
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
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
);
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
; }
1210 inline iterator
&operator ++ ();
1211 bool operator != (const iterator
&other
) const
1213 return m_slot
!= other
.m_slot
|| m_limit
!= other
.m_limit
;
1218 value_type
*m_limit
;
1221 iterator
begin () const
1223 iterator
iter (m_entries
, m_entries
+ m_size
);
1228 iterator
end () const { return iterator (); }
1230 double collisions () const
1232 return m_searches
? static_cast <double> (m_collisions
) / m_searches
: 0;
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
,
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
);
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
);
1271 typename
Descriptor::value_type
*m_entries
;
1275 /* Current number of elements including also deleted elements. */
1276 size_t m_n_elements
;
1278 /* Current number of deleted elements in the table. */
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
1291 unsigned int m_size_prime_index
;
1293 /* if m_entries is stored in ggc memory. */
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),
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
);
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
]);
1320 Allocator
<value_type
> ::data_free (m_entries
);
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
;
1334 nentries
= Allocator
<value_type
> ::data_alloc (n
);
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
]);
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
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
;
1362 if (is_empty (*slot
))
1364 #ifdef ENABLE_CHECKING
1365 gcc_checking_assert (!is_deleted (*slot
));
1368 hash2
= hash_table_mod2 (hash
, m_size_prime_index
);
1375 slot
= m_entries
+ index
;
1376 if (is_empty (*slot
))
1378 #ifdef ENABLE_CHECKING
1379 gcc_checking_assert (!is_deleted (*slot
));
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
1391 template<typename Descriptor
, template<typename Type
> class Allocator
>
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
;
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
;
1416 value_type
*nentries
= alloc_entries (nsize
);
1417 m_entries
= nentries
;
1419 m_size_prime_index
= nindex
;
1420 m_n_elements
-= m_n_deleted
;
1423 value_type
*p
= oentries
;
1428 if (!is_empty (x
) && !is_deleted (x
))
1430 value_type
*q
= find_empty_slot_for_expand (Descriptor::hash (x
));
1440 Allocator
<value_type
> ::data_free (oentries
);
1442 ggc_free (oentries
);
1445 template<typename Descriptor
, template<typename Type
> class Allocator
>
1447 hash_table
<Descriptor
, Allocator
, true>::empty ()
1449 size_t size
= m_size
;
1450 value_type
*entries
= m_entries
;
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
;
1464 Allocator
<value_type
> ::data_free (m_entries
);
1466 ggc_free (m_entries
);
1468 m_entries
= alloc_entries (nsize
);
1470 m_size_prime_index
= nindex
;
1473 memset (entries
, 0, size
* sizeof (value_type
));
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
1482 template<typename Descriptor
, template<typename Type
> class Allocator
>
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
);
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
)
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
)))
1513 hashval_t hash2
= hash_table_mod2 (hash
, m_size_prime_index
);
1521 entry
= &m_entries
[index
];
1522 if (is_empty (*entry
)
1523 || (!is_deleted (*entry
) && Descriptor::equal (*entry
, comparable
)))
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)
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
))
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
];
1566 entry
= &m_entries
[index
];
1567 if (is_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
];
1579 if (insert
== NO_INSERT
)
1582 if (first_deleted_slot
)
1585 mark_empty (*first_deleted_slot
);
1586 return first_deleted_slot
;
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
>
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
))
1606 Descriptor::remove (*slot
);
1608 mark_deleted (*slot
);
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
,
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
))
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
,
1649 hash_table
<Descriptor
, Allocator
, true>::traverse (Argument argument
)
1651 size_t size
= m_size
;
1652 if (elements () * 8 < size
&& size
> 32)
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
>
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
))
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 ++ ()
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; \
1695 /* ggc walking routines. */
1697 template<typename E
>
1699 gt_ggc_mx (hash_table
<E
> *h
)
1701 typedef hash_table
<E
> table
;
1703 if (!ggc_test_and_set_mark (h
->m_entries
))
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
]))
1712 E::ggc_mx (h
->m_entries
[i
]);
1716 template<typename D
>
1718 hashtab_entry_note_pointers (void *obj
, void *h
, gt_pointer_operator op
,
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
]))
1730 D::pch_nx (map
->m_entries
[i
], op
, cookie
);
1734 template<typename D
>
1736 gt_pch_nx (hash_table
<D
> *h
)
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
]))
1747 D::pch_nx (h
->m_entries
[i
]);
1751 template<typename D
>
1753 gt_pch_nx (hash_table
<D
> *h
, gt_pointer_operator op
, void *cookie
)
1755 op (&h
->m_entries
, cookie
);
1758 template<typename H
>
1760 gt_cleare_cache (hash_table
<H
> *h
)
1765 for (typename hash_table
<H
>::iterator iter
= h
->begin (); iter
!= h
->end ();
1767 H::handle_cache_entry (*iter
);
1770 #endif /* TYPED_HASHTAB_H */