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
202 template<typename
, typename
, typename
> class hash_map
;
203 template<typename
, typename
> class hash_set
;
205 /* The ordinary memory allocator. */
206 /* FIXME (crowl): This allocator may be extracted for wider sharing later. */
208 template <typename Type
>
211 static Type
*data_alloc (size_t count
);
212 static void data_free (Type
*memory
);
216 /* Allocate memory for COUNT data blocks. */
218 template <typename Type
>
220 xcallocator
<Type
>::data_alloc (size_t count
)
222 return static_cast <Type
*> (xcalloc (count
, sizeof (Type
)));
226 /* Free memory for data blocks. */
228 template <typename Type
>
230 xcallocator
<Type
>::data_free (Type
*memory
)
232 return ::free (memory
);
236 /* Helpful type for removing with free. */
238 template <typename Type
>
239 struct typed_free_remove
241 static inline void remove (Type
*p
);
245 /* Remove with free. */
247 template <typename Type
>
249 typed_free_remove
<Type
>::remove (Type
*p
)
255 /* Helpful type for a no-op remove. */
257 template <typename Type
>
258 struct typed_noop_remove
260 static inline void remove (Type
*p
);
264 /* Remove doing nothing. */
266 template <typename Type
>
268 typed_noop_remove
<Type
>::remove (Type
*p ATTRIBUTE_UNUSED
)
273 /* Pointer hash with a no-op remove method. */
275 template <typename Type
>
276 struct pointer_hash
: typed_noop_remove
<Type
>
278 typedef Type
*value_type
;
279 typedef Type
*compare_type
;
280 typedef int store_values_directly
;
282 static inline hashval_t
hash (const value_type
&);
284 static inline bool equal (const value_type
&existing
, const compare_type
&candidate
);
287 template <typename Type
>
289 pointer_hash
<Type
>::hash (const value_type
&candidate
)
291 /* This is a really poor hash function, but it is what the current code uses,
292 so I am reusing it to avoid an additional axis in testing. */
293 return (hashval_t
) ((intptr_t)candidate
>> 3);
296 template <typename Type
>
298 pointer_hash
<Type
>::equal (const value_type
&existing
,
299 const compare_type
&candidate
)
301 return existing
== candidate
;
305 /* Table of primes and their inversion information. */
311 hashval_t inv_m2
; /* inverse of prime-2 */
315 extern struct prime_ent
const prime_tab
[];
318 /* Functions for computing hash table indexes. */
320 extern unsigned int hash_table_higher_prime_index (unsigned long n
);
321 extern hashval_t
hash_table_mod1 (hashval_t hash
, unsigned int index
);
322 extern hashval_t
hash_table_mod2 (hashval_t hash
, unsigned int index
);
324 /* The below is some template meta programming to decide if we should use the
325 hash table partial specialization that directly stores value_type instead of
326 pointers to value_type. If the Descriptor type defines the type
327 Descriptor::store_values_directly then values are stored directly otherwise
328 pointers to them are stored. */
329 template<typename T
> struct notype
{ typedef void type
; };
331 template<typename T
, typename
= void>
332 struct storage_tester
334 static const bool value
= false;
338 struct storage_tester
<T
, typename notype
<typename
339 T::store_values_directly
>::type
>
341 static const bool value
= true;
344 template<typename Traits
>
345 struct has_is_deleted
347 template<typename U
, bool (*)(U
&)> struct helper
{};
348 template<typename U
> static char test (helper
<U
, U::is_deleted
> *);
349 template<typename U
> static int test (...);
350 static const bool value
= sizeof (test
<Traits
> (0)) == sizeof (char);
353 template<typename Type
, typename Traits
, bool = has_is_deleted
<Traits
>::value
>
354 struct is_deleted_helper
359 return Traits::is_deleted (v
);
363 template<typename Type
, typename Traits
>
364 struct is_deleted_helper
<Type
*, Traits
, false>
369 return v
== HTAB_DELETED_ENTRY
;
373 template<typename Traits
>
376 template<typename U
, bool (*)(U
&)> struct helper
{};
377 template<typename U
> static char test (helper
<U
, U::is_empty
> *);
378 template<typename U
> static int test (...);
379 static const bool value
= sizeof (test
<Traits
> (0)) == sizeof (char);
382 template<typename Type
, typename Traits
, bool = has_is_deleted
<Traits
>::value
>
383 struct is_empty_helper
388 return Traits::is_empty (v
);
392 template<typename Type
, typename Traits
>
393 struct is_empty_helper
<Type
*, Traits
, false>
398 return v
== HTAB_EMPTY_ENTRY
;
402 template<typename Traits
>
403 struct has_mark_deleted
405 template<typename U
, void (*)(U
&)> struct helper
{};
406 template<typename U
> static char test (helper
<U
, U::mark_deleted
> *);
407 template<typename U
> static int test (...);
408 static const bool value
= sizeof (test
<Traits
> (0)) == sizeof (char);
411 template<typename Type
, typename Traits
, bool = has_is_deleted
<Traits
>::value
>
412 struct mark_deleted_helper
417 Traits::mark_deleted (v
);
421 template<typename Type
, typename Traits
>
422 struct mark_deleted_helper
<Type
*, Traits
, false>
427 v
= static_cast<Type
*> (HTAB_DELETED_ENTRY
);
431 template<typename Traits
>
432 struct has_mark_empty
434 template<typename U
, void (*)(U
&)> struct helper
{};
435 template<typename U
> static char test (helper
<U
, U::mark_empty
> *);
436 template<typename U
> static int test (...);
437 static const bool value
= sizeof (test
<Traits
> (0)) == sizeof (char);
440 template<typename Type
, typename Traits
, bool = has_is_deleted
<Traits
>::value
>
441 struct mark_empty_helper
446 Traits::mark_empty (v
);
450 template<typename Type
, typename Traits
>
451 struct mark_empty_helper
<Type
*, Traits
, false>
456 v
= static_cast<Type
*> (HTAB_EMPTY_ENTRY
);
460 /* User-facing hash table type.
462 The table stores elements of type Descriptor::value_type, or pointers to
463 objects of type value_type if the descriptor does not define the type
464 store_values_directly.
466 It hashes values with the hash member function.
467 The table currently works with relatively weak hash functions.
468 Use typed_pointer_hash <Value> when hashing pointers instead of objects.
470 It compares elements with the equal member function.
471 Two elements with the same hash may not be equal.
472 Use typed_pointer_equal <Value> when hashing pointers instead of objects.
474 It removes elements with the remove member function.
475 This feature is useful for freeing memory.
476 Derive from typed_null_remove <Value> when not freeing objects.
477 Derive from typed_free_remove <Value> when doing a simple object free.
479 Specify the template Allocator to allocate and free memory.
480 The default is xcallocator.
482 Storage is an implementation detail and should not be used outside the
486 template <typename Descriptor
,
487 template<typename Type
> class Allocator
= xcallocator
,
488 bool Storage
= storage_tester
<Descriptor
>::value
>
493 template <typename Descriptor
,
494 template<typename Type
> class Allocator
>
495 class hash_table
<Descriptor
, Allocator
, false>
497 typedef typename
Descriptor::value_type value_type
;
498 typedef typename
Descriptor::compare_type compare_type
;
504 /* Current size (in entries) of the hash table. */
505 size_t size () const { return m_size
; }
507 /* Return the current number of elements in this hash table. */
508 size_t elements () const { return m_n_elements
- m_n_deleted
; }
510 /* Return the current number of elements in this hash table. */
511 size_t elements_with_deleted () const { return m_n_elements
; }
513 /* This function clears all entries in the given hash table. */
516 /* This function clears a specified SLOT in a hash table. It is
517 useful when you've already done the lookup and don't want to do it
520 void clear_slot (value_type
**);
522 /* This function searches for a hash table entry equal to the given
523 COMPARABLE element starting with the given HASH value. It cannot
524 be used to insert or delete an element. */
525 value_type
*find_with_hash (const compare_type
*, hashval_t
);
527 /* Like find_slot_with_hash, but compute the hash value from the element. */
528 value_type
*find (const value_type
*value
)
530 return find_with_hash (value
, Descriptor::hash (value
));
533 value_type
**find_slot (const value_type
*value
, insert_option insert
)
535 return find_slot_with_hash (value
, Descriptor::hash (value
), insert
);
538 /* This function searches for a hash table slot containing an entry
539 equal to the given COMPARABLE element and starting with the given
540 HASH. To delete an entry, call this with insert=NO_INSERT, then
541 call clear_slot on the slot returned (possibly after doing some
542 checks). To insert an entry, call this with insert=INSERT, then
543 write the value you want into the returned slot. When inserting an
544 entry, NULL may be returned if memory allocation fails. */
545 value_type
**find_slot_with_hash (const compare_type
*comparable
,
546 hashval_t hash
, enum insert_option insert
);
548 /* This function deletes an element with the given COMPARABLE value
549 from hash table starting with the given HASH. If there is no
550 matching element in the hash table, this function does nothing. */
551 void remove_elt_with_hash (const compare_type
*, hashval_t
);
553 /* Like remove_elt_with_hash, but compute the hash value from the element. */
554 void remove_elt (const value_type
*value
)
556 remove_elt_with_hash (value
, Descriptor::hash (value
));
559 /* This function scans over the entire hash table calling CALLBACK for
560 each live entry. If CALLBACK returns false, the iteration stops.
561 ARGUMENT is passed as CALLBACK's second argument. */
562 template <typename Argument
,
563 int (*Callback
) (value_type
**slot
, Argument argument
)>
564 void traverse_noresize (Argument argument
);
566 /* Like traverse_noresize, but does resize the table when it is too empty
567 to improve effectivity of subsequent calls. */
568 template <typename Argument
,
569 int (*Callback
) (value_type
**slot
, Argument argument
)>
570 void traverse (Argument argument
);
575 iterator () : m_slot (NULL
), m_limit (NULL
) {}
577 iterator (value_type
**slot
, value_type
**limit
) :
578 m_slot (slot
), m_limit (limit
) {}
580 inline value_type
*operator * () { return *m_slot
; }
582 inline iterator
&operator ++ ();
583 bool operator != (const iterator
&other
) const
585 return m_slot
!= other
.m_slot
|| m_limit
!= other
.m_limit
;
590 value_type
**m_limit
;
593 iterator
begin () const
595 iterator
iter (m_entries
, m_entries
+ m_size
);
600 iterator
end () const { return iterator (); }
602 double collisions () const
604 return m_searches
? static_cast <double> (m_collisions
) / m_searches
: 0;
609 value_type
**find_empty_slot_for_expand (hashval_t
);
613 typename
Descriptor::value_type
**m_entries
;
617 /* Current number of elements including also deleted elements. */
620 /* Current number of deleted elements in the table. */
623 /* The following member is used for debugging. Its value is number
624 of all calls of `htab_find_slot' for the hash table. */
625 unsigned int m_searches
;
627 /* The following member is used for debugging. Its value is number
628 of collisions fixed for time of work with the hash table. */
629 unsigned int m_collisions
;
631 /* Current size (in entries) of the hash table, as an index into the
633 unsigned int m_size_prime_index
;
636 template<typename Descriptor
, template<typename Type
> class Allocator
>
637 hash_table
<Descriptor
, Allocator
, false>::hash_table (size_t size
) :
638 m_n_elements (0), m_n_deleted (0), m_searches (0), m_collisions (0)
640 unsigned int size_prime_index
;
642 size_prime_index
= hash_table_higher_prime_index (size
);
643 size
= prime_tab
[size_prime_index
].prime
;
645 m_entries
= Allocator
<value_type
*> ::data_alloc (size
);
646 gcc_assert (m_entries
!= NULL
);
648 m_size_prime_index
= size_prime_index
;
651 template<typename Descriptor
, template<typename Type
> class Allocator
>
652 hash_table
<Descriptor
, Allocator
, false>::~hash_table ()
654 for (size_t i
= m_size
- 1; i
< m_size
; i
--)
655 if (m_entries
[i
] != HTAB_EMPTY_ENTRY
&& m_entries
[i
] != HTAB_DELETED_ENTRY
)
656 Descriptor::remove (m_entries
[i
]);
658 Allocator
<value_type
*> ::data_free (m_entries
);
661 /* Similar to find_slot, but without several unwanted side effects:
662 - Does not call equal when it finds an existing entry.
663 - Does not change the count of elements/searches/collisions in the
665 This function also assumes there are no deleted entries in the table.
666 HASH is the hash value for the element to be inserted. */
668 template<typename Descriptor
, template<typename Type
> class Allocator
>
669 typename hash_table
<Descriptor
, Allocator
, false>::value_type
**
670 hash_table
<Descriptor
, Allocator
, false>
671 ::find_empty_slot_for_expand (hashval_t hash
)
673 hashval_t index
= hash_table_mod1 (hash
, m_size_prime_index
);
674 size_t size
= m_size
;
675 value_type
**slot
= m_entries
+ index
;
678 if (*slot
== HTAB_EMPTY_ENTRY
)
680 else if (*slot
== HTAB_DELETED_ENTRY
)
683 hash2
= hash_table_mod2 (hash
, m_size_prime_index
);
690 slot
= m_entries
+ index
;
691 if (*slot
== HTAB_EMPTY_ENTRY
)
693 else if (*slot
== HTAB_DELETED_ENTRY
)
698 /* The following function changes size of memory allocated for the
699 entries and repeatedly inserts the table elements. The occupancy
700 of the table after the call will be about 50%. Naturally the hash
701 table must already exist. Remember also that the place of the
702 table entries is changed. If memory allocation fails, this function
705 template<typename Descriptor
, template<typename Type
> class Allocator
>
707 hash_table
<Descriptor
, Allocator
, false>::expand ()
709 value_type
**oentries
= m_entries
;
710 unsigned int oindex
= m_size_prime_index
;
711 size_t osize
= size ();
712 value_type
**olimit
= oentries
+ osize
;
713 size_t elts
= elements ();
715 /* Resize only when table after removal of unused elements is either
716 too full or too empty. */
719 if (elts
* 2 > osize
|| (elts
* 8 < osize
&& osize
> 32))
721 nindex
= hash_table_higher_prime_index (elts
* 2);
722 nsize
= prime_tab
[nindex
].prime
;
730 value_type
**nentries
= Allocator
<value_type
*> ::data_alloc (nsize
);
731 gcc_assert (nentries
!= NULL
);
732 m_entries
= nentries
;
734 m_size_prime_index
= nindex
;
735 m_n_elements
-= m_n_deleted
;
738 value_type
**p
= oentries
;
743 if (x
!= HTAB_EMPTY_ENTRY
&& x
!= HTAB_DELETED_ENTRY
)
745 value_type
**q
= find_empty_slot_for_expand (Descriptor::hash (x
));
754 Allocator
<value_type
*> ::data_free (oentries
);
757 template<typename Descriptor
, template<typename Type
> class Allocator
>
759 hash_table
<Descriptor
, Allocator
, false>::empty ()
761 size_t size
= m_size
;
762 value_type
**entries
= m_entries
;
765 for (i
= size
- 1; i
>= 0; i
--)
766 if (entries
[i
] != HTAB_EMPTY_ENTRY
&& entries
[i
] != HTAB_DELETED_ENTRY
)
767 Descriptor::remove (entries
[i
]);
769 /* Instead of clearing megabyte, downsize the table. */
770 if (size
> 1024*1024 / sizeof (PTR
))
772 int nindex
= hash_table_higher_prime_index (1024 / sizeof (PTR
));
773 int nsize
= prime_tab
[nindex
].prime
;
775 Allocator
<value_type
*> ::data_free (m_entries
);
776 m_entries
= Allocator
<value_type
*> ::data_alloc (nsize
);
778 m_size_prime_index
= nindex
;
781 memset (entries
, 0, size
* sizeof (value_type
*));
786 /* This function clears a specified SLOT in a hash table. It is
787 useful when you've already done the lookup and don't want to do it
790 template<typename Descriptor
, template<typename Type
> class Allocator
>
792 hash_table
<Descriptor
, Allocator
, false>::clear_slot (value_type
**slot
)
794 if (slot
< m_entries
|| slot
>= m_entries
+ size ()
795 || *slot
== HTAB_EMPTY_ENTRY
|| *slot
== HTAB_DELETED_ENTRY
)
798 Descriptor::remove (*slot
);
800 *slot
= static_cast <value_type
*> (HTAB_DELETED_ENTRY
);
804 /* This function searches for a hash table entry equal to the given
805 COMPARABLE element starting with the given HASH value. It cannot
806 be used to insert or delete an element. */
808 template<typename Descriptor
, template<typename Type
> class Allocator
>
809 typename hash_table
<Descriptor
, Allocator
, false>::value_type
*
810 hash_table
<Descriptor
, Allocator
, false>
811 ::find_with_hash (const compare_type
*comparable
, hashval_t hash
)
814 size_t size
= m_size
;
815 hashval_t index
= hash_table_mod1 (hash
, m_size_prime_index
);
817 value_type
*entry
= m_entries
[index
];
818 if (entry
== HTAB_EMPTY_ENTRY
819 || (entry
!= HTAB_DELETED_ENTRY
&& Descriptor::equal (entry
, comparable
)))
822 hashval_t hash2
= hash_table_mod2 (hash
, m_size_prime_index
);
830 entry
= m_entries
[index
];
831 if (entry
== HTAB_EMPTY_ENTRY
832 || (entry
!= HTAB_DELETED_ENTRY
833 && Descriptor::equal (entry
, comparable
)))
838 /* This function searches for a hash table slot containing an entry
839 equal to the given COMPARABLE element and starting with the given
840 HASH. To delete an entry, call this with insert=NO_INSERT, then
841 call clear_slot on the slot returned (possibly after doing some
842 checks). To insert an entry, call this with insert=INSERT, then
843 write the value you want into the returned slot. When inserting an
844 entry, NULL may be returned if memory allocation fails. */
846 template<typename Descriptor
, template<typename Type
> class Allocator
>
847 typename hash_table
<Descriptor
, Allocator
, false>::value_type
**
848 hash_table
<Descriptor
, Allocator
, false>
849 ::find_slot_with_hash (const compare_type
*comparable
, hashval_t hash
,
850 enum insert_option insert
)
852 if (insert
== INSERT
&& m_size
* 3 <= m_n_elements
* 4)
857 value_type
**first_deleted_slot
= NULL
;
858 hashval_t index
= hash_table_mod1 (hash
, m_size_prime_index
);
859 hashval_t hash2
= hash_table_mod2 (hash
, m_size_prime_index
);
860 value_type
*entry
= m_entries
[index
];
861 size_t size
= m_size
;
862 if (entry
== HTAB_EMPTY_ENTRY
)
864 else if (entry
== HTAB_DELETED_ENTRY
)
865 first_deleted_slot
= &m_entries
[index
];
866 else if (Descriptor::equal (entry
, comparable
))
867 return &m_entries
[index
];
876 entry
= m_entries
[index
];
877 if (entry
== HTAB_EMPTY_ENTRY
)
879 else if (entry
== HTAB_DELETED_ENTRY
)
881 if (!first_deleted_slot
)
882 first_deleted_slot
= &m_entries
[index
];
884 else if (Descriptor::equal (entry
, comparable
))
885 return &m_entries
[index
];
889 if (insert
== NO_INSERT
)
892 if (first_deleted_slot
)
895 *first_deleted_slot
= static_cast <value_type
*> (HTAB_EMPTY_ENTRY
);
896 return first_deleted_slot
;
900 return &m_entries
[index
];
903 /* This function deletes an element with the given COMPARABLE value
904 from hash table starting with the given HASH. If there is no
905 matching element in the hash table, this function does nothing. */
907 template<typename Descriptor
, template<typename Type
> class Allocator
>
909 hash_table
<Descriptor
, Allocator
, false>
910 ::remove_elt_with_hash (const compare_type
*comparable
, hashval_t hash
)
912 value_type
**slot
= find_slot_with_hash (comparable
, hash
, NO_INSERT
);
913 if (*slot
== HTAB_EMPTY_ENTRY
)
916 Descriptor::remove (*slot
);
918 *slot
= static_cast <value_type
*> (HTAB_DELETED_ENTRY
);
922 /* This function scans over the entire hash table calling CALLBACK for
923 each live entry. If CALLBACK returns false, the iteration stops.
924 ARGUMENT is passed as CALLBACK's second argument. */
926 template<typename Descriptor
, template<typename Type
> class Allocator
>
927 template<typename Argument
,
928 int (*Callback
) (typename hash_table
<Descriptor
, Allocator
,
929 false>::value_type
**slot
,
932 hash_table
<Descriptor
, Allocator
, false>::traverse_noresize (Argument argument
)
934 value_type
**slot
= m_entries
;
935 value_type
**limit
= slot
+ size ();
939 value_type
*x
= *slot
;
941 if (x
!= HTAB_EMPTY_ENTRY
&& x
!= HTAB_DELETED_ENTRY
)
942 if (! Callback (slot
, argument
))
945 while (++slot
< limit
);
948 /* Like traverse_noresize, but does resize the table when it is too empty
949 to improve effectivity of subsequent calls. */
951 template <typename Descriptor
,
952 template <typename Type
> class Allocator
>
953 template <typename Argument
,
954 int (*Callback
) (typename hash_table
<Descriptor
, Allocator
,
955 false>::value_type
**slot
,
958 hash_table
<Descriptor
, Allocator
, false>::traverse (Argument argument
)
960 size_t size
= m_size
;
961 if (elements () * 8 < size
&& size
> 32)
964 traverse_noresize
<Argument
, Callback
> (argument
);
967 /* Slide down the iterator slots until an active entry is found. */
969 template<typename Descriptor
, template<typename Type
> class Allocator
>
971 hash_table
<Descriptor
, Allocator
, false>::iterator::slide ()
973 for ( ; m_slot
< m_limit
; ++m_slot
)
975 value_type
*x
= *m_slot
;
976 if (x
!= HTAB_EMPTY_ENTRY
&& x
!= HTAB_DELETED_ENTRY
)
983 /* Bump the iterator. */
985 template<typename Descriptor
, template<typename Type
> class Allocator
>
986 inline typename hash_table
<Descriptor
, Allocator
, false>::iterator
&
987 hash_table
<Descriptor
, Allocator
, false>::iterator::operator ++ ()
994 /* A partial specialization used when values should be stored directly. */
996 template <typename Descriptor
,
997 template<typename Type
> class Allocator
>
998 class hash_table
<Descriptor
, Allocator
, true>
1000 typedef typename
Descriptor::value_type value_type
;
1001 typedef typename
Descriptor::compare_type compare_type
;
1004 explicit hash_table (size_t, bool ggc
= false);
1007 /* Current size (in entries) of the hash table. */
1008 size_t size () const { return m_size
; }
1010 /* Return the current number of elements in this hash table. */
1011 size_t elements () const { return m_n_elements
- m_n_deleted
; }
1013 /* Return the current number of elements in this hash table. */
1014 size_t elements_with_deleted () const { return m_n_elements
; }
1016 /* This function clears all entries in the given hash table. */
1019 /* This function clears a specified SLOT in a hash table. It is
1020 useful when you've already done the lookup and don't want to do it
1023 void clear_slot (value_type
*);
1025 /* This function searches for a hash table entry equal to the given
1026 COMPARABLE element starting with the given HASH value. It cannot
1027 be used to insert or delete an element. */
1028 value_type
&find_with_hash (const compare_type
&, hashval_t
);
1030 /* Like find_slot_with_hash, but compute the hash value from the element. */
1031 value_type
&find (const value_type
&value
)
1033 return find_with_hash (value
, Descriptor::hash (value
));
1036 value_type
*find_slot (const value_type
&value
, insert_option insert
)
1038 return find_slot_with_hash (value
, Descriptor::hash (value
), insert
);
1041 /* This function searches for a hash table slot containing an entry
1042 equal to the given COMPARABLE element and starting with the given
1043 HASH. To delete an entry, call this with insert=NO_INSERT, then
1044 call clear_slot on the slot returned (possibly after doing some
1045 checks). To insert an entry, call this with insert=INSERT, then
1046 write the value you want into the returned slot. When inserting an
1047 entry, NULL may be returned if memory allocation fails. */
1048 value_type
*find_slot_with_hash (const compare_type
&comparable
,
1049 hashval_t hash
, enum insert_option insert
);
1051 /* This function deletes an element with the given COMPARABLE value
1052 from hash table starting with the given HASH. If there is no
1053 matching element in the hash table, this function does nothing. */
1054 void remove_elt_with_hash (const compare_type
&, hashval_t
);
1056 /* Like remove_elt_with_hash, but compute the hash value from the element. */
1057 void remove_elt (const value_type
&value
)
1059 remove_elt_with_hash (value
, Descriptor::hash (value
));
1062 /* This function scans over the entire hash table calling CALLBACK for
1063 each live entry. If CALLBACK returns false, the iteration stops.
1064 ARGUMENT is passed as CALLBACK's second argument. */
1065 template <typename Argument
,
1066 int (*Callback
) (value_type
*slot
, Argument argument
)>
1067 void traverse_noresize (Argument argument
);
1069 /* Like traverse_noresize, but does resize the table when it is too empty
1070 to improve effectivity of subsequent calls. */
1071 template <typename Argument
,
1072 int (*Callback
) (value_type
*slot
, Argument argument
)>
1073 void traverse (Argument argument
);
1078 iterator () : m_slot (NULL
), m_limit (NULL
) {}
1080 iterator (value_type
*slot
, value_type
*limit
) :
1081 m_slot (slot
), m_limit (limit
) {}
1083 inline value_type
&operator * () { return *m_slot
; }
1085 inline iterator
&operator ++ ();
1086 bool operator != (const iterator
&other
) const
1088 return m_slot
!= other
.m_slot
|| m_limit
!= other
.m_limit
;
1093 value_type
*m_limit
;
1096 iterator
begin () const
1098 iterator
iter (m_entries
, m_entries
+ m_size
);
1103 iterator
end () const { return iterator (); }
1105 double collisions () const
1107 return m_searches
? static_cast <double> (m_collisions
) / m_searches
: 0;
1111 template<typename T
> friend void gt_ggc_mx (hash_table
<T
> *);
1112 template<typename T
> friend void gt_pch_nx (hash_table
<T
> *);
1113 template<typename T
> friend void hashtab_entry_note_pointers (void *, void *, gt_pointer_operator
, void *);
1114 template<typename T
, typename U
, typename V
> friend void gt_pch_nx (hash_map
<T
, U
, V
> *, gt_pointer_operator
, void *);
1115 template<typename T
, typename U
> friend void gt_pch_nx (hash_set
<T
, U
> *, gt_pointer_operator
, void *);
1117 value_type
*find_empty_slot_for_expand (hashval_t
);
1119 static bool is_deleted (value_type
&v
)
1121 return is_deleted_helper
<value_type
, Descriptor
>::call (v
);
1123 static bool is_empty (value_type
&v
)
1125 return is_empty_helper
<value_type
, Descriptor
>::call (v
);
1128 static void mark_deleted (value_type
&v
)
1130 return mark_deleted_helper
<value_type
, Descriptor
>::call (v
);
1133 static void mark_empty (value_type
&v
)
1135 return mark_empty_helper
<value_type
, Descriptor
>::call (v
);
1139 typename
Descriptor::value_type
*m_entries
;
1143 /* Current number of elements including also deleted elements. */
1144 size_t m_n_elements
;
1146 /* Current number of deleted elements in the table. */
1149 /* The following member is used for debugging. Its value is number
1150 of all calls of `htab_find_slot' for the hash table. */
1151 unsigned int m_searches
;
1153 /* The following member is used for debugging. Its value is number
1154 of collisions fixed for time of work with the hash table. */
1155 unsigned int m_collisions
;
1157 /* Current size (in entries) of the hash table, as an index into the
1159 unsigned int m_size_prime_index
;
1161 /* if m_entries is stored in ggc memory. */
1165 template<typename Descriptor
, template<typename Type
> class Allocator
>
1166 hash_table
<Descriptor
, Allocator
, true>::hash_table (size_t size
, bool ggc
) :
1167 m_n_elements (0), m_n_deleted (0), m_searches (0), m_collisions (0),
1170 unsigned int size_prime_index
;
1172 size_prime_index
= hash_table_higher_prime_index (size
);
1173 size
= prime_tab
[size_prime_index
].prime
;
1176 m_entries
= Allocator
<value_type
> ::data_alloc (size
);
1178 m_entries
= ggc_cleared_vec_alloc
<value_type
> (size
);
1180 gcc_assert (m_entries
!= NULL
);
1182 m_size_prime_index
= size_prime_index
;
1185 template<typename Descriptor
, template<typename Type
> class Allocator
>
1186 hash_table
<Descriptor
, Allocator
, true>::~hash_table ()
1188 for (size_t i
= m_size
- 1; i
< m_size
; i
--)
1189 if (!is_empty (m_entries
[i
]) && !is_deleted (m_entries
[i
]))
1190 Descriptor::remove (m_entries
[i
]);
1193 Allocator
<value_type
> ::data_free (m_entries
);
1195 ggc_free (m_entries
);
1198 /* Similar to find_slot, but without several unwanted side effects:
1199 - Does not call equal when it finds an existing entry.
1200 - Does not change the count of elements/searches/collisions in the
1202 This function also assumes there are no deleted entries in the table.
1203 HASH is the hash value for the element to be inserted. */
1205 template<typename Descriptor
, template<typename Type
> class Allocator
>
1206 typename hash_table
<Descriptor
, Allocator
, true>::value_type
*
1207 hash_table
<Descriptor
, Allocator
, true>
1208 ::find_empty_slot_for_expand (hashval_t hash
)
1210 hashval_t index
= hash_table_mod1 (hash
, m_size_prime_index
);
1211 size_t size
= m_size
;
1212 value_type
*slot
= m_entries
+ index
;
1215 if (is_empty (*slot
))
1217 else if (is_deleted (*slot
))
1220 hash2
= hash_table_mod2 (hash
, m_size_prime_index
);
1227 slot
= m_entries
+ index
;
1228 if (is_empty (*slot
))
1230 else if (is_deleted (*slot
))
1235 /* The following function changes size of memory allocated for the
1236 entries and repeatedly inserts the table elements. The occupancy
1237 of the table after the call will be about 50%. Naturally the hash
1238 table must already exist. Remember also that the place of the
1239 table entries is changed. If memory allocation fails, this function
1242 template<typename Descriptor
, template<typename Type
> class Allocator
>
1244 hash_table
<Descriptor
, Allocator
, true>::expand ()
1246 value_type
*oentries
= m_entries
;
1247 unsigned int oindex
= m_size_prime_index
;
1248 size_t osize
= size ();
1249 value_type
*olimit
= oentries
+ osize
;
1250 size_t elts
= elements ();
1252 /* Resize only when table after removal of unused elements is either
1253 too full or too empty. */
1254 unsigned int nindex
;
1256 if (elts
* 2 > osize
|| (elts
* 8 < osize
&& osize
> 32))
1258 nindex
= hash_table_higher_prime_index (elts
* 2);
1259 nsize
= prime_tab
[nindex
].prime
;
1267 value_type
*nentries
;
1269 nentries
= Allocator
<value_type
> ::data_alloc (nsize
);
1271 nentries
= ggc_cleared_vec_alloc
<value_type
> (nsize
);
1273 gcc_assert (nentries
!= NULL
);
1274 m_entries
= nentries
;
1276 m_size_prime_index
= nindex
;
1277 m_n_elements
-= m_n_deleted
;
1280 value_type
*p
= oentries
;
1285 if (!is_empty (x
) && !is_deleted (x
))
1287 value_type
*q
= find_empty_slot_for_expand (Descriptor::hash (x
));
1297 Allocator
<value_type
> ::data_free (oentries
);
1299 ggc_free (oentries
);
1302 template<typename Descriptor
, template<typename Type
> class Allocator
>
1304 hash_table
<Descriptor
, Allocator
, true>::empty ()
1306 size_t size
= m_size
;
1307 value_type
*entries
= m_entries
;
1310 for (i
= size
- 1; i
>= 0; i
--)
1311 if (!is_empty (entries
[i
]) && !is_deleted (entries
[i
]))
1312 Descriptor::remove (entries
[i
]);
1314 /* Instead of clearing megabyte, downsize the table. */
1315 if (size
> 1024*1024 / sizeof (PTR
))
1317 int nindex
= hash_table_higher_prime_index (1024 / sizeof (PTR
));
1318 int nsize
= prime_tab
[nindex
].prime
;
1322 Allocator
<value_type
> ::data_free (m_entries
);
1323 m_entries
= Allocator
<value_type
> ::data_alloc (nsize
);
1327 ggc_free (m_entries
);
1328 m_entries
= ggc_cleared_vec_alloc
<value_type
> (nsize
);
1332 m_size_prime_index
= nindex
;
1335 memset (entries
, 0, size
* sizeof (value_type
));
1340 /* This function clears a specified SLOT in a hash table. It is
1341 useful when you've already done the lookup and don't want to do it
1344 template<typename Descriptor
, template<typename Type
> class Allocator
>
1346 hash_table
<Descriptor
, Allocator
, true>::clear_slot (value_type
*slot
)
1348 if (slot
< m_entries
|| slot
>= m_entries
+ size ()
1349 || is_empty (*slot
) || is_deleted (*slot
))
1352 Descriptor::remove (*slot
);
1354 mark_deleted (*slot
);
1358 /* This function searches for a hash table entry equal to the given
1359 COMPARABLE element starting with the given HASH value. It cannot
1360 be used to insert or delete an element. */
1362 template<typename Descriptor
, template<typename Type
> class Allocator
>
1363 typename hash_table
<Descriptor
, Allocator
, true>::value_type
&
1364 hash_table
<Descriptor
, Allocator
, true>
1365 ::find_with_hash (const compare_type
&comparable
, hashval_t hash
)
1368 size_t size
= m_size
;
1369 hashval_t index
= hash_table_mod1 (hash
, m_size_prime_index
);
1371 value_type
*entry
= &m_entries
[index
];
1372 if (is_empty (*entry
)
1373 || (!is_deleted (*entry
) && Descriptor::equal (*entry
, comparable
)))
1376 hashval_t hash2
= hash_table_mod2 (hash
, m_size_prime_index
);
1384 entry
= &m_entries
[index
];
1385 if (is_empty (*entry
)
1386 || (!is_deleted (*entry
) && Descriptor::equal (*entry
, comparable
)))
1391 /* This function searches for a hash table slot containing an entry
1392 equal to the given COMPARABLE element and starting with the given
1393 HASH. To delete an entry, call this with insert=NO_INSERT, then
1394 call clear_slot on the slot returned (possibly after doing some
1395 checks). To insert an entry, call this with insert=INSERT, then
1396 write the value you want into the returned slot. When inserting an
1397 entry, NULL may be returned if memory allocation fails. */
1399 template<typename Descriptor
, template<typename Type
> class Allocator
>
1400 typename hash_table
<Descriptor
, Allocator
, true>::value_type
*
1401 hash_table
<Descriptor
, Allocator
, true>
1402 ::find_slot_with_hash (const compare_type
&comparable
, hashval_t hash
,
1403 enum insert_option insert
)
1405 if (insert
== INSERT
&& m_size
* 3 <= m_n_elements
* 4)
1410 value_type
*first_deleted_slot
= NULL
;
1411 hashval_t index
= hash_table_mod1 (hash
, m_size_prime_index
);
1412 hashval_t hash2
= hash_table_mod2 (hash
, m_size_prime_index
);
1413 value_type
*entry
= &m_entries
[index
];
1414 size_t size
= m_size
;
1415 if (is_empty (*entry
))
1417 else if (is_deleted (*entry
))
1418 first_deleted_slot
= &m_entries
[index
];
1419 else if (Descriptor::equal (*entry
, comparable
))
1420 return &m_entries
[index
];
1429 entry
= &m_entries
[index
];
1430 if (is_empty (*entry
))
1432 else if (is_deleted (*entry
))
1434 if (!first_deleted_slot
)
1435 first_deleted_slot
= &m_entries
[index
];
1437 else if (Descriptor::equal (*entry
, comparable
))
1438 return &m_entries
[index
];
1442 if (insert
== NO_INSERT
)
1445 if (first_deleted_slot
)
1448 mark_empty (*first_deleted_slot
);
1449 return first_deleted_slot
;
1453 return &m_entries
[index
];
1456 /* This function deletes an element with the given COMPARABLE value
1457 from hash table starting with the given HASH. If there is no
1458 matching element in the hash table, this function does nothing. */
1460 template<typename Descriptor
, template<typename Type
> class Allocator
>
1462 hash_table
<Descriptor
, Allocator
, true>
1463 ::remove_elt_with_hash (const compare_type
&comparable
, hashval_t hash
)
1465 value_type
*slot
= find_slot_with_hash (comparable
, hash
, NO_INSERT
);
1466 if (is_empty (*slot
))
1469 Descriptor::remove (*slot
);
1471 mark_deleted (*slot
);
1475 /* This function scans over the entire hash table calling CALLBACK for
1476 each live entry. If CALLBACK returns false, the iteration stops.
1477 ARGUMENT is passed as CALLBACK's second argument. */
1479 template<typename Descriptor
,
1480 template<typename Type
> class Allocator
>
1481 template<typename Argument
,
1482 int (*Callback
) (typename hash_table
<Descriptor
, Allocator
,
1483 true>::value_type
*slot
,
1486 hash_table
<Descriptor
, Allocator
, true>::traverse_noresize (Argument argument
)
1488 value_type
*slot
= m_entries
;
1489 value_type
*limit
= slot
+ size ();
1493 value_type
&x
= *slot
;
1495 if (!is_empty (x
) && !is_deleted (x
))
1496 if (! Callback (slot
, argument
))
1499 while (++slot
< limit
);
1502 /* Like traverse_noresize, but does resize the table when it is too empty
1503 to improve effectivity of subsequent calls. */
1505 template <typename Descriptor
,
1506 template <typename Type
> class Allocator
>
1507 template <typename Argument
,
1508 int (*Callback
) (typename hash_table
<Descriptor
, Allocator
,
1509 true>::value_type
*slot
,
1512 hash_table
<Descriptor
, Allocator
, true>::traverse (Argument argument
)
1514 size_t size
= m_size
;
1515 if (elements () * 8 < size
&& size
> 32)
1518 traverse_noresize
<Argument
, Callback
> (argument
);
1521 /* Slide down the iterator slots until an active entry is found. */
1523 template<typename Descriptor
, template<typename Type
> class Allocator
>
1525 hash_table
<Descriptor
, Allocator
, true>::iterator::slide ()
1527 for ( ; m_slot
< m_limit
; ++m_slot
)
1529 value_type
&x
= *m_slot
;
1530 if (!is_empty (x
) && !is_deleted (x
))
1537 /* Bump the iterator. */
1539 template<typename Descriptor
, template<typename Type
> class Allocator
>
1540 inline typename hash_table
<Descriptor
, Allocator
, true>::iterator
&
1541 hash_table
<Descriptor
, Allocator
, true>::iterator::operator ++ ()
1549 /* Iterate through the elements of hash_table HTAB,
1550 using hash_table <....>::iterator ITER,
1551 storing each element in RESULT, which is of type TYPE. */
1553 #define FOR_EACH_HASH_TABLE_ELEMENT(HTAB, RESULT, TYPE, ITER) \
1554 for ((ITER) = (HTAB).begin (); \
1555 (ITER) != (HTAB).end () ? (RESULT = *(ITER) , true) : false; \
1558 /* ggc walking routines. */
1560 template<typename E
>
1562 gt_ggc_mx (hash_table
<E
> *h
)
1564 typedef hash_table
<E
> table
;
1566 if (!ggc_test_and_set_mark (h
->m_entries
))
1569 for (size_t i
= 0; i
< h
->m_size
; i
++)
1571 if (table::is_empty (h
->m_entries
[i
])
1572 || table::is_deleted (h
->m_entries
[i
]))
1575 E::ggc_mx (h
->m_entries
[i
]);
1579 template<typename D
>
1581 hashtab_entry_note_pointers (void *obj
, void *h
, gt_pointer_operator op
,
1584 hash_table
<D
> *map
= static_cast<hash_table
<D
> *> (h
);
1585 gcc_checking_assert (map
->m_entries
== obj
);
1586 for (size_t i
= 0; i
< map
->m_size
; i
++)
1588 typedef hash_table
<D
> table
;
1589 if (table::is_empty (map
->m_entries
[i
])
1590 || table::is_deleted (map
->m_entries
[i
]))
1593 D::pch_nx (map
->m_entries
[i
], op
, cookie
);
1597 template<typename D
>
1599 gt_pch_nx (hash_table
<D
> *h
)
1601 bool success ATTRIBUTE_UNUSED
1602 = gt_pch_note_object (h
->m_entries
, h
, hashtab_entry_note_pointers
<D
>);
1603 gcc_checking_assert (success
);
1604 for (size_t i
= 0; i
< h
->m_size
; i
++)
1606 if (hash_table
<D
>::is_empty (h
->m_entries
[i
])
1607 || hash_table
<D
>::is_deleted (h
->m_entries
[i
]))
1610 D::pch_nx (h
->m_entries
[i
]);
1614 #endif /* TYPED_HASHTAB_H */