From 9fa99306140f5d16f43b3fe3e495e8a95a87e20d Mon Sep 17 00:00:00 2001 From: Sears Russell Date: Sun, 3 Oct 2010 18:00:34 +0000 Subject: [PATCH] added fnv-1 hash implementation --- src/stasis/CMakeLists.txt | 2 +- src/stasis/util/hashFunctions.c | 7 +++ stasis/util/hashFunctions.h | 107 ++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 src/stasis/util/hashFunctions.c create mode 100644 stasis/util/hashFunctions.h diff --git a/src/stasis/CMakeLists.txt b/src/stasis/CMakeLists.txt index a33a1e2..095fd2e 100644 --- a/src/stasis/CMakeLists.txt +++ b/src/stasis/CMakeLists.txt @@ -46,7 +46,7 @@ ADD_LIBRARY(stasis crc32.c redblack.c tsearchcompat.c lhtable.c concurrentHash.c bufferManager/pageArray.c bufferManager/bufferHash.c replacementPolicy/lru.c replacementPolicy/lruFast.c replacementPolicy/threadsafeWrapper.c replacementPolicy/concurrentWrapper.c - util/log2.c util/histogram.c + util/log2.c util/histogram.c util//hashFunctions.c stlredblack.cpp) INSTALL(TARGETS stasis LIBRARY DESTINATION lib) diff --git a/src/stasis/util/hashFunctions.c b/src/stasis/util/hashFunctions.c new file mode 100644 index 0000000..6a3c6ce --- /dev/null +++ b/src/stasis/util/hashFunctions.c @@ -0,0 +1,7 @@ +/* + * hashFunctions.c + * + * Created on: Oct 3, 2010 + * Author: sears + */ +#include diff --git a/stasis/util/hashFunctions.h b/stasis/util/hashFunctions.h new file mode 100644 index 0000000..924c5f6 --- /dev/null +++ b/stasis/util/hashFunctions.h @@ -0,0 +1,107 @@ +/* + * hashFunctions.h + * + * Created on: Oct 3, 2010 + * Author: sears + */ + +#ifndef HASHFUNCTIONS_H_ +#define HASHFUNCTIONS_H_ + +/** + * This file contains a number of hash function implementations. + * + * Some are expensive, but general-purpose, and choose values with good + * mathematical properties (i.e. CRC32). Others are faster, but special + * purpose (assume their input is an integer), or provide weaker guarantees + * about their outputs. + * + * FNV-1 hash implementations all have the following form: + * + * hash = offset_basis + * for each octet_of_data to be hashed + * hash = hash * FNV_prime + * hash = hash xor octet_of_data + * return hash + * + * + * (From http://isthe.com/chongo/tech/comp/fnv/) + */ + +#include + +#define stasis_hash_util_define_fnv_1(TYPE, FNV_prime, offset_basis) \ +static inline TYPE stasis_util_hash_fnv_1_##TYPE(const byte* octets, int len){\ + TYPE hash = offset_basis; \ + \ + for(int i = 0; i < len; i++) { \ + hash = hash * FNV_prime; \ + hash ^= octets[i]; \ + } \ + return hash; \ +} \ +/** + * Implementation of FNV-1 (32-bit). Function is called stasis_util_hash_fnv_uint32_t(). + */ +stasis_hash_util_define_fnv_1(uint32_t, 16777619U, 2166136261U) +/** + * Implementation of FNV-1 (64-bit). Function is called stasis_util_hash_fnv_uint64_t(). + */ +stasis_hash_util_define_fnv_1(uint64_t, 1099511628211ULL, 14695981039346656037ULL) + +/** + * Macro to define xor folding for dynamically set of bits. This is static inline, + * so you can call the function and pass a constant value in as the second argument. + * With gcc and -O2, it should propagate the constant, and this is as good as a + * separte macro for each possible value of bits. + * + * Do not call this function if bits is less than 16. + */ +#define stasis_util_hash_define_fnv_xor_fold_big(TYPE) \ +static inline TYPE stasis_util_hash_fnv_xor_fold_big_##TYPE(TYPE val, uint8_t bits) {\ + const TYPE mask = ((TYPE)1<>bits) ^ (val & mask); \ +} + +stasis_util_hash_define_fnv_xor_fold_big(uint32_t) +stasis_util_hash_define_fnv_xor_fold_big(uint64_t) + +/** + * @see stasis_util_hash_define_fnv_xor_fold_big + * + * Do not call this function if bits is greater than 16. + */ +#define stasis_util_hash_define_fnv_xor_fold_tiny(TYPE) \ +static inline TYPE stasis_util_hash_fnv_xor_fold_tiny_##TYPE(TYPE val, uint8_t bits) {\ + const TYPE mask = ((TYPE)1<>bits ^ val) & mask; \ +} + +stasis_util_hash_define_fnv_xor_fold_tiny(uint32_t) + +static inline uint64_t stasis_util_hash_fnv_xor_fold_uint64_t(uint64_t val, uint8_t bits) { + if(bits < 16) { + return + stasis_util_hash_fnv_xor_fold_tiny_uint32_t( + stasis_util_hash_fnv_xor_fold_big_uint64_t(val, 32), bits + ); + } else if(bits < 32) { + return + stasis_util_hash_fnv_xor_fold_big_uint32_t( + stasis_util_hash_fnv_xor_fold_big_uint64_t(val, 32), bits + ); + } else { + return stasis_util_hash_fnv_xor_fold_big_uint64_t(val, bits); + } +} +static inline uint32_t stasis_util_hash_fnv_xor_fold_uint32_t(uint32_t val, uint8_t bits) { + if(bits < 16) { + return + stasis_util_hash_fnv_xor_fold_tiny_uint32_t(val, bits); + } else { + return + stasis_util_hash_fnv_xor_fold_big_uint32_t(val, bits); + } +} + +#endif /* HASHFUNCTIONS_H_ */