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