From 7e56bd72d60caae88b422b8a979d0e259a829ead Mon Sep 17 00:00:00 2001 From: Stefen Guzik <guzik2@llnl.gov> Date: Sat, 30 Sep 2006 02:36:54 +0000 Subject: [PATCH] *** empty log message *** --- Common/Hash.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Common/Hash.h diff --git a/Common/Hash.h b/Common/Hash.h new file mode 100644 index 0000000000..3fd2004628 --- /dev/null +++ b/Common/Hash.h @@ -0,0 +1,49 @@ +#ifndef _HASH_H_ +#define _HASH_H_ + +#if defined(HAVE_64BIT_SIZE_T) +#define FNV_PRIME 1099511628211UL +#define FNV_OFFSET_BASIS 14695981039346656037UL +#else +#define FNV_PRIME 16777619UL +#define FNV_OFFSET_BASIS 2166136261UL +#endif + +//--Hash FNV1a implemented via for loop. "key" has size "len" bytes. + +inline size_t hash_FNV1a(const void *const key, const int len) +{ + const unsigned char *p = static_cast<const unsigned char*>(key); + size_t hash = FNV_OFFSET_BASIS; + for(int n = len; n--; ) hash = (hash^static_cast<size_t>(*p++))*FNV_PRIME; + return hash; +} + +//--Hash FNV1a implemented via template-metaprogramming loop. This should be +//--used if the length N is known at compile time. "key" has size "N" bytes. +//--Use the entry point HashFNV1a<N>::eval(key). + +template <int N> struct Hash1FNV1a { + static size_t eval(size_t hash, const unsigned char *p) + { + return Hash1FNV1a<N-1>::eval((hash^static_cast<size_t>(*p))*FNV_PRIME, p+1); + } +}; + +template <> struct Hash1FNV1a<1> { + static size_t eval(size_t hash, const unsigned char *p) + { + return (hash^static_cast<size_t>(*p))*FNV_PRIME; + } +}; + +// Entry point +template <int N> struct HashFNV1a { + static size_t eval(const void *const key) + { + size_t hash = FNV_OFFSET_BASIS; + return Hash1FNV1a<N>::eval(hash, static_cast<const unsigned char*>(key)); + } +}; + +#endif -- GitLab