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