//===- StringHash.h ---------------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MCLD_STRING_HASH_FUNCTION_H #define MCLD_STRING_HASH_FUNCTION_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif #include <llvm/ADT/StringRef.h> #include <llvm/Support/ErrorHandling.h> #include <functional> namespace mcld { enum StringHashType { RS, JS, PJW, ELF, BKDR, SDBM, DJB, DEK, BP, FNV, AP }; /** \class template<size_t TYPE> StringHash * \brief the template StringHash class, for specification */ template<size_t TYPE> struct StringHash : public std::unary_function<const llvm::StringRef&, size_t> { size_t operator()(const llvm::StringRef& pKey) const { llvm::report_fatal_error("Undefined StringHash function.\n"); } }; /** \class StringHash<RSHash> * \brief RS StringHash funciton */ template<> struct StringHash<RS> : public std::unary_function<const llvm::StringRef&, size_t> { size_t operator()(const llvm::StringRef& pKey) const { const unsigned int b = 378551; size_t a = 63689; size_t hash_val = 0; for(unsigned int i = 0; i < pKey.size(); ++i) { hash_val = hash_val * a + pKey[i]; a = a * b; } return hash_val; } }; /** \class StringHash<JSHash> * \brief JS hash funciton */ template<> struct StringHash<JS> : public std::unary_function<const llvm::StringRef&, size_t> { size_t operator()(const llvm::StringRef& pKey) const { size_t hash_val = 1315423911; for(unsigned int i = 0; i < pKey.size(); ++i) { hash_val ^= ((hash_val << 5) + pKey[i] + (hash_val >> 2)); } return hash_val; } }; /** \class StringHash<PJW> * \brief P.J. Weinberger hash function */ template<> struct StringHash<PJW> : public std::unary_function<const llvm::StringRef&, size_t> { size_t operator()(const llvm::StringRef& pKey) const { const unsigned int BitsInUnsignedInt = (unsigned int)(sizeof(unsigned int) * 8); const unsigned int ThreeQuarters = (unsigned int)((BitsInUnsignedInt * 3) / 4); const unsigned int OneEighth = (unsigned int)(BitsInUnsignedInt / 8); const unsigned int HighBits = (unsigned int)(0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth); size_t hash_val = 0; size_t test = 0; for(unsigned int i = 0; i < pKey.size(); ++i) { hash_val = (hash_val << OneEighth) + pKey[i]; if((test = hash_val & HighBits) != 0) { hash_val = (( hash_val ^ (test >> ThreeQuarters)) & (~HighBits)); } } return hash_val; } }; /** \class StringHash<ELF> * \brief ELF hash function. */ template<> struct StringHash<ELF> : public std::unary_function<const llvm::StringRef&, size_t> { size_t operator()(const llvm::StringRef& pKey) const { size_t hash_val = 0; size_t x = 0; for (unsigned int i = 0; i < pKey.size(); ++i) { hash_val = (hash_val << 4) + pKey[i]; if((x = hash_val & 0xF0000000L) != 0) hash_val ^= (x >> 24); hash_val &= ~x; } return hash_val; } }; /** \class StringHash<BKDR> * \brief BKDR hash function */ template<> struct StringHash<BKDR> : public std::unary_function<const llvm::StringRef&, size_t> { size_t operator()(const llvm::StringRef& pKey) const { const size_t seed = 131; size_t hash_val = 0; for(size_t i = 0; i < pKey.size(); ++i) hash_val = (hash_val * seed) + pKey[i]; return hash_val; } }; /** \class StringHash<SDBM> * \brief SDBM hash function * 0.049s in 100000 test */ template<> struct StringHash<SDBM> : public std::unary_function<const llvm::StringRef&, size_t> { size_t operator()(const llvm::StringRef& pKey) const { size_t hash_val = 0; for(size_t i = 0; i < pKey.size(); ++i) hash_val = pKey[i] + (hash_val << 6) + (hash_val << 16) - hash_val; return hash_val; } }; /** \class StringHash<DJB> * \brief DJB hash function * 0.057s in 100000 test */ template<> struct StringHash<DJB> : public std::unary_function<const llvm::StringRef&, size_t> { size_t operator()(const llvm::StringRef& pKey) const { size_t hash_val = 5381; for(size_t i = 0; i < pKey.size(); ++i) hash_val = ((hash_val << 5) + hash_val) + pKey[i]; return hash_val; } }; /** \class StringHash<DEK> * \brief DEK hash function * 0.60s */ template<> struct StringHash<DEK> : public std::unary_function<const llvm::StringRef&, size_t> { size_t operator()(const llvm::StringRef& pKey) const { size_t hash_val = pKey.size(); for(size_t i = 0; i < pKey.size(); ++i) hash_val = ((hash_val << 5) ^ (hash_val >> 27)) ^ pKey[i]; return hash_val; } }; /** \class StringHash<BP> * \brief BP hash function * 0.057s */ template<> struct StringHash<BP> : public std::unary_function<const llvm::StringRef&, size_t> { size_t operator()(const llvm::StringRef& pKey) const { size_t hash_val = 0; for(size_t i = 0; i < pKey.size(); ++i) hash_val = hash_val << 7 ^ pKey[i]; return hash_val; } }; /** \class StringHash<FNV> * \brief FNV hash function * 0.058s */ template<> struct StringHash<FNV> : public std::unary_function<const llvm::StringRef&, size_t> { size_t operator()(const llvm::StringRef& pKey) const { const size_t fnv_prime = 0x811C9DC5; size_t hash_val = 0; for(size_t i = 0; i < pKey.size(); ++i) { hash_val *= fnv_prime; hash_val ^= pKey[i]; } return hash_val; } }; /** \class StringHash<AP> * \brief AP hash function * 0.060s */ template<> struct StringHash<AP> : public std::unary_function<const llvm::StringRef&, size_t> { size_t operator()(const llvm::StringRef& pKey) const { unsigned int hash_val = 0xAAAAAAAA; for(size_t i = 0; i < pKey.size(); ++i) { hash_val ^= ((i & 1) == 0)? ((hash_val << 7) ^ pKey[i] * (hash_val >> 3)): (~((hash_val << 11) + (pKey[i] ^ (hash_val >> 5)))); } return hash_val; } }; /** \class template<size_t TYPE> StringCompare * \brief the template StringCompare class, for specification */ template<typename STRING_TYPE> struct StringCompare : public std::binary_function<const STRING_TYPE&, const STRING_TYPE&, bool> { bool operator()(const STRING_TYPE& X, const STRING_TYPE& Y) const { return X == Y; } }; template<> struct StringCompare<const char*> : public std::binary_function<const char*, const char*, bool> { bool operator()(const char* X, const char* Y) const { return (0 == std::strcmp(X, Y)); } }; template<> struct StringCompare<char*> : public std::binary_function<const char*, const char*, bool> { bool operator()(const char* X, const char* Y) const { return (0 == std::strcmp(X, Y)); } }; } // namespace of mcld #endif