mirror of
https://github.com/OpenVPN/openvpn3.git
synced 2024-09-20 12:12:15 +02:00
Support Cityhash.
When running build script, add CITY=1 to build with Cityhash library. Signed-off-by: James Yonan <james@openvpn.net>
This commit is contained in:
parent
fdbb0b96b1
commit
ce0977b2ea
@ -853,23 +853,31 @@ namespace openvpn {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::size_t hashval() const
|
||||
template <typename HASH>
|
||||
void hash(HASH& h) const
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
switch (ver)
|
||||
{
|
||||
case Addr::V4:
|
||||
Hash::combine(seed, 4, u.v4);
|
||||
u.v4.hash(h);
|
||||
break;
|
||||
case Addr::V6:
|
||||
Hash::combine(seed, 6, u.v6);
|
||||
u.v6.hash(h);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CITYHASH
|
||||
std::size_t hashval() const
|
||||
{
|
||||
HashSizeT h;
|
||||
hash(h);
|
||||
return h.value();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OPENVPN_IP_IMMUTABLE
|
||||
private:
|
||||
#endif
|
||||
@ -967,6 +975,8 @@ namespace openvpn {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_CITYHASH
|
||||
OPENVPN_HASH_METHOD(openvpn::IP::Addr, hashval);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include <openvpn/common/socktypes.hpp>
|
||||
#include <openvpn/common/ffs.hpp>
|
||||
#include <openvpn/common/hexstr.hpp>
|
||||
#include <openvpn/common/hash.hpp>
|
||||
#include <openvpn/addr/iperr.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
@ -493,9 +492,10 @@ namespace openvpn {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
std::size_t hashval() const
|
||||
template <typename HASH>
|
||||
void hash(HASH& h) const
|
||||
{
|
||||
return Hash::value(u.addr);
|
||||
h(u.addr);
|
||||
}
|
||||
|
||||
#ifdef OPENVPN_IP_IMMUTABLE
|
||||
@ -566,6 +566,4 @@ namespace openvpn {
|
||||
}
|
||||
}
|
||||
|
||||
OPENVPN_HASH_METHOD(openvpn::IPv4::Addr, hashval);
|
||||
|
||||
#endif // OPENVPN_ADDR_IPV4_H
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include <openvpn/common/socktypes.hpp>
|
||||
#include <openvpn/common/ffs.hpp>
|
||||
#include <openvpn/common/hexstr.hpp>
|
||||
#include <openvpn/common/hash.hpp>
|
||||
#include <openvpn/addr/ipv4.hpp>
|
||||
#include <openvpn/addr/iperr.hpp>
|
||||
|
||||
@ -535,9 +534,10 @@ namespace openvpn {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
std::size_t hashval() const
|
||||
template <typename HASH>
|
||||
void hash(HASH& h) const
|
||||
{
|
||||
return Hash::value(u.u32[0], u.u32[1], u.u32[2], u.u32[3]);
|
||||
h(u.bytes, sizeof(u.bytes));
|
||||
}
|
||||
|
||||
#ifdef OPENVPN_IP_IMMUTABLE
|
||||
@ -825,6 +825,4 @@ namespace openvpn {
|
||||
}
|
||||
}
|
||||
|
||||
OPENVPN_HASH_METHOD(openvpn::IPv6::Addr, hashval);
|
||||
|
||||
#endif // OPENVPN_ADDR_IPV6_H
|
||||
|
@ -167,10 +167,21 @@ namespace openvpn {
|
||||
return prefix_len == other.prefix_len && addr == other.addr;
|
||||
}
|
||||
|
||||
template <typename HASH>
|
||||
void hash(HASH& h) const
|
||||
{
|
||||
addr.hash(h);
|
||||
h(prefix_len);
|
||||
}
|
||||
|
||||
#ifdef HAVE_CITYHASH
|
||||
std::size_t hash_value() const
|
||||
{
|
||||
return Hash::value(addr, prefix_len);
|
||||
HashSizeT h;
|
||||
hash(h);
|
||||
return h.value();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename ADDR>
|
||||
@ -253,8 +264,10 @@ namespace openvpn {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_CITYHASH
|
||||
OPENVPN_HASH_METHOD(openvpn::IP::Route, hash_value);
|
||||
OPENVPN_HASH_METHOD(openvpn::IP::Route4, hash_value);
|
||||
OPENVPN_HASH_METHOD(openvpn::IP::Route6, hash_value);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -22,11 +22,12 @@
|
||||
#ifndef OPENVPN_COMMON_HASH_H
|
||||
#define OPENVPN_COMMON_HASH_H
|
||||
|
||||
#include <cstring> // for std::strlen
|
||||
#include <string>
|
||||
#include <cstdint> // for std::uint32_t, uint64_t
|
||||
#include <functional>
|
||||
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/hexstr.hpp>
|
||||
|
||||
#define OPENVPN_HASH_METHOD(T, meth) \
|
||||
namespace std { \
|
||||
@ -40,79 +41,152 @@
|
||||
}; \
|
||||
}
|
||||
|
||||
#ifdef HAVE_CITYHASH
|
||||
|
||||
#ifdef OPENVPN_HASH128_CRC
|
||||
#include <citycrc.h>
|
||||
#define OPENVPN_HASH128 ::CityHashCrc128WithSeed
|
||||
#else
|
||||
#include <city.h>
|
||||
#define OPENVPN_HASH128 ::CityHash128WithSeed
|
||||
#endif
|
||||
|
||||
#if SIZE_MAX == 0xFFFFFFFF
|
||||
#define HashSizeT Hash32
|
||||
#elif SIZE_MAX == 0xFFFFFFFFFFFFFFFF
|
||||
#define HashSizeT Hash64
|
||||
#else
|
||||
#error "Unrecognized SIZE_MAX"
|
||||
#endif
|
||||
|
||||
namespace openvpn {
|
||||
namespace Hash {
|
||||
|
||||
void combine_data(std::size_t& seed, const void *data, std::size_t size);
|
||||
class Hash128
|
||||
{
|
||||
public:
|
||||
Hash128() : hashval(0,0) {}
|
||||
|
||||
template <class T>
|
||||
inline void combine(std::size_t& seed, const T& v)
|
||||
void operator()(const void *data, const std::size_t size)
|
||||
{
|
||||
std::hash<T> hasher;
|
||||
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||
hashval = OPENVPN_HASH128((const char *)data, size, hashval);
|
||||
}
|
||||
|
||||
inline void combine(std::size_t& seed, const char *str)
|
||||
void operator()(const std::string& str)
|
||||
{
|
||||
combine_data(seed, str, std::strlen(str));
|
||||
(*this)(str.c_str(), str.length());
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
inline void combine(std::size_t& seed, const T& first, Args... args)
|
||||
{
|
||||
combine(seed, first);
|
||||
combine(seed, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
inline std::size_t value(Args... args)
|
||||
{
|
||||
std::size_t hash = 0;
|
||||
combine(hash, args...);
|
||||
return hash;
|
||||
}
|
||||
|
||||
// A hasher that combines a data hash with a stateful seed.
|
||||
template <typename T>
|
||||
class InitialSeed
|
||||
inline void operator()(const T& obj)
|
||||
{
|
||||
public:
|
||||
InitialSeed(std::size_t seed) : seed_(seed) {}
|
||||
|
||||
std::size_t operator()(const T& obj) const
|
||||
{
|
||||
std::size_t seed = seed_;
|
||||
combine(seed, obj);
|
||||
return seed;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t seed_;
|
||||
};
|
||||
|
||||
inline void combine_data(std::size_t& seed, const void *data, std::size_t size)
|
||||
{
|
||||
while (size >= sizeof(std::uint32_t))
|
||||
{
|
||||
combine(seed, static_cast<const std::uint32_t*>(data)[0]);
|
||||
data = static_cast<const std::uint8_t*>(data) + sizeof(std::uint32_t);
|
||||
size -= sizeof(std::uint32_t);
|
||||
}
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
combine(seed, static_cast<const std::uint8_t*>(data)[0]);
|
||||
break;
|
||||
case 2:
|
||||
combine(seed, static_cast<const std::uint16_t*>(data)[0]);
|
||||
break;
|
||||
case 3:
|
||||
combine(seed, static_cast<const std::uint16_t*>(data)[0]);
|
||||
combine(seed, static_cast<const std::uint8_t*>(data)[2]);
|
||||
break;
|
||||
}
|
||||
static_assert(std::is_pod<T>::value, "Hash128: POD type required");
|
||||
(*this)(&obj, sizeof(obj));
|
||||
}
|
||||
}
|
||||
|
||||
std::uint64_t high() const
|
||||
{
|
||||
return hashval.second;
|
||||
}
|
||||
|
||||
std::uint64_t low() const
|
||||
{
|
||||
return hashval.first;
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
return render_hex_number(high()) + render_hex_number(low());
|
||||
}
|
||||
|
||||
private:
|
||||
uint128 hashval;
|
||||
};
|
||||
|
||||
class Hash64
|
||||
{
|
||||
public:
|
||||
Hash64(const std::uint64_t init_hashval=0)
|
||||
: hashval(init_hashval)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const void *data, const std::size_t size)
|
||||
{
|
||||
hashval = ::CityHash64WithSeed((const char *)data, size, hashval);
|
||||
}
|
||||
|
||||
void operator()(const std::string& str)
|
||||
{
|
||||
(*this)(str.c_str(), str.length());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void operator()(const T& obj)
|
||||
{
|
||||
static_assert(std::is_pod<T>::value, "Hash64: POD type required");
|
||||
(*this)(&obj, sizeof(obj));
|
||||
}
|
||||
|
||||
std::uint64_t value() const
|
||||
{
|
||||
return hashval;
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
return render_hex_number(hashval);
|
||||
}
|
||||
|
||||
private:
|
||||
std::uint64_t hashval;
|
||||
};
|
||||
|
||||
class Hash32
|
||||
{
|
||||
public:
|
||||
Hash32(const std::uint32_t init_hashval=0)
|
||||
: hashval(init_hashval)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const void *data, const std::size_t size)
|
||||
{
|
||||
hashval = hash_combine(::CityHash32((const char *)data, size), hashval);
|
||||
}
|
||||
|
||||
void operator()(const std::string& str)
|
||||
{
|
||||
(*this)(str.c_str(), str.length());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void operator()(const T& obj)
|
||||
{
|
||||
static_assert(std::is_pod<T>::value, "Hash64: POD type required");
|
||||
(*this)(&obj, sizeof(obj));
|
||||
}
|
||||
|
||||
std::uint32_t value() const
|
||||
{
|
||||
return hashval;
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
return render_hex_number(hashval);
|
||||
}
|
||||
|
||||
private:
|
||||
static std::uint32_t hash_combine(const std::uint32_t h1,
|
||||
const std::uint32_t h2)
|
||||
{
|
||||
return h1 ^ (h2 + 0x9e3779b9 + (h1<<6) + (h1>>2));
|
||||
}
|
||||
|
||||
std::uint32_t hashval;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -42,6 +42,7 @@ if [ -z "$1" ]; then
|
||||
echo " LZ4=1 -- build with LZ4 compression library"
|
||||
echo " LZ4_SYS=1 -- build with system LZ4 compression library"
|
||||
echo " SNAP=1 -- build with Snappy compression library"
|
||||
echo " CITY=1 -- build with Cityhash hash library"
|
||||
echo " JAVA=1 -- build with JVM"
|
||||
echo ' EXTRA_CPP="foo1.cpp foo2.cpp" -- add extra .cpp files'
|
||||
for s in $(enum_build_extras) ; do
|
||||
@ -213,6 +214,12 @@ if [ "$SNAP" = "1" ]; then
|
||||
CPPFLAGS="$CPPFLAGS -DHAVE_SNAPPY"
|
||||
fi
|
||||
|
||||
# Cityhash
|
||||
if [ "$CITY" = "1" ]; then
|
||||
LIBS="$LIBS -lcityhash"
|
||||
CPPFLAGS="$CPPFLAGS -DHAVE_CITYHASH"
|
||||
fi
|
||||
|
||||
# JVM
|
||||
if [ "$JAVA" = "1" ]; then
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
|
Loading…
Reference in New Issue
Block a user