/** * Inserts the data with the given hash into the table. * * Note that insertion may rearrange the table on a resize or rehash, * so previously found hash_entries are no longer valid after this function. */ int ht_insert(SdbHash *ht, ut32 hash, void *data, SdbListIter *iter) { ut32 hash_address; if (ht->entries >= ht->max_entries) ht_rehash (ht, ht->size_index + 1); else if (ht->deleted_entries + ht->entries >= ht->max_entries) ht_rehash (ht, ht->size_index); hash_address = hash % ht->size; do { SdbHashEntry *entry = ht->table + hash_address; ut32 double_hash; if (!entry_is_present (entry)) { if (entry_is_deleted (entry)) ht->deleted_entries--; entry->hash = hash; entry->data = data; if (!rehash) entry->iter = ls_append (ht->list, data); else entry->iter = iter; ht->entries++; return 1; } 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); /* We could hit here if a required resize failed. An unchecked-malloc * application could ignore this result. */ return 0; }
/** * 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; }
/** * Inserts the data with the given hash into the table. * * Note that insertion may rearrange the table on a resize or rehash, * so previously found hash_entries are no longer valid after this function. */ int ht_insert2(ht_t *ht, uint64_t hash, void *data, uint32_t length) { uint64_t hash_address; if(length == 0 || length > ht->data_length) { return -1; } if(ht->entries >= ht->max_entries) { hashtable_rehash(ht, ht->size_index + 1); } else if(ht->deleted_entries + ht->entries >= ht->max_entries) { hashtable_rehash(ht, ht->size_index); } 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_present(entry)) { if(entry_is_deleted(entry)) { ht->deleted_entries--; } entry->hash = hash; entry->length = length; memcpy(entry->data, data, length); ht->entries++; return 0; } uint64_t 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); /* We could hit here if a required resize failed. An unchecked-malloc * application could ignore this result. */ return -1; }