1 /* Copyright (C) 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
4 #include "hashtable_private.h"
11 Credit for primes table: Aaron Krowne
12 http://br.endernet.org/~akrowne/
13 http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
15 static const unsigned int primes
[] = {
17 769, 1543, 3079, 6151,
18 12289, 24593, 49157, 98317,
19 196613, 393241, 786433, 1572869,
20 3145739, 6291469, 12582917, 25165843,
21 50331653, 100663319, 201326611, 402653189,
24 const unsigned int prime_table_length
= sizeof(primes
)/sizeof(primes
[0]);
25 const float max_load_factor
= 0.65;
27 /*****************************************************************************/
29 create_hashtable(unsigned int minsize
,
30 unsigned int (*hashf
) (void*),
31 int (*eqf
) (void*,void*))
34 unsigned int pindex
, size
= primes
[0];
35 /* Check requested hashtable isn't too large */
36 if (minsize
> (1u << 30)) return NULL
;
37 /* Enforce size as prime */
38 for (pindex
=0; pindex
< prime_table_length
; pindex
++) {
39 if (primes
[pindex
] > minsize
) { size
= primes
[pindex
]; break; }
41 h
= (struct hashtable
*)malloc(sizeof(struct hashtable
));
42 if (NULL
== h
) return NULL
; /*oom*/
43 h
->table
= (struct entry
**)malloc(sizeof(struct entry
*) * size
);
44 if (NULL
== h
->table
) { free(h
); return NULL
; } /*oom*/
45 memset(h
->table
, 0, size
* sizeof(struct entry
*));
46 h
->tablelength
= size
;
47 h
->primeindex
= pindex
;
51 h
->loadlimit
= (unsigned int) ceil(size
* max_load_factor
);
55 /*****************************************************************************/
57 hash(struct hashtable
*h
, void *k
)
59 /* Aim to protect against poor hash functions by adding logic here
60 * - logic taken from java 1.4 hashtable source */
61 unsigned int i
= h
->hashfn(k
);
63 i
^= ((i
>> 14) | (i
<< 18)); /* >>> */
65 i
^= ((i
>> 10) | (i
<< 22)); /* >>> */
69 /*****************************************************************************/
71 hashtable_expand(struct hashtable
*h
)
73 /* Double the size of the table to accomodate more entries */
74 struct entry
**newtable
;
77 unsigned int newsize
, i
, index
;
78 /* Check we're not hitting max capacity */
79 if (h
->primeindex
== (prime_table_length
- 1)) return 0;
80 newsize
= primes
[++(h
->primeindex
)];
82 newtable
= (struct entry
**)malloc(sizeof(struct entry
*) * newsize
);
85 memset(newtable
, 0, newsize
* sizeof(struct entry
*));
86 /* This algorithm is not 'stable'. ie. it reverses the list
87 * when it transfers entries between the tables */
88 for (i
= 0; i
< h
->tablelength
; i
++) {
89 while (NULL
!= (e
= h
->table
[i
])) {
90 h
->table
[i
] = e
->next
;
91 index
= indexFor(newsize
,e
->h
);
92 e
->next
= newtable
[index
];
99 /* Plan B: realloc instead */
102 newtable
= (struct entry
**)
103 realloc(h
->table
, newsize
* sizeof(struct entry
*));
104 if (NULL
== newtable
) { (h
->primeindex
)--; return 0; }
106 memset(newtable
[h
->tablelength
], 0, newsize
- h
->tablelength
);
107 for (i
= 0; i
< h
->tablelength
; i
++) {
108 for (pE
= &(newtable
[i
]), e
= *pE
; e
!= NULL
; e
= *pE
) {
109 index
= indexFor(newsize
,e
->h
);
117 e
->next
= newtable
[index
];
123 h
->tablelength
= newsize
;
124 h
->loadlimit
= (unsigned int) ceil(newsize
* max_load_factor
);
128 /*****************************************************************************/
130 hashtable_count(struct hashtable
*h
)
132 return h
->entrycount
;
135 /*****************************************************************************/
137 hashtable_insert(struct hashtable
*h
, void *k
, void *v
)
139 /* This method allows duplicate keys - but they shouldn't be used */
142 if (++(h
->entrycount
) > h
->loadlimit
)
144 /* Ignore the return value. If expand fails, we should
145 * still try cramming just this value into the existing table
146 * -- we may not have memory for a larger table, but one more
147 * element may be ok. Next time we insert, we'll try expanding again.*/
150 e
= (struct entry
*)malloc(sizeof(struct entry
));
151 if (NULL
== e
) { --(h
->entrycount
); return 0; } /*oom*/
153 index
= indexFor(h
->tablelength
,e
->h
);
156 e
->next
= h
->table
[index
];
161 /*****************************************************************************/
162 void * /* returns value associated with key */
163 hashtable_search(struct hashtable
*h
, void *k
)
166 unsigned int hashvalue
, index
;
167 hashvalue
= hash(h
,k
);
168 index
= indexFor(h
->tablelength
,hashvalue
);
172 /* Check hash value to short circuit heavier comparison */
173 if ((hashvalue
== e
->h
) && (h
->eqfn(k
, e
->k
))) return e
->v
;
179 /*****************************************************************************/
180 void * /* returns value associated with key */
181 hashtable_remove(struct hashtable
*h
, void *k
)
183 /* TODO: consider compacting the table when the load factor drops enough,
184 * or provide a 'compact' method. */
189 unsigned int hashvalue
, index
;
191 hashvalue
= hash(h
,k
);
192 index
= indexFor(h
->tablelength
,hash(h
,k
));
193 pE
= &(h
->table
[index
]);
197 /* Check hash value to short circuit heavier comparison */
198 if ((hashvalue
== e
->h
) && (h
->eqfn(k
, e
->k
)))
213 /*****************************************************************************/
216 hashtable_destroy(struct hashtable
*h
, int free_values
)
220 struct entry
**table
= h
->table
;
223 for (i
= 0; i
< h
->tablelength
; i
++)
227 { f
= e
; e
= e
->next
; freekey(f
->k
); free(f
->v
); free(f
); }
232 for (i
= 0; i
< h
->tablelength
; i
++)
236 { f
= e
; e
= e
->next
; freekey(f
->k
); free(f
); }
244 * Copyright (c) 2002, Christopher Clark
245 * All rights reserved.
247 * Redistribution and use in source and binary forms, with or without
248 * modification, are permitted provided that the following conditions
251 * * Redistributions of source code must retain the above copyright
252 * notice, this list of conditions and the following disclaimer.
254 * * Redistributions in binary form must reproduce the above copyright
255 * notice, this list of conditions and the following disclaimer in the
256 * documentation and/or other materials provided with the distribution.
258 * * Neither the name of the original author; nor the names of any contributors
259 * may be used to endorse or promote products derived from this software
260 * without specific prior written permission.
263 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
264 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
265 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
266 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
267 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
268 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
269 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
270 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
271 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
272 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
273 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.