]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/hash.c
Fix cmdline option handling
[netatalk.git] / etc / afpd / hash.c
index 24bfb403e664df46e19c40706d530f910fdfa092..b7471ccb19ec821b7b7a6559272b02ec6736c985 100644 (file)
@@ -14,7 +14,7 @@
  * 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 $
+ * $Id: hash.c,v 1.4 2009-11-19 10:37:43 franklahm Exp $
  * $Name:  $
  */
 #define NDEBUG
@@ -26,7 +26,7 @@
 #include "hash.h"
 
 #ifdef KAZLIB_RCSID
-static const char rcsid[] = "$Id: hash.c,v 1.3 2009-11-19 09:18:28 franklahm Exp $";
+static const char rcsid[] = "$Id: hash.c,v 1.4 2009-11-19 10:37:43 franklahm Exp $";
 #endif
 
 #define INIT_BITS   6
@@ -58,6 +58,7 @@ static const char rcsid[] = "$Id: hash.c,v 1.3 2009-11-19 09:18:28 franklahm Exp
 static hnode_t *hnode_alloc(void *context);
 static void hnode_free(hnode_t *node, void *context);
 static hash_val_t hash_fun_default(const void *key);
+static hash_val_t hash_fun2(const void *key);
 static int hash_comp_default(const void *key1, const void *key2);
 
 int hash_val_t_bit;
@@ -837,6 +838,65 @@ static hash_val_t hash_fun_default(const void *key)
     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 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;
+}
+
 static int hash_comp_default(const void *key1, const void *key2)
 {
     return strcmp(key1, key2);
@@ -904,7 +964,7 @@ static void del_node(hnode_t *n, void *c)
 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;