From e51d11a93766448d55f57ae872c6ddbba61985d4 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Fri, 27 Nov 2015 15:33:16 +0100 Subject: add patch series --- ...-provide-a-general-purpose-hash-algorithm.patch | 261 +++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 debian/patches/ihash-as-cache0005-libihash-provide-a-general-purpose-hash-algorithm.patch (limited to 'debian/patches/ihash-as-cache0005-libihash-provide-a-general-purpose-hash-algorithm.patch') diff --git a/debian/patches/ihash-as-cache0005-libihash-provide-a-general-purpose-hash-algorithm.patch b/debian/patches/ihash-as-cache0005-libihash-provide-a-general-purpose-hash-algorithm.patch new file mode 100644 index 00000000..f23ef287 --- /dev/null +++ b/debian/patches/ihash-as-cache0005-libihash-provide-a-general-purpose-hash-algorithm.patch @@ -0,0 +1,261 @@ +From bc6d77c63547ce4da7e5d49f1a86a84aad42bf69 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Fri, 27 Nov 2015 03:24:24 +0100 +Subject: [PATCH hurd 5/5] libihash: provide a general purpose hash algorithm + +* libdiskfs/name-cache.c: Move the Murmur3 algorithm... +* libihash/murmur3.c: ... here, and properly attribute the code. +* libihash/ihash.h (hurd_ihash_hash32): New prototype. +* libihash/Makefile (SRCS): Add new file. +--- + libdiskfs/name-cache.c | 89 ++--------------------------------------------- + libihash/Makefile | 2 +- + libihash/ihash.h | 5 +++ + libihash/murmur3.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 102 insertions(+), 87 deletions(-) + create mode 100644 libihash/murmur3.c + +diff --git a/libdiskfs/name-cache.c b/libdiskfs/name-cache.c +index e9fe27e..53935ab 100644 +--- a/libdiskfs/name-cache.c ++++ b/libdiskfs/name-cache.c +@@ -21,6 +21,7 @@ + + #include "priv.h" + #include ++#include + #include + + /* The name cache is implemented using a hash table. +@@ -118,90 +119,6 @@ valid_entry (struct cache_bucket *b, int i) + return b->name[i] != 0; + } + +-/* This is the Murmur3 hash algorithm. */ +- +-#define FORCE_INLINE inline __attribute__((always_inline)) +- +-inline uint32_t rotl32 ( uint32_t x, int8_t r ) +-{ +- return (x << r) | (x >> (32 - r)); +-} +- +-#define ROTL32(x,y) rotl32(x,y) +- +-/* Block read - if your platform needs to do endian-swapping or can +- only handle aligned reads, do the conversion here. */ +- +-FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i ) +-{ +- return p[i]; +-} +- +-/* Finalization mix - force all bits of a hash block to avalanche. */ +- +-FORCE_INLINE uint32_t fmix32 ( uint32_t h ) +-{ +- h ^= h >> 16; +- h *= 0x85ebca6b; +- h ^= h >> 13; +- h *= 0xc2b2ae35; +- h ^= h >> 16; +- +- return h; +-} +- +-/* The Murmur3 hash function. */ +-void MurmurHash3_x86_32 ( const void * key, int len, +- uint32_t seed, void * out ) +-{ +- const uint8_t * data = (const uint8_t*)key; +- const int nblocks = len / 4; +- +- uint32_t h1 = seed; +- +- const uint32_t c1 = 0xcc9e2d51; +- const uint32_t c2 = 0x1b873593; +- +- /* body */ +- +- const uint32_t * blocks = (const uint32_t *)(data + nblocks*4); +- +- for(int i = -nblocks; i; i++) +- { +- uint32_t k1 = getblock32(blocks,i); +- +- k1 *= c1; +- k1 = ROTL32(k1,15); +- k1 *= c2; +- +- h1 ^= k1; +- h1 = ROTL32(h1,13); +- h1 = h1*5+0xe6546b64; +- } +- +- /* tail */ +- +- const uint8_t * tail = (const uint8_t*)(data + nblocks*4); +- +- uint32_t k1 = 0; +- +- switch(len & 3) +- { +- case 3: k1 ^= tail[2] << 16; +- case 2: k1 ^= tail[1] << 8; +- case 1: k1 ^= tail[0]; +- k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; +- }; +- +- /* finalization */ +- +- h1 ^= len; +- +- h1 = fmix32(h1); +- +- *(uint32_t*)out = h1; +-} +- + /* If there is no best candidate to replace, pick any. We approximate + any by picking the slot depicted by REPLACE, and increment REPLACE + then. */ +@@ -259,8 +176,8 @@ static inline unsigned long + hash (ino64_t dir_cache_id, const char *name) + { + unsigned long h; +- MurmurHash3_x86_32 (&dir_cache_id, sizeof dir_cache_id, 0, &h); +- MurmurHash3_x86_32 (name, strlen (name), h, &h); ++ h = hurd_ihash_hash32 (&dir_cache_id, sizeof dir_cache_id, 0); ++ h = hurd_ihash_hash32 (name, strlen (name), h); + return h; + } + +diff --git a/libihash/Makefile b/libihash/Makefile +index 09bb136..3377ef4 100644 +--- a/libihash/Makefile ++++ b/libihash/Makefile +@@ -20,7 +20,7 @@ dir := libihash + makemode := library + + libname := libihash +-SRCS = ihash.c ++SRCS = ihash.c murmur3.c + installhdrs = ihash.h + + OBJS = $(SRCS:.c=.o) +diff --git a/libihash/ihash.h b/libihash/ihash.h +index d332479..9333fc6 100644 +--- a/libihash/ihash.h ++++ b/libihash/ihash.h +@@ -349,5 +349,10 @@ int hurd_ihash_remove (hurd_ihash_t ht, hurd_ihash_key_t key); + was provided to hurd_ihash_add(). This call is faster than + hurd_ihash_remove(). */ + void hurd_ihash_locp_remove (hurd_ihash_t ht, hurd_ihash_locp_t locp); ++ ++/* We provide a general purpose hash function. This function can be ++ used with the generalized key interface to use arbitrary data as ++ keys using this library. */ ++uint32_t hurd_ihash_hash32 (const char *buf, size_t len, uint32_t seed); + + #endif /* _HURD_IHASH_H */ +diff --git a/libihash/murmur3.c b/libihash/murmur3.c +new file mode 100644 +index 0000000..0b06037 +--- /dev/null ++++ b/libihash/murmur3.c +@@ -0,0 +1,93 @@ ++/* This is the Murmur3 hash algorithm. ++ * ++ * MurmurHash3 was written by Austin Appleby, and is placed in the public ++ * domain. The author hereby disclaims copyright to this source code. ++ */ ++ ++#include ++#include ++ ++#define FORCE_INLINE static inline __attribute__((always_inline)) ++ ++static inline uint32_t rotl32 ( uint32_t x, int8_t r ) ++{ ++ return (x << r) | (x >> (32 - r)); ++} ++ ++#define ROTL32(x,y) rotl32(x,y) ++ ++/* Block read - if your platform needs to do endian-swapping or can ++ only handle aligned reads, do the conversion here. */ ++ ++FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i ) ++{ ++ return p[i]; ++} ++ ++/* Finalization mix - force all bits of a hash block to avalanche. */ ++ ++FORCE_INLINE uint32_t fmix32 ( uint32_t h ) ++{ ++ h ^= h >> 16; ++ h *= 0x85ebca6b; ++ h ^= h >> 13; ++ h *= 0xc2b2ae35; ++ h ^= h >> 16; ++ ++ return h; ++} ++ ++/* The Murmur3 hash function. */ ++static uint32_t ++MurmurHash3_x86_32 (const void *key, size_t len, uint32_t seed) ++{ ++ const uint8_t * data = (const uint8_t*)key; ++ const int nblocks = (int) (len / 4); ++ ++ uint32_t h1 = seed; ++ ++ const uint32_t c1 = 0xcc9e2d51; ++ const uint32_t c2 = 0x1b873593; ++ ++ /* body */ ++ ++ const uint32_t * blocks = (const uint32_t *)(data + nblocks*4); ++ ++ for(int i = -nblocks; i; i++) ++ { ++ uint32_t k1 = getblock32(blocks,i); ++ ++ k1 *= c1; ++ k1 = ROTL32(k1,15); ++ k1 *= c2; ++ ++ h1 ^= k1; ++ h1 = ROTL32(h1,13); ++ h1 = h1*5+0xe6546b64; ++ } ++ ++ /* tail */ ++ ++ const uint8_t * tail = (const uint8_t*)(data + nblocks*4); ++ ++ uint32_t k1 = 0; ++ ++ switch(len & 3) ++ { ++ case 3: k1 ^= tail[2] << 16; ++ case 2: k1 ^= tail[1] << 8; ++ case 1: k1 ^= tail[0]; ++ k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; ++ }; ++ ++ /* finalization */ ++ ++ h1 ^= len; ++ ++ h1 = fmix32(h1); ++ ++ return h1; ++} ++ ++uint32_t hurd_ihash_hash32 (const char *, size_t, uint32_t) ++ __attribute__ ((weak, alias ("MurmurHash3_x86_32"))); +-- +2.1.4 + -- cgit v1.2.3