* into proprietary software; there is no requirement for such software to
* contain a copyright notice related to this source.
*
- * $Id: hash.c,v 1.3 2009-11-19 09:18:28 franklahm Exp $
* $Name: $
*/
#define NDEBUG
#include "hash.h"
#ifdef KAZLIB_RCSID
-static const char rcsid[] = "$Id: hash.c,v 1.3 2009-11-19 09:18:28 franklahm Exp $";
#endif
#define INIT_BITS 6
return acc;
}
+/* From http://www.azillionmonkeys.com/qed/hash.html */
+#undef get16bits
+#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
+ || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
+#define get16bits(d) (*((const uint16_t *) (d)))
+#endif
+
+#if !defined (get16bits)
+#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \
+ +(uint32_t)(((const uint8_t *)(d))[0]) )
+#endif
+
static int hash_comp_default(const void *key1, const void *key2)
{
return strcmp(key1, key2);
#ifdef KAZLIB_TEST_MAIN
+static hash_val_t hash_fun2(const void *key)
+{
+ int len, rem;
+ const unsigned char *data = key;
+ hash_val_t hash = 0, tmp = 0;
+
+ len = strlen((char *)data);
+
+ rem = len & 3;
+ len >>= 2;
+
+ /* Main loop */
+ for (;len > 0; len--) {
+ hash += get16bits (data);
+ tmp = (get16bits (data+2) << 11) ^ hash;
+ hash = (hash << 16) ^ tmp;
+ data += 2*sizeof (uint16_t);
+ hash += hash >> 11;
+ }
+
+ /* Handle end cases */
+ switch (rem) {
+ case 3: hash += get16bits (data);
+ hash ^= hash << 16;
+ hash ^= data[sizeof (uint16_t)] << 18;
+ hash += hash >> 11;
+ break;
+ case 2: hash += get16bits (data);
+ hash ^= hash << 11;
+ hash += hash >> 17;
+ break;
+ case 1: hash += *data;
+ hash ^= hash << 10;
+ hash += hash >> 1;
+ }
+
+ /* Force "avalanching" of final 127 bits */
+ hash ^= hash << 3;
+ hash += hash >> 5;
+ hash ^= hash << 4;
+ hash += hash >> 17;
+ hash ^= hash << 25;
+ hash += hash >> 6;
+
+ return hash;
+}
+
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
int main(void)
{
input_t in;
- hash_t *h = hash_create(HASHCOUNT_T_MAX, 0, 0);
+ hash_t *h = hash_create(HASHCOUNT_T_MAX, 0, hash_fun2);
hnode_t *hn;
hscan_t hs;
char *tok1, *tok2, *val;
"s switch to non-functioning allocator\n"
"q quit";
- if (!h)
+ if (!h) {
puts("hash_create failed");
+ return 1;
+ }
for (;;) {
if (prompt)
puts("out of memory");
free((void *) key);
free(val);
+ break;
}
if (!hash_alloc_insert(h, key, val)) {