Esempio n. 1
0
bool
hashtable2_resize(hashtable2* table, unsigned new_size)
{
    ASSERT(table != NULL);
    ASSERT(new_size != 0);

    new_size = dict_prime_geq(new_size);
    if (table->size == new_size)
	return true;

    if (table->count > new_size) {
	/* The number of records already in hashtable will not fit (must be a reduction in size). */
	return false;
    }

    const unsigned old_size = table->size;
    const size_t old_count = table->count;
    hash_node *const old_table = table->table;

    table->table = MALLOC(new_size * sizeof(hash_node));
    if (!table->table) {
	table->table = old_table;
	return false;
    }
    memset(table->table, 0, new_size * sizeof(hash_node));
    table->size = new_size;
    table->count = 0;

    for (unsigned i = 0; i < old_size; i++) {
	if (old_table[i].hash) {
	    bool inserted = false;
	    void **datum_location = insert(table, old_table[i].key, old_table[i].hash, &inserted);
	    if (!inserted || !datum_location) {
		FREE(table->table);
		table->table = old_table;
		table->size = old_size;
		table->count = old_count;
		return false;
	    }
	    *datum_location = old_table[i].datum;
	}
    }
    ASSERT(table->count == old_count);
    FREE(old_table);
    return true;
}
Esempio n. 2
0
bool
hashtable_resize(hashtable* table, unsigned new_size)
{
    ASSERT(table != NULL);
    ASSERT(new_size != 0);

    new_size = dict_prime_geq(new_size);
    if (table->size == new_size)
	return true;

    /* TODO: investigate whether using realloc would be advantageous. */
    hash_node** ntable = MALLOC(new_size * sizeof(hash_node*));
    if (!ntable)
	return false;
    memset(ntable, 0, new_size * sizeof(hash_node*));

    for (unsigned i = 0; i < table->size; i++) {
	hash_node* node = table->table[i];
	while (node) {
	    hash_node* next = node->next;
	    unsigned mhash = node->hash % new_size;

	    hash_node* search = ntable[mhash];
	    hash_node* prev = NULL;
	    while (search && node->hash >= search->hash) {
		prev = search;
		search = search->next;
	    }
	    if ((node->next = search) != NULL)
		search->prev = node;
	    if ((node->prev = prev) != NULL)
		prev->next = node;
	    else
		ntable[mhash] = node;

	    node = next;
	}
    }

    FREE(table->table);
    table->table = ntable;
    table->size = new_size;
    return true;
}
Esempio n. 3
0
hashtable2*
hashtable2_new(dict_compare_func cmp_func, dict_hash_func hash_func,
	       dict_delete_func del_func, unsigned initial_size)
{
    ASSERT(hash_func != NULL);
    ASSERT(initial_size != 0);

    hashtable2* table = MALLOC(sizeof(*table));
    if (table) {
	table->size = dict_prime_geq(initial_size);
	table->table = MALLOC(table->size * sizeof(hash_node));
	if (!table->table) {
	    FREE(table);
	    return NULL;
	}
	memset(table->table, 0, table->size * sizeof(hash_node));
	table->cmp_func = cmp_func ? cmp_func : dict_ptr_cmp;
	table->hash_func = hash_func;
	table->del_func = del_func;
	table->count = 0;
    }
    return table;
}