/** * Finds a hash table entry with the given key and hash of that key. * * Returns NULL if no entry is found. Note that the data pointer may be * modified by the user. */ static ht_entry_t* hashtable_search(const ht_t *ht, uint64_t hash) { uint64_t double_hash, hash_address; if(ht == NULL) { return NULL; } uint32_t element_size = sizeof(*ht->table) + ht->data_length; hash_address = hash % ht->size; do { ht_entry_t *entry = (ht_entry_t *)( (char *) ht->table + hash_address * element_size); if(entry_is_free(entry)) { return NULL; } if(entry_is_present(entry) && entry->hash == hash) { return entry; } double_hash = hash % ht->rehash; if(double_hash == 0) { double_hash = 1; } hash_address = (hash_address + double_hash) % ht->size; } while (hash_address != hash % ht->size); return NULL; }
/** * Inserts the given value into the set. * * Note that insertion may rearrange the table on a resize or rehash, * so previously found int_set_entry pointers are no longer valid * after this function. */ struct int_set_entry * int_set_add(struct int_set *set, uint32_t value) { uint32_t hash_address; struct int_set_entry *available_entry = NULL; if (set->entries >= set->max_entries) { int_set_rehash(set, set->size_index + 1); } else if (set->deleted_entries + set->entries >= set->max_entries) { int_set_rehash(set, set->size_index); } hash_address = value % set->size; do { struct int_set_entry *entry = set->table + hash_address; uint32_t double_hash; if (!entry_is_present(entry)) { if (available_entry == NULL) available_entry = entry; if (entry_is_free(entry)) break; if (entry_is_deleted(entry)) { set->deleted_entries--; entry->deleted = 0; } } if (entry->value == value) { return entry; } double_hash = 1 + value % set->rehash; hash_address = (hash_address + double_hash) % set->size; } while (hash_address != value % set->size); if (available_entry) { available_entry->value = value; available_entry->occupied = 1; set->entries++; return available_entry; } /* We could hit here if a required resize failed. An unchecked-malloc * application could ignore this result. */ return NULL; }
/** * Finds a hash table entry with the given key and hash of that key. * * Returns NULL if no entry is found. Note that the data pointer may be * modified by the user. */ SdbHashEntry* ht_search(SdbHash *ht, ut32 hash) { ut32 double_hash, hash_address = hash % ht->size; if (ht->entries) do { SdbHashEntry *entry = ht->table + hash_address; if (entry_is_free (entry)) return NULL; if (entry_is_present (entry) && entry->hash == hash) return entry; double_hash = hash % ht->rehash; if (double_hash == 0) double_hash = 1; hash_address = (hash_address + double_hash) % ht->size; } while (hash_address != hash % ht->size); return NULL; }
/** * Finds a hash table entry with the given key and hash of that key. * * Returns NULL if no entry is found. Note that the data pointer may be * modified by the user. */ static RHTE* ht_(search)(RHT *ht, utH hash) { utH double_hash, hash_address; if (ht == NULL) return NULL; hash_address = hash % ht->size; do { RHTE *entry = ht->table + hash_address; if (entry_is_free (entry)) return NULL; if (entry_is_present (entry) && entry->hash == hash) return entry; double_hash = hash % ht->rehash; if (double_hash == 0) double_hash = 1; hash_address = (hash_address + double_hash) % ht->size; } while (hash_address != hash % ht->size); return NULL; }
/** * Finds a set entry with the given value * * Returns NULL if no entry is found. */ struct int_set_entry * int_set_search(struct int_set *set, uint32_t value) { uint32_t hash_address; hash_address = value % set->size; do { uint32_t double_hash; struct int_set_entry *entry = set->table + hash_address; if (entry_is_free(entry)) { return NULL; } else if (entry_is_present(entry) && entry->value == value) { return entry; } double_hash = 1 + value % set->rehash; hash_address = (hash_address + double_hash) % set->size; } while (hash_address != value % set->size); return NULL; }