Пример #1
0
HashTable *hash_table_new(HashTableHashFunc hash_func, 
                          HashTableEqualFunc equal_func)
{
	HashTable *hash_table;

	/* Allocate a new hash table structure */
	
	hash_table = (HashTable *) malloc(sizeof(HashTable));

	if (hash_table == NULL) {
		return NULL;
	}
	
	hash_table->hash_func = hash_func;
	hash_table->equal_func = equal_func;
	hash_table->key_free_func = NULL;
	hash_table->value_free_func = NULL;
	hash_table->entries = 0;
	hash_table->prime_index = 0;

	/* Allocate the table */

	if (!hash_table_allocate_table(hash_table, 0)) {
		free(hash_table);

		return NULL;
	}

	return hash_table;
}
Пример #2
0
int hash_table_resize(HashTable *hash_table)
{
    HashTableEntry **old_table;
    unsigned long long int old_table_size;
    int old_prime_index;
    HashTableEntry *rover;
    HashTableEntry *next;
    unsigned long long int index;
    unsigned long long int i;
        
    int increment = 0;    
    
    // GROW
    if((hash_table->entries * 2) / hash_table->table_size > 0)
    {
        do
        {
            /* Table is more than 1/2 full */
            increment++;

        } while ((hash_table->entries * 2) / getHashTableSizeWithIncrement(hash_table, increment) > 0);
    }    
    // SHRINK
    else if((hash_table->entries * 8) / hash_table->table_size == 0)
    {
        do 
        {
            // Are we already as small as possible?
            if(getHashTableSizeWithIncrement(hash_table, increment) <= hash_table_primes[0])
            {
                break;
            }
            
            /* Table is less than 1/8 full */
            increment--;
        } while ((hash_table->entries * 8) / getHashTableSizeWithIncrement(hash_table, increment) <= 0);
    }
    
    if(increment != 0)
    {	
	/* Store a copy of the old table */	
	old_table = hash_table->table;
	old_table_size = hash_table->table_size;
	old_prime_index = hash_table->prime_index;
	
	if (!hash_table_allocate_table(hash_table, increment)) {

            /* Failed to allocate the new table */
            
            printf("CRITICAL: FAILED TO ALLOCATE HASH TABLE!\n");

            hash_table->table = old_table;
            hash_table->table_size = old_table_size;
            hash_table->prime_index = old_prime_index;

            return 0;
	}

	/* Link all entries from all chains into the new table */

	for (i=0; i<old_table_size; ++i) {
            rover = old_table[i];

            while (rover != NULL) {
                next = rover->next;

                /* Find the index into the new table */

                index = hash_table->hash_func(rover->key) % hash_table->table_size;

                /* Link this entry into the chain */

                rover->next = hash_table->table[index];
                hash_table->table[index] = rover;

                /* Advance to next in the chain */

                rover = next;
            }
	}

	/* Free the old table */

	free(old_table);       
    }
    
    return 1;
}
Пример #3
0
static int hash_table_enlarge(HashTable *hash_table)
{
	HashTableEntry **old_table;
	unsigned int old_table_size;
	unsigned int old_prime_index;
	HashTableEntry *rover;
	HashTableEntry *next;
	unsigned int index;
	unsigned int i;

	/* Store a copy of the old table */

	old_table = hash_table->table;
	old_table_size = hash_table->table_size;
	old_prime_index = hash_table->prime_index;

	/* Allocate a new, larger table */

	++hash_table->prime_index;

	if (!hash_table_allocate_table(hash_table)) {

		/* Failed to allocate the new table */

		hash_table->table = old_table;
		hash_table->table_size = old_table_size;
		hash_table->prime_index = old_prime_index;

		return 0;
	}

	/* Link all entries from all chains into the new table */

	for (i=0; i<old_table_size; ++i) {
		rover = old_table[i];

		while (rover != NULL) {
			next = rover->next;

			/* Find the index into the new table */

			index = hash_table->hash_func(rover->key)
			      % hash_table->table_size;

			/* Link this entry into the chain */

			rover->next = hash_table->table[index];
			hash_table->table[index] = rover;

			/* Advance to next in the chain */

			rover = next;
		}
	}

	/* Free the old table */

	free(old_table);

	return 1;
}