hash: Make hash function pieces available to other modules.
authorBen Pfaff <blp@nicira.com>
Sat, 28 Feb 2009 00:54:38 +0000 (16:54 -0800)
committerBen Pfaff <blp@nicira.com>
Mon, 2 Mar 2009 20:52:00 +0000 (12:52 -0800)
This way, modules that want to implement hash functions on their own terms,
for performance (e.g. the classifier), do not have to duplicate the code.

lib/hash.c
lib/hash.h

index 104ce224896f5dbbd725f62d6785c314c58cc90f..ebf3d5349f5613531c47f3e0e516c7d842c0732e 100644 (file)
 #include "hash.h"
 #include <string.h>
 
-/* This is the public domain lookup3 hash by Bob Jenkins from
- * http://burtleburtle.net/bob/c/lookup3.c, modified for style. */
-#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
-
-#define mix(a, b, c)                            \
-    do {                                        \
-      a -= c; a ^= rot(c,  4); c += b;          \
-      b -= a; b ^= rot(a,  6); a += c;          \
-      c -= b; c ^= rot(b,  8); b += a;          \
-      a -= c; a ^= rot(c, 16); c += b;          \
-      b -= a; b ^= rot(a, 19); a += c;          \
-      c -= b; c ^= rot(b,  4); b += a;          \
-    } while (0)
-
-#define final(a, b, c)                          \
-    do {                                        \
-      c ^= b; c -= rot(b, 14);                  \
-      a ^= c; a -= rot(c, 11);                  \
-      b ^= a; b -= rot(a, 25);                  \
-      c ^= b; c -= rot(b, 16);                  \
-      a ^= c; a -= rot(c,  4);                  \
-      b ^= a; b -= rot(a, 14);                  \
-      c ^= b; c -= rot(b, 24);                  \
-    } while (0)
-
 /* Returns the hash of the 'n' 32-bit words at 'p', starting from 'basis'.
  * 'p' must be properly aligned. */
 uint32_t
@@ -72,7 +47,7 @@ hash_words(const uint32_t *p, size_t n, uint32_t basis)
         a += p[0];
         b += p[1];
         c += p[2];
-        mix(a, b, c);
+        HASH_MIX(a, b, c);
         n -= 3;
         p += 3;
     }
@@ -86,7 +61,7 @@ hash_words(const uint32_t *p, size_t n, uint32_t basis)
         /* fall through */
     case 1:
         a += p[0];
-        final(a, b, c);
+        HASH_FINAL(a, b, c);
         /* fall through */
     case 0:
         break;
@@ -109,7 +84,7 @@ hash_bytes(const void *p_, size_t n, uint32_t basis)
         a += tmp[0];
         b += tmp[1];
         c += tmp[2];
-        mix(a, b, c);
+        HASH_MIX(a, b, c);
         n -= sizeof tmp;
         p += sizeof tmp;
     }
@@ -120,7 +95,7 @@ hash_bytes(const void *p_, size_t n, uint32_t basis)
         a += tmp[0];
         b += tmp[1];
         c += tmp[2];
-        final(a, b, c);
+        HASH_FINAL(a, b, c);
     }
 
     return c;
index a52d8ca7bd84960de2830ec82526521d405bf17d..e1393ddfd85a59ecd97ec83b80b3af69934d95d0 100644 (file)
 #include <stddef.h>
 #include <stdint.h>
 
+/* This is the public domain lookup3 hash by Bob Jenkins from
+ * http://burtleburtle.net/bob/c/lookup3.c, modified for style. */
+
+#define HASH_ROT(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
+
+#define HASH_MIX(a, b, c)                       \
+    do {                                        \
+      a -= c; a ^= HASH_ROT(c,  4); c += b;     \
+      b -= a; b ^= HASH_ROT(a,  6); a += c;     \
+      c -= b; c ^= HASH_ROT(b,  8); b += a;     \
+      a -= c; a ^= HASH_ROT(c, 16); c += b;     \
+      b -= a; b ^= HASH_ROT(a, 19); a += c;     \
+      c -= b; c ^= HASH_ROT(b,  4); b += a;     \
+    } while (0)
+
+#define HASH_FINAL(a, b, c)                     \
+    do {                                        \
+      c ^= b; c -= HASH_ROT(b, 14);             \
+      a ^= c; a -= HASH_ROT(c, 11);             \
+      b ^= a; b -= HASH_ROT(a, 25);             \
+      c ^= b; c -= HASH_ROT(b, 16);             \
+      a ^= c; a -= HASH_ROT(c,  4);             \
+      b ^= a; b -= HASH_ROT(a, 14);             \
+      c ^= b; c -= HASH_ROT(b, 24);             \
+    } while (0)
+
 uint32_t hash_words(const uint32_t *, size_t n_word, uint32_t basis);
 uint32_t hash_bytes(const void *, size_t n_bytes, uint32_t basis);