300 lines
8.3 KiB
C++
300 lines
8.3 KiB
C++
//
|
|
// ********************************************************************
|
|
// * License and Disclaimer *
|
|
// * *
|
|
// * The Geant4 software is copyright of the Copyright Holders of *
|
|
// * the Geant4 Collaboration. It is provided under the terms and *
|
|
// * conditions of the Geant4 Software License, included in the file *
|
|
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
|
// * include a list of copyright holders. *
|
|
// * *
|
|
// * Neither the authors of this software system, nor their employing *
|
|
// * institutes,nor the agencies providing financial support for this *
|
|
// * work make any representation or warranty, express or implied, *
|
|
// * regarding this software system or assume any liability for its *
|
|
// * use. Please see the license in the file LICENSE and URL above *
|
|
// * for the full disclaimer and the limitation of liability. *
|
|
// * *
|
|
// * This code implementation is the result of the scientific and *
|
|
// * technical work of the GEANT4 collaboration. *
|
|
// * By using, copying, modifying or distributing the software (or *
|
|
// * any work based on the software) you agree to acknowledge its *
|
|
// * use in resulting scientific publications, and indicate your *
|
|
// * acceptance of all terms of the Geant4 Software license. *
|
|
// ********************************************************************
|
|
//
|
|
//
|
|
//
|
|
// MolecularDNAHashing.hh
|
|
// Geant4
|
|
//
|
|
// Created by Mathieu Karamitros
|
|
//
|
|
//
|
|
|
|
#ifndef MolecularDNAHashing_h
|
|
#define MolecularDNAHashing_h
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
|
|
|
namespace G4::hashing
|
|
{
|
|
namespace crc32
|
|
{
|
|
//--------------------------------------------------------------------------
|
|
// Generate CRC lookup table
|
|
//--------------------------------------------------------------------------
|
|
|
|
template<unsigned long long c, int k = 8>
|
|
struct f : f<((c & 1) ? 0xedb88320 : 0) ^ (c >> 1), k - 1>
|
|
{};
|
|
template<unsigned long long c>
|
|
struct f<c, 0>
|
|
{
|
|
enum
|
|
{
|
|
value = c
|
|
};
|
|
};
|
|
|
|
#define _A_(x) _B_(x) _B_(x + 128llu)
|
|
#define _B_(x) _C_(x) _C_(x + 64llu)
|
|
#define _C_(x) _D_(x) _D_(x + 32llu)
|
|
#define _D_(x) _E_(x) _E_(x + 16llu)
|
|
#define _E_(x) _F_(x) _F_(x + 8llu)
|
|
#define _F_(x) _G_(x) _G_(x + 4llu)
|
|
#define _G_(x) _H_(x) _H_(x + 2llu)
|
|
#define _H_(x) _I_(x) _I_(x + 1llu)
|
|
#define _I_(x) f<x>::value,
|
|
|
|
static constexpr unsigned fCrc_table[] = {_A_(0llu)};
|
|
|
|
//--------------------------------------------------------------------------
|
|
// CRC32 ALGO
|
|
//--------------------------------------------------------------------------
|
|
|
|
//--------------------------------
|
|
// RUN TIME ALGO
|
|
uint32_t Hash(const char* str, size_t len);
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Details for compilation time
|
|
namespace detail
|
|
{
|
|
// CRC32 Table (zlib polynomial)
|
|
template<size_t idx>
|
|
constexpr uint32_t Combine_crc32(const char* str, uint32_t part)
|
|
{
|
|
return (part >> 8) ^ fCrc_table[(part ^ str[idx]) & 0x000000FF];
|
|
}
|
|
|
|
// recursion
|
|
template<size_t idx>
|
|
constexpr uint32_t Crc32(const char* str)
|
|
{
|
|
return Combine_crc32<idx>(str, Crc32<idx - 1>(str));
|
|
}
|
|
|
|
// stop-recursion
|
|
template<>
|
|
constexpr uint32_t Crc32<size_t(-1)>(const char* /*str*/)
|
|
{
|
|
return 0xFFFFFFFF;
|
|
}
|
|
} // namespace detail
|
|
|
|
//--------------------------------------------------------------------------
|
|
// use COMPILATION TIME CRC32 as a hash function
|
|
template<size_t len>
|
|
constexpr uint32_t Hash(const char (&str)[len])
|
|
{
|
|
return (detail::Crc32<len - 2>(str)) ^ 0xFFFFFFFF;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// std::string hasher for convenience
|
|
uint32_t Hash(const std::string& str);
|
|
// in window
|
|
// warning C4717: 'G4::hashing::crc32::crc32_hasher<G4String>::operator()':
|
|
// recursive on all control paths, function will cause runtime stack overflow
|
|
/*
|
|
template <typename T>
|
|
struct crc32_hasher
|
|
{
|
|
template <size_t len>
|
|
uint32_t constexpr operator()(const char (&str)[len]) const
|
|
{
|
|
return hash(str);
|
|
}
|
|
|
|
uint32_t operator()(T str) const { return hash(str); }
|
|
};
|
|
|
|
template <typename T>
|
|
uint32_t constexpr hash(T&& t)
|
|
{
|
|
return crc32_hasher<typename std::decay<T>::type>()(std::forward<T>(t));
|
|
}
|
|
*/
|
|
} // namespace crc32
|
|
|
|
//--------------------------------------------------------------------------
|
|
// fnv ALGO
|
|
//--------------------------------------------------------------------------
|
|
|
|
namespace fnv
|
|
{
|
|
// Fowler / Noll / Vo (fnv) Hash - 1a
|
|
// magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/
|
|
#define fnv_offset_basis 0xcbf29ce484222325U
|
|
#define fnv_prime 0x100000001b3U // 64 bits
|
|
// 224 + 28 + 0x93
|
|
|
|
//------------------------------------------------------------------------
|
|
// Run time
|
|
size_t Hash(const std::string& str);
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Details for compilation time
|
|
namespace detail
|
|
{
|
|
// recursion
|
|
template<int idx>
|
|
constexpr size_t Fnv(const char* str, size_t len, size_t hash)
|
|
{
|
|
return Fnv<idx - 1>(str, len, (hash ^ (str[len - idx])) * fnv_prime);
|
|
}
|
|
|
|
// stop-recursion
|
|
template<>
|
|
constexpr size_t Fnv<-1>(const char*, size_t, size_t hash)
|
|
{
|
|
return hash;
|
|
}
|
|
} // namespace detail
|
|
|
|
//------------------------------------------------------------------------
|
|
// COMPILATION TIME
|
|
template<size_t len>
|
|
constexpr size_t Hash(const char (&str)[len])
|
|
{
|
|
return detail::Fnv<len - 2>(str, len - 2, fnv_offset_basis);
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
template<class>
|
|
struct fnv_hasher;
|
|
|
|
template<typename T>
|
|
struct fnv_hasher
|
|
{
|
|
template<size_t len>
|
|
size_t constexpr operator()(const char (&str)[len]) const
|
|
{
|
|
return Hash(str);
|
|
}
|
|
|
|
size_t operator()(const T& str) const { return Hash(str); }
|
|
};
|
|
|
|
// template<>
|
|
// size_t fnv_hasher<std::string>::operator()(const std::string& str)
|
|
// const{
|
|
// return hash(str.c_str());
|
|
// }
|
|
|
|
template<typename T>
|
|
size_t constexpr Hash(T&& t)
|
|
{
|
|
return fnv_hasher<typename std::decay<T>::type>()(std::forward<T>(t));
|
|
}
|
|
} // namespace fnv
|
|
|
|
//--------------------------------------------------------------------------
|
|
// LARSON
|
|
//--------------------------------------------------------------------------
|
|
|
|
namespace larson
|
|
{
|
|
//------------------------------------------------------------------------
|
|
// Details for compilation time
|
|
namespace detail
|
|
{
|
|
// recursion
|
|
template<int idx>
|
|
constexpr size_t Larson(const char* str, size_t len, size_t hash)
|
|
{
|
|
return Larson<idx - 1>(str, len + 1, hash * 101 + str[len]);
|
|
}
|
|
|
|
// stop-recursion
|
|
template<>
|
|
constexpr size_t Larson<-1>(const char*, size_t, size_t hash)
|
|
{
|
|
return hash;
|
|
}
|
|
} // namespace detail
|
|
|
|
//------------------------------------------------------------------------
|
|
// COMPILATION TIME
|
|
template<size_t len>
|
|
constexpr size_t Cthash(const char (&str)[len], unsigned int seed = 0)
|
|
{
|
|
return detail::Larson<len - 2>(str, 0, seed);
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// RUN TIME
|
|
size_t Hash(const char* str, unsigned int seed = 0);
|
|
|
|
size_t Hash(std::string str, unsigned int seed = 0);
|
|
} // namespace larson
|
|
|
|
//--------------------------------------------------------------------------
|
|
// DEFAULT STRING HASHER
|
|
//--------------------------------------------------------------------------
|
|
|
|
template<typename T>
|
|
struct hasher
|
|
{
|
|
std::size_t constexpr operator()(char const* input) const
|
|
{
|
|
return *input ? static_cast<std::size_t>(*input) + 33 * (*this)(input + 1) : 5381;
|
|
}
|
|
|
|
std::size_t operator()(const std::string& str) const { return (*this)(str.c_str()); }
|
|
};
|
|
|
|
template<typename T>
|
|
std::size_t constexpr Hash(T&& t)
|
|
{
|
|
return hasher<typename std::decay<T>::type>()(std::forward<T>(t));
|
|
}
|
|
|
|
// not necessary
|
|
template<>
|
|
std::size_t constexpr Hash<const char*>(const char*&& str)
|
|
{
|
|
return hasher<std::string>()(str);
|
|
}
|
|
|
|
inline namespace literals
|
|
{
|
|
std::size_t constexpr operator""_hash(const char* s, size_t)
|
|
{
|
|
return hasher<std::string>()(s);
|
|
}
|
|
} // namespace literals
|
|
} // namespace G4::hashing
|
|
|
|
using namespace G4::hashing::literals;
|
|
|
|
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
|
|
|
#endif
|