1 #include "hash.h"
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <stdint.h>
6 
create_hash_table(int size,unsigned long int (* hashfn)(void *),int (* keyfn)(void *,void *),void (* freefn)(void *))7 hash_table *create_hash_table(int size,
8 			     unsigned long int (*hashfn)(void *),
9 			     int (*keyfn)(void *, void*),
10 			     void (*freefn)(void *)){
11 	hash_table *new_table;
12 
13 	new_table=(hash_table*)calloc(1,sizeof(hash_table));
14 	if(!new_table) return NULL;
15 
16 	new_table->store=(hash_entry**)calloc(size,sizeof(hash_entry*));
17 	if(!new_table->store) { free(new_table); return NULL;}
18 
19 	new_table->size=size;
20 	new_table->items=0;
21 	new_table->hash_fun=hashfn;
22 	new_table->key_cmp=keyfn;
23 	new_table->free_fun=freefn;
24 
25 	return new_table;
26 }
27 
destroy_hash_table(hash_table * table)28 int destroy_hash_table(hash_table *table){
29 	int i;
30 	hash_entry *he=NULL, *ht=NULL;
31 
32 	if(table){
33 		if(table->store) {
34 			if (table->free_fun)
35 				for(i=0;i<table->size;i++){
36 					he=table->store[i];
37 					while(he){
38 						ht=he->next;
39 						table->free_fun(he->item);
40 						free(he);
41 						he=ht;
42 					}
43 				}
44 			free(table->store);
45 		}
46 		free(table);
47 		return 1;
48 	}
49 	return 0;
50 }
51 
hash_get(hash_table * table,void * key)52 hash_entry *hash_get(hash_table *table, void* key){
53 	unsigned int pos;
54 	hash_entry *he=NULL;
55 
56 	if(!table||!table->hash_fun||!table->key_cmp) return NULL;
57 
58 	pos=(table->hash_fun(key))%table->size;
59 
60 	he=table->store[pos];
61 	while(he){
62 		if(table->key_cmp(key,he->key)!=0) break;
63 		he=he->next;
64 	}
65 	return he;
66 }
67 
hash_add(hash_table * table,void * key,void * item)68 int hash_add(hash_table *table, void* key, void *item){
69 	unsigned int pos;
70 	hash_entry *he=NULL;
71 
72 	if(!table||!table->hash_fun) return 0;
73 
74 	pos=table->hash_fun(key)%table->size;
75 
76 	he=(hash_entry*)calloc(1,sizeof(hash_entry));
77 	if(!he) return 0;
78 	he->key=key;
79 	he->item=item;
80 	he->next=table->store[pos];
81 	table->store[pos]=he;
82 	table->items++;
83 	return 1;
84 }
85 
hash_delete(hash_table * table,void * key)86 int hash_delete(hash_table *table, void *key){
87 
88 	hash_entry *he,*ht,*hp;
89 	int del=0,pos;
90 
91 	if(!table||!table->hash_fun||!table->key_cmp) return del;
92 
93 	pos=table->hash_fun(key)%table->size;
94 	he=table->store[pos];
95 	ht=NULL;
96 	while(he){
97 		hp=he->next;
98 		if(table->key_cmp(key,he->key)!=0) {
99 			if (ht) ht->next=he->next;
100 			else table->store[pos]=he->next;
101 			if (table->free_fun)
102 				table->free_fun(he->item);
103 			free(he);
104 			del++;
105 			table->items--;
106 		} else ht=he;
107 		he=hp;
108 	}
109 	return del;
110 }
111 
112 
hash_start_iterator(hash_table * table)113 void hash_start_iterator(hash_table *table){
114 	if(!table) return;
115 	table->cur=table->store[0];
116 	table->where=-1;
117 }
118 
hash_get_next(hash_table * table)119 hash_entry *hash_get_next(hash_table *table){
120 
121 	if(!table||table->where>=table->size) {
122 		return NULL;
123 	}
124 
125 	if(table->where==-1&&table->cur&&table->cur==table->store[0]) {
126 		table->where++;
127 		return table->store[0];
128 	}
129 
130 	if(table->cur&&table->cur->next){
131 			return (table->cur = table->cur->next);
132 			}
133 
134 	table->cur=NULL;
135 	table->where++;
136 	while(table->where<table->size){
137 		if(table->store[table->where]){
138 			table->cur=table->store[table->where];
139 			break;
140 		}
141 		table->where++;
142 	}
143 	return table->cur;
144 }
145 
146 
147 //HASH AND COMPARE FNs
hash_fn_int(void * key)148 unsigned long int hash_fn_int(void *key){
149 	return (unsigned long int)(uintptr_t) key;
150 }
cmp_fn_int(void * key1,void * key2)151 int cmp_fn_int(void *key1, void *key2){
152 	return key1==key2;
153 }
154 
hash_fn_str(void * key)155 unsigned long int hash_fn_str(void *key)
156 {
157 	unsigned long int hash = 5381;
158 	char c;
159 	char *k=(char*)key;
160 
161 	while ( (c=*k++) )
162 		hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
163 	hash--;
164 
165 	return hash;
166 }
167 
cmp_fn_str(void * key1,void * key2)168 int cmp_fn_str(void *key1, void *key2){
169 	return !strcmp((char*)key1,(char*)key2);
170 }
171 
mem_hash(const void * str,const Uint32 len)172 Uint32 mem_hash(const void* str, const Uint32 len)
173 {
174 	Uint32 hash, i;
175 
176 	hash = 2166136261u;
177 
178 	for (i = 0; i < len; i++)
179 	{
180 		hash = hash * 1607;
181 		hash = hash ^ ((Uint8*)str)[i];
182 	}
183 
184 	return hash;
185 }
186 
187