X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fadt%2Fhashset.c;h=811078742941fe61ec4c63d84fc548a98946437e;hb=ce6161a7e42a48f7422b7babcc64d8ace18e2687;hp=4631f5ffd0d0db6af7fab00dd25b9553732ff299;hpb=e45ad3cd5813d5ac0cc741c6ddadabc9ca783866;p=libfirm diff --git a/ir/adt/hashset.c b/ir/adt/hashset.c index 4631f5ffd..811078742 100644 --- a/ir/adt/hashset.c +++ b/ir/adt/hashset.c @@ -47,7 +47,7 @@ *
  • GetKey(value) Extracts the key from a data value
  • *
  • KeysEqual(hashset,key1,key2) Tests wether 2 keys are equal
  • *
  • DO_REHASH Instead of storing the hash-values, recalculate - * them on demand from the datavalues. (usefull if + * them on demand from the datavalues. (useful if * calculating the hash-values takes less time than * a memory access)
  • * @@ -84,7 +84,7 @@ #ifdef DO_REHASH #define HashSetEntry ValueType -#define EntrySetHash(entry,new_hash) +#define EntrySetHash(entry,new_hash) (void)0 #define EntryGetHash(self,entry) Hash(self, GetKey(entry)) #define EntryGetValue(entry) (entry) #else /* ! DO_REHASH */ @@ -95,7 +95,7 @@ #ifndef Alloc #include "xmalloc.h" -#define Alloc(size) (HashSetEntry*) xmalloc((size) * sizeof(HashSetEntry)) +#define Alloc(size) XMALLOCN(HashSetEntry, (size)) #define Free(ptr) free(ptr) #endif /* Alloc */ @@ -143,7 +143,7 @@ size_t _i; \ size_t _size = (size); \ HashSetEntry *entries = (ptr); \ - for(_i = 0; _i < _size; ++_i) { \ + for (_i = 0; _i < _size; ++_i) { \ HashSetEntry *entry = & entries[_i]; \ EntrySetEmpty(*entry); \ } \ @@ -192,6 +192,8 @@ #ifndef hashset_size #error You have to redefine hashset_size #endif + +#ifndef NO_ITERATOR #ifndef hashset_iterator_init #error You have to redefine hashset_iterator_init #endif @@ -201,6 +203,7 @@ #ifndef hashset_remove_iterator #error You have to redefine hashset_remove_iterator #endif +#endif /** * Returns the number of elements in the hashset @@ -216,8 +219,7 @@ size_t hashset_size(const HashSet *self) * @note also see comments for hashset_insert() * @internal */ -static INLINE -InsertReturnValue insert_nogrow(HashSet *self, KeyType key) +static inline InsertReturnValue insert_nogrow(HashSet *self, KeyType key) { size_t num_probes = 0; size_t num_buckets = self->num_buckets; @@ -228,14 +230,14 @@ InsertReturnValue insert_nogrow(HashSet *self, KeyType key) assert((num_buckets & (num_buckets - 1)) == 0); - while(1) { + for (;;) { HashSetEntry *entry = & self->entries[bucknum]; - if(EntryIsEmpty(*entry)) { + if (EntryIsEmpty(*entry)) { size_t p; HashSetEntry *nentry; - if(insert_pos != ILLEGAL_POS) { + if (insert_pos != ILLEGAL_POS) { p = insert_pos; } else { p = bucknum; @@ -247,11 +249,11 @@ InsertReturnValue insert_nogrow(HashSet *self, KeyType key) self->num_elements++; return GetInsertReturnValue(*nentry, 0); } - if(EntryIsDeleted(*entry)) { - if(insert_pos == ILLEGAL_POS) + if (EntryIsDeleted(*entry)) { + if (insert_pos == ILLEGAL_POS) insert_pos = bucknum; - } else if(EntryGetHash(self, *entry) == hash) { - if(KeysEqual(self, GetKey(EntryGetValue(*entry)), key)) { + } else if (EntryGetHash(self, *entry) == hash) { + if (KeysEqual(self, GetKey(EntryGetValue(*entry)), key)) { // Value already in the set, return it return GetInsertReturnValue(*entry, 1); } @@ -263,13 +265,24 @@ InsertReturnValue insert_nogrow(HashSet *self, KeyType key) } } +/** + * calculate shrink and enlarge limits + * @internal + */ +static inline void reset_thresholds(HashSet *self) +{ + self->enlarge_threshold = (size_t) HT_OCCUPANCY_FLT(self->num_buckets); + self->shrink_threshold = (size_t) HT_EMPTY_FLT(self->num_buckets); + self->consider_shrink = 0; +} + +#ifndef HAVE_OWN_RESIZE /** * Inserts an element into a hashset under the assumption that the hashset * contains no deleted entries and the element doesn't exist in the hashset yet. * @internal */ -static -void insert_new(HashSet *self, unsigned hash, ValueType value) +static void insert_new(HashSet *self, unsigned hash, ValueType value) { size_t num_probes = 0; size_t num_buckets = self->num_buckets; @@ -279,14 +292,14 @@ void insert_new(HashSet *self, unsigned hash, ValueType value) //assert(value != NullValue); - while(1) { + for (;;) { HashSetEntry *entry = & self->entries[bucknum]; - if(EntryIsEmpty(*entry)) { + if (EntryIsEmpty(*entry)) { size_t p; HashSetEntry *nentry; - if(insert_pos != ILLEGAL_POS) { + if (insert_pos != ILLEGAL_POS) { p = insert_pos; } else { p = bucknum; @@ -306,24 +319,11 @@ void insert_new(HashSet *self, unsigned hash, ValueType value) } } -/** - * calculate shrink and enlarge limits - * @internal - */ -static INLINE -void reset_thresholds(HashSet *self) -{ - self->enlarge_threshold = (size_t) HT_OCCUPANCY_FLT(self->num_buckets); - self->shrink_threshold = (size_t) HT_EMPTY_FLT(self->num_buckets); - self->consider_shrink = 0; -} - /** * Resize the hashset * @internal */ -static INLINE -void resize(HashSet *self, size_t new_size) +static inline void resize(HashSet *self, size_t new_size) { size_t num_buckets = self->num_buckets; size_t i; @@ -345,9 +345,9 @@ void resize(HashSet *self, size_t new_size) reset_thresholds(self); /* reinsert all elements */ - for(i = 0; i < num_buckets; ++i) { + for (i = 0; i < num_buckets; ++i) { HashSetEntry *entry = & old_entries[i]; - if(EntryIsEmpty(*entry) || EntryIsDeleted(*entry)) + if (EntryIsEmpty(*entry) || EntryIsDeleted(*entry)) continue; insert_new(self, EntryGetHash(self, *entry), EntryGetValue(*entry)); @@ -356,17 +356,22 @@ void resize(HashSet *self, size_t new_size) /* now we can free the old array */ Free(old_entries); } +#else + +/* resize must be defined outside */ +static inline void resize(HashSet *self, size_t new_size); + +#endif /** * grow the hashset if adding 1 more elements would make it too crowded * @internal */ -static INLINE -void maybe_grow(HashSet *self) +static inline void maybe_grow(HashSet *self) { size_t resize_to; - if(LIKELY(self->num_elements + 1 <= self->enlarge_threshold)) + if (LIKELY(self->num_elements + 1 <= self->enlarge_threshold)) return; /* double table size */ @@ -378,35 +383,34 @@ void maybe_grow(HashSet *self) * shrink the hashset if it is only sparsely filled * @internal */ -static INLINE -void maybe_shrink(HashSet *self) +static inline void maybe_shrink(HashSet *self) { size_t size; size_t resize_to; - if(!self->consider_shrink) + if (!self->consider_shrink) return; self->consider_shrink = 0; size = hashset_size(self); - if(size <= HT_MIN_BUCKETS) + if (size <= HT_MIN_BUCKETS) return; - if(LIKELY(size > self->shrink_threshold)) + if (LIKELY(size > self->shrink_threshold)) return; resize_to = ceil_po2(size); - if(resize_to < 4) + if (resize_to < 4) resize_to = 4; resize(self, resize_to); } /** - * Insert an element into the hashset. If no element with key key exists yet, + * Insert an element into the hashset. If no element with the given key exists yet, * then a new one is created and initialized with the InitData function. - * Otherwise the exisiting element is returned (for hashs where key is equal to + * Otherwise the existing element is returned (for hashs where key is equal to * value, nothing is returned.) * * @param self the hashset @@ -425,7 +429,7 @@ InsertReturnValue hashset_insert(HashSet *self, KeyType key) } /** - * Searchs for an element with key @p key. + * Searches for an element with key @p key. * * @param self the hashset * @param key the key to search for @@ -439,16 +443,16 @@ InsertReturnValue hashset_find(const HashSet *self, ConstKeyType key) unsigned hash = Hash(self, key); size_t bucknum = hash & hashmask; - while(1) { + for (;;) { HashSetEntry *entry = & self->entries[bucknum]; - if(EntryIsEmpty(*entry)) { + if (EntryIsEmpty(*entry)) { return NullReturnValue; } - if(EntryIsDeleted(*entry)) { + if (EntryIsDeleted(*entry)) { // value is deleted - } else if(EntryGetHash(self, *entry) == hash) { - if(KeysEqual(self, GetKey(EntryGetValue(*entry)), key)) { + } else if (EntryGetHash(self, *entry) == hash) { + if (KeysEqual(self, GetKey(EntryGetValue(*entry)), key)) { // found the value return GetInsertReturnValue(*entry, 1); } @@ -479,16 +483,16 @@ void hashset_remove(HashSet *self, ConstKeyType key) self->entries_version++; #endif - while(1) { + for (;;) { HashSetEntry *entry = & self->entries[bucknum]; - if(EntryIsEmpty(*entry)) { + if (EntryIsEmpty(*entry)) { return; } - if(EntryIsDeleted(*entry)) { + if (EntryIsDeleted(*entry)) { // entry is deleted - } else if(EntryGetHash(self, *entry) == hash) { - if(KeysEqual(self, GetKey(EntryGetValue(*entry)), key)) { + } else if (EntryGetHash(self, *entry) == hash) { + if (KeysEqual(self, GetKey(EntryGetValue(*entry)), key)) { EntrySetDeleted(*entry); self->num_deleted++; self->consider_shrink = 1; @@ -506,10 +510,9 @@ void hashset_remove(HashSet *self, ConstKeyType key) * Initializes hashset with a specific size * @internal */ -static INLINE -void init_size(HashSet *self, size_t initial_size) +static inline void init_size(HashSet *self, size_t initial_size) { - if(initial_size < 4) + if (initial_size < 4) initial_size = 4; self->entries = Alloc(initial_size); @@ -521,12 +524,15 @@ void init_size(HashSet *self, size_t initial_size) #ifndef NDEBUG self->entries_version = 0; #endif +#ifdef ADDITIONAL_INIT + ADDITIONAL_INIT +#endif reset_thresholds(self); } /** - * Initialializes a hashset with the default size. The memory for the set has to + * Initializes a hashset with the default size. The memory for the set has to * already allocated. */ void hashset_init(HashSet *self) @@ -540,6 +546,9 @@ void hashset_init(HashSet *self) */ void hashset_destroy(HashSet *self) { +#ifdef ADDITIONAL_TERM + ADDITIONAL_TERM +#endif Free(self->entries); #ifndef NDEBUG self->entries = NULL; @@ -547,14 +556,14 @@ void hashset_destroy(HashSet *self) } /** - * Initializes a hashset expecting expected_element size + * Initializes a hashset expecting expected_element size. */ void hashset_init_size(HashSet *self, size_t expected_elements) { size_t needed_size; size_t po2size; - if(expected_elements >= UINT_MAX/2) { + if (expected_elements >= UINT_MAX/2) { abort(); } @@ -563,6 +572,7 @@ void hashset_init_size(HashSet *self, size_t expected_elements) init_size(self, po2size); } +#ifndef NO_ITERATOR /** * Initializes a hashset iterator. The memory for the allocator has to be * already allocated. @@ -593,9 +603,9 @@ ValueType hashset_iterator_next(HashSetIterator *self) do { current_bucket++; - if(current_bucket >= end) + if (current_bucket >= end) return NullValue; - } while(EntryIsEmpty(*current_bucket) || EntryIsDeleted(*current_bucket)); + } while (EntryIsEmpty(*current_bucket) || EntryIsDeleted(*current_bucket)); self->current_bucket = current_bucket; return EntryGetValue(*current_bucket); @@ -614,12 +624,13 @@ void hashset_remove_iterator(HashSet *self, const HashSetIterator *iter) /* needs to be on a valid element */ assert(entry < self->entries + self->num_buckets); - if(EntryIsDeleted(*entry)) + if (EntryIsDeleted(*entry)) return; EntrySetDeleted(*entry); self->num_deleted++; self->consider_shrink = 1; } +#endif /* NO_ITERATOR */ -#endif +#endif /* HashSet */