202 #ifndef TYPED_HASHTAB_H
203 #define TYPED_HASHTAB_H
211 template <
typename Type>
223 template <
typename Type>
227 return static_cast <Type *> (xcalloc (
count,
sizeof (Type)));
233 template <
typename Type>
237 return static_cast <Type *> (xcalloc (
count,
sizeof (Type)));
243 template <
typename Type>
253 template <
typename Type>
263 template <
typename Type>
266 static inline void remove (Type *p);
272 template <
typename Type>
282 template <
typename Type>
285 static inline void remove (Type *p);
291 template <
typename Type>
300 template <
typename Type>
306 static inline hashval_t
313 template <
typename Type>
319 return (hashval_t) ((intptr_t)
candidate >> 3);
322 template <
typename Type>
353 template <
typename T>
404 template <
typename Descriptor,
405 template <
typename Type>
class Allocator =
xcallocator>
409 typedef typename Descriptor::value_type
value_type;
441 hashval_t hash,
enum insert_option
insert);
451 template <
typename Argument,
455 template <
typename Argument,
466 template <
typename Descriptor,
467 template <
typename Type>
class Allocator>
477 template <
typename Descriptor,
478 template <
typename Type>
class Allocator>
488 template <
typename Descriptor,
489 template <
typename Type>
class Allocator>
490 inline typename Descriptor::value_type *
493 return find_with_hash (value, Descriptor::hash (value));
499 template <
typename Descriptor,
500 template <
typename Type>
class Allocator>
501 inline typename Descriptor::value_type **
505 return find_slot_with_hash (value, Descriptor::hash (value), insert);
511 template <
typename Descriptor,
512 template <
typename Type>
class Allocator>
516 remove_elt_with_hash (value, Descriptor::hash (value));
522 template <
typename Descriptor,
523 template <
typename Type>
class Allocator>
533 template <
typename Descriptor,
534 template <
typename Type>
class Allocator>
538 return htab->n_elements - htab->n_deleted;
544 template <
typename Descriptor,
545 template <
typename Type>
class Allocator>
549 return htab->n_elements;
556 template <
typename Descriptor,
557 template <
typename Type>
class Allocator>
561 if (htab->searches == 0)
564 return static_cast <
double> (htab->collisions) / htab->searches;
570 template <
typename Descriptor,
571 template <
typename Type>
class Allocator>
575 unsigned int size_prime_index;
580 htab = Allocator <hash_table_control <value_type> > ::control_alloc (1);
581 gcc_assert (htab != NULL);
582 htab->entries = Allocator <value_type*> ::data_alloc (size);
583 gcc_assert (htab->entries != NULL);
585 htab->size_prime_index = size_prime_index;
592 template <
typename Descriptor,
593 template <
typename Type>
class Allocator>
597 size_t size = htab->
size;
600 for (
int i = size - 1; i >= 0; i--)
601 if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY)
602 Descriptor::remove (entries[i]);
604 Allocator <value_type *> ::data_free (entries);
605 Allocator <hash_table_control <value_type> > ::control_free (htab);
617 template <
typename Descriptor,
618 template <
typename Type>
class Allocator>
619 typename Descriptor::value_type **
623 size_t size = htab->size;
627 if (*slot == HTAB_EMPTY_ENTRY)
629 else if (*slot == HTAB_DELETED_ENTRY)
639 slot = htab->entries + index;
640 if (*slot == HTAB_EMPTY_ENTRY)
642 else if (*slot == HTAB_DELETED_ENTRY)
655 template <
typename Descriptor,
656 template <
typename Type>
class Allocator>
664 size_t nsize, osize, elts;
665 unsigned int oindex, nindex;
667 oentries = htab->entries;
668 oindex = htab->size_prime_index;
670 olimit = oentries + osize;
675 if (elts * 2 > osize || (elts * 8 < osize && osize > 32))
686 nentries = Allocator <value_type *> ::data_alloc (nsize);
687 gcc_assert (nentries != NULL);
688 htab->entries = nentries;
690 htab->size_prime_index = nindex;
691 htab->n_elements -= htab->n_deleted;
699 if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
701 value_type **q = find_empty_slot_for_expand (Descriptor::hash (x));
710 Allocator <value_type *> ::data_free (oentries);
718 template <
typename Descriptor,
719 template <
typename Type>
class Allocator>
720 typename Descriptor::value_type *
722 ::find_with_hash (
const compare_type *comparable, hashval_t hash)
724 hashval_t index, hash2;
732 entry = htab->entries[index];
733 if (entry == HTAB_EMPTY_ENTRY
734 || (entry != HTAB_DELETED_ENTRY && Descriptor::equal (entry, comparable)))
745 entry = htab->entries[index];
746 if (entry == HTAB_EMPTY_ENTRY
747 || (entry != HTAB_DELETED_ENTRY
748 && Descriptor::equal (entry, comparable)))
762 template <
typename Descriptor,
763 template <
typename Type>
class Allocator>
764 typename Descriptor::value_type **
766 ::find_slot_with_hash (
const compare_type *comparable, hashval_t hash,
767 enum insert_option
insert)
770 hashval_t index, hash2;
775 if (insert == INSERT && size * 3 <= htab->n_elements * 4)
784 first_deleted_slot = NULL;
786 entry = htab->entries[index];
787 if (entry == HTAB_EMPTY_ENTRY)
789 else if (entry == HTAB_DELETED_ENTRY)
790 first_deleted_slot = &htab->entries[index];
791 else if (Descriptor::equal (entry, comparable))
792 return &htab->entries[index];
802 entry = htab->entries[index];
803 if (entry == HTAB_EMPTY_ENTRY)
805 else if (entry == HTAB_DELETED_ENTRY)
807 if (!first_deleted_slot)
808 first_deleted_slot = &htab->entries[index];
810 else if (Descriptor::equal (entry, comparable))
811 return &htab->entries[index];
815 if (insert == NO_INSERT)
818 if (first_deleted_slot)
821 *first_deleted_slot = static_cast <value_type *> (HTAB_EMPTY_ENTRY);
822 return first_deleted_slot;
826 return &htab->entries[index];
832 template <
typename Descriptor,
833 template <
typename Type>
class Allocator>
837 size_t size = htab->
size;
838 value_type **entries = htab->entries;
841 for (i = size - 1; i >= 0; i--)
842 if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY)
843 Descriptor::remove (entries[i]);
846 if (size > 1024*1024 /
sizeof (PTR))
851 Allocator <value_type *> ::data_free (htab->entries);
852 htab->entries = Allocator <value_type *> ::data_alloc (nsize);
854 htab->size_prime_index = nindex;
857 memset (entries, 0, size *
sizeof (value_type *));
859 htab->n_elements = 0;
867 template <
typename Descriptor,
868 template <
typename Type>
class Allocator>
872 if (
slot < htab->entries || slot >= htab->entries + htab->size
873 || *slot == HTAB_EMPTY_ENTRY || *slot == HTAB_DELETED_ENTRY)
876 Descriptor::remove (*slot);
878 *slot = static_cast <
value_type *> (HTAB_DELETED_ENTRY);
887 template <
typename Descriptor,
888 template <
typename Type>
class Allocator>
891 ::remove_elt_with_hash (
const compare_type *comparable, hashval_t hash)
895 slot = find_slot_with_hash (comparable, hash, NO_INSERT);
896 if (*slot == HTAB_EMPTY_ENTRY)
899 Descriptor::remove (*slot);
901 *slot = static_cast <value_type *> (HTAB_DELETED_ENTRY);
910 template <
typename Descriptor,
911 template <
typename Type>
class Allocator>
912 template <
typename Argument,
913 int (*Callback) (
typename Descriptor::value_type **slot, Argument argument)>
920 slot = htab->entries;
921 limit = slot + htab->size;
927 if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
928 if (! Callback (slot, argument))
931 while (++slot < limit);
938 template <
typename Descriptor,
939 template <
typename Type>
class Allocator>
940 template <
typename Argument,
941 int (*Callback) (
typename Descriptor::value_type **slot,
946 size_t size = htab->
size;
947 if (elements () * 8 < size && size > 32)
950 traverse_noresize <Argument, Callback> (argument);
958 template <
typename Descriptor,
959 template <
typename Type>
class Allocator>
962 : m_slot (NULL), m_limit (NULL)
968 template <
typename Descriptor,
969 template <
typename Type>
class Allocator>
972 (value_type **slot, value_type **
limit)
973 : m_slot (slot), m_limit (
limit)
979 template <
typename Descriptor,
980 template <
typename Type>
class Allocator>
989 template <
typename Descriptor,
990 template <
typename Type>
class Allocator>
994 for ( ; m_slot < m_limit; ++m_slot )
997 if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
1006 template <
typename Descriptor,
1007 template <
typename Type>
class Allocator>
1018 template <
typename Descriptor,
1019 template <
typename Type>
class Allocator>
1024 return m_slot != other.
m_slot || m_limit != other.m_limit;
1031 template <
typename Descriptor,
1032 template <
typename Type>
class Allocator>
1036 iterator hti (htab->entries, htab->entries + htab->size);
1043 template <
typename Descriptor,
1044 template <
typename Type>
class Allocator>
1058 #define FOR_EACH_HASH_TABLE_ELEMENT(HTAB, RESULT, TYPE, ITER) \
1059 for ((ITER) = (HTAB).begin (); \
1060 (ITER) != (HTAB).end () ? (RESULT = &*(ITER) , true) : false; \