Example #1
0
/**
 * 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;
}
Example #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;
}
/**
 * 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;
}