Public feed #379999

Miscellany

public text v1 · immutable
Raw Edit
·published 2007-03-03 18:09 UTC
rendered paste body
static int primes[] = {50,100,150,200,250,300,350,400,500,1000,2000,3000,4000,5000,10000,50000,70000}; 

int str_hash (signed char *v)
{
	/* 31 bit hash function */
	const signed char *p = v;
	int h = *p;
	if (h)
		for (p += 1; *p != '\0'; p++)
		h = (h << 5) - h + *p;
	return h;
}

typedef struct _HashNode {
	int hash;
	void *content;
	struct _HashNode * next;
} HashNode;

typedef struct _HashTable{
	int free;
	int size_index;
	HashNode **nodes; 
} HashTable;

HashTable* init_hash_table(){
	HashTable *table = (HashTable*) calloc(1,sizeof(HashTable));
	table->size_index = 0;
	size = primes[table->size_index];
	table->free = size;
	table->nodes = (HashNode**) calloc(1, sizeof(HashNode*) * size);
	
	return table;
}

int hash_table_increase_size(HashTable *table){
	int i, new_position, newsize, oldsize;
	
	newsize = primes[table->size_index + 1];
	oldsize = primes[table->size_index];
	HashNode **new_nodes = (HashNode**) calloc(1, sizeof(HashNode*) * newsize);
	
	if (new_nodes == NULL) return -1;
	
	for (i=0; i < oldsize; i++) {
		if (table->nodes[i] != NULL) {
			new_position = table->nodes[i]->hash % newsize;
			new_nodes[new_position] = table->nodes[i];
		}
	}
	
	table->nodes = new_nodes;
	table->size_index++;
	table->free = table->free + (newsize - oldsize);
	
	return 1;
}

void insert_node(HashNode *node, HashTable *table) {
	int position;
	HashNode *scan;
	
	if (table->free < 2) hash_table_increase_size(table);
	
	position = node->hash % primes[table->size_index];
	
	if (table->nodes[position] == NULL){
		table->nodes[position] = node;
		table->free--;
	} else {
		scan = table->nodes[position];
		while (scan->next != NULL){		
			scan = scan->next;
		}
		scan->next = node;
	}
}

HashNode* get_node(int hash, HashTable *table){
	int position;
	HashNode *node;
	
	position = hash % primes[table->size_index];
	node = table->nodes[position];
	
	while (node != NULL){
		if (node->hash == hash) {
			return node;
		}
		node = node->next;
	}
	
	return NULL;
	
};