/**
 * 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;
}
Пример #2
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;
}
Пример #3
0
/**
 * 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;
}
Пример #4
0
/**
 * 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;
}
Пример #5
0
/**
 * 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;
}