Use common inline functions for splitting/combining uint128 to/from two uint64 values
This commit is contained in:
parent
b16bf00a10
commit
1bda001b8c
4 changed files with 44 additions and 34 deletions
|
|
@ -29,8 +29,8 @@ namespace fc {
|
|||
inline void pack( Stream& s, const uint128_t& v, uint32_t _max_depth )
|
||||
{
|
||||
boost::endian::little_uint64_buf_at hilo[2];
|
||||
hilo[0] = static_cast<uint64_t>(v >> 64);
|
||||
hilo[1] = static_cast<uint64_t>(v & 0xffffffffffffffffULL);
|
||||
hilo[0] = uint128_hi64( v );
|
||||
hilo[1] = uint128_lo64( v );
|
||||
s.write( hilo[0].data(), sizeof(hilo) );
|
||||
}
|
||||
template<typename Stream>
|
||||
|
|
@ -38,9 +38,7 @@ namespace fc {
|
|||
{
|
||||
boost::endian::little_uint64_buf_at hilo[2];
|
||||
s.read( (char*) hilo, sizeof(hilo) );
|
||||
v = hilo[0].value();
|
||||
v <<= 64;
|
||||
v += hilo[1].value();
|
||||
v = uint128( hilo[0].value(), hilo[1].value() );
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
|
|
|
|||
|
|
@ -33,6 +33,13 @@ namespace fc {
|
|||
using int128_t = __int128_t;
|
||||
using uint128_t = __uint128_t;
|
||||
|
||||
inline uint64_t uint128_lo64(const uint128_t x) {
|
||||
return static_cast<uint64_t>(x & 0xffffffffffffffffULL);
|
||||
}
|
||||
inline uint64_t uint128_hi64(const uint128_t x) {
|
||||
return static_cast<uint64_t>( x >> 64 );
|
||||
}
|
||||
|
||||
} // namespace fc
|
||||
|
||||
#else // __SIZEOF_INT128__
|
||||
|
|
@ -44,6 +51,21 @@ namespace fc {
|
|||
using boost::multiprecision::int128_t;
|
||||
using boost::multiprecision::uint128_t;
|
||||
|
||||
inline uint64_t uint128_lo64(const uint128_t& x) {
|
||||
return static_cast<uint64_t>(x & 0xffffffffffffffffULL);
|
||||
}
|
||||
inline uint64_t uint128_hi64(const uint128_t& x) {
|
||||
return static_cast<uint64_t>( x >> 64 );
|
||||
}
|
||||
|
||||
} // namespace fc
|
||||
|
||||
#endif // __SIZEOF_INT128__
|
||||
|
||||
namespace fc {
|
||||
|
||||
inline uint128_t uint128( const uint64_t hi, const uint64_t lo ) {
|
||||
return ( uint128_t(hi) << 64 ) + lo;
|
||||
}
|
||||
|
||||
} // namespace fc
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ void aes_encoder::init( const fc::sha256& key, const uint128_t& init_value )
|
|||
* IV size for *most* modes is the same as the block size. For AES this
|
||||
* is 128 bits */
|
||||
boost::endian::little_uint64_buf_t iv[2];
|
||||
iv[0] = static_cast<uint64_t>( init_value >> 64 );
|
||||
iv[1] = static_cast<uint64_t>( init_value & 0xffffffffffffffffULL );
|
||||
iv[0] = uint128_hi64( init_value );
|
||||
iv[1] = uint128_lo64( init_value );
|
||||
if(1 != EVP_EncryptInit_ex(my->ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)&key, (const unsigned char*)iv[0].data()))
|
||||
{
|
||||
FC_THROW_EXCEPTION( aes_exception, "error during aes 256 cbc encryption init",
|
||||
|
|
@ -122,8 +122,8 @@ void aes_decoder::init( const fc::sha256& key, const uint128_t& init_value )
|
|||
* IV size for *most* modes is the same as the block size. For AES this
|
||||
* is 128 bits */
|
||||
boost::endian::little_uint64_buf_t iv[2];
|
||||
iv[0] = static_cast<uint64_t>( init_value >> 64 );
|
||||
iv[1] = static_cast<uint64_t>( init_value & 0xffffffffffffffffULL );
|
||||
iv[0] = uint128_hi64( init_value );
|
||||
iv[1] = uint128_lo64( init_value );
|
||||
if(1 != EVP_DecryptInit_ex(my->ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)&key, (const unsigned char*)iv[0].data()))
|
||||
{
|
||||
FC_THROW_EXCEPTION( aes_exception, "error during aes 256 cbc encryption init",
|
||||
|
|
|
|||
|
|
@ -46,21 +46,14 @@ namespace fc {
|
|||
|
||||
using namespace std;
|
||||
|
||||
inline uint64_t Uint128Low64(const uint128_t& x) {
|
||||
return static_cast<uint64_t>(x & 0xffffffffffffffffULL);
|
||||
}
|
||||
inline uint64_t Uint128High64(const uint128_t& x) {
|
||||
return static_cast<uint64_t>( x >> 64 );
|
||||
}
|
||||
|
||||
// Hash 128 input bits down to 64 bits of output.
|
||||
// This is intended to be a reasonably good hash function.
|
||||
inline uint64_t Hash128to64(const uint128_t& x) {
|
||||
// Murmur-inspired hashing.
|
||||
const uint64_t kMul = 0x9ddfea08eb382d69ULL;
|
||||
uint64_t a = (Uint128Low64(x) ^ Uint128High64(x)) * kMul;
|
||||
uint64_t a = (uint128_lo64(x) ^ uint128_hi64(x)) * kMul;
|
||||
a ^= (a >> 47);
|
||||
uint64_t b = (Uint128High64(x) ^ a) * kMul;
|
||||
uint64_t b = (uint128_hi64(x) ^ a) * kMul;
|
||||
b ^= (b >> 47);
|
||||
b *= kMul;
|
||||
return b;
|
||||
|
|
@ -282,7 +275,7 @@ static uint64_t ShiftMix(uint64_t val) {
|
|||
}
|
||||
|
||||
static uint64_t HashLen16(uint64_t u, uint64_t v) {
|
||||
return Hash128to64( ( uint128_t(u) << 64 ) + v);
|
||||
return Hash128to64( uint128( u, v) );
|
||||
}
|
||||
|
||||
static uint64_t HashLen16(uint64_t u, uint64_t v, uint64_t mul) {
|
||||
|
|
@ -428,8 +421,8 @@ uint64_t CityHash64WithSeed(const char *s, size_t len, uint64_t seed) {
|
|||
// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
|
||||
// of any length representable in signed long. Based on City and Murmur.
|
||||
uint128_t CityMurmur(const char *s, size_t len, uint128_t seed) {
|
||||
uint64_t a = Uint128Low64(seed);
|
||||
uint64_t b = Uint128High64(seed);
|
||||
uint64_t a = uint128_lo64(seed);
|
||||
uint64_t b = uint128_hi64(seed);
|
||||
uint64_t c = 0;
|
||||
uint64_t d = 0;
|
||||
signed long l = len - 16;
|
||||
|
|
@ -454,7 +447,7 @@ uint128_t CityMurmur(const char *s, size_t len, uint128_t seed) {
|
|||
}
|
||||
a = HashLen16(a, c);
|
||||
b = HashLen16(d, b);
|
||||
return ( uint128_t(a ^ b) << 64 ) + HashLen16(b, a);
|
||||
return uint128( a ^ b, HashLen16(b, a) );
|
||||
}
|
||||
|
||||
uint128_t CityHash128WithSeed(const char *s, size_t len, uint128_t seed) {
|
||||
|
|
@ -465,8 +458,8 @@ uint128_t CityHash128WithSeed(const char *s, size_t len, uint128_t seed) {
|
|||
// We expect len >= 128 to be the common case. Keep 56 bytes of state:
|
||||
// v, w, x, y, and z.
|
||||
pair<uint64_t, uint64_t> v, w;
|
||||
uint64_t x = Uint128Low64(seed);
|
||||
uint64_t y = Uint128High64(seed);
|
||||
uint64_t x = uint128_lo64(seed);
|
||||
uint64_t y = uint128_hi64(seed);
|
||||
uint64_t z = len * k1;
|
||||
v.first = Rotate(y ^ k1, 49) * k1 + Fetch64(s);
|
||||
v.second = Rotate(v.first, 42) * k1 + Fetch64(s + 8);
|
||||
|
|
@ -516,15 +509,13 @@ uint128_t CityHash128WithSeed(const char *s, size_t len, uint128_t seed) {
|
|||
// different 56-byte-to-8-byte hashes to get a 16-byte final result.
|
||||
x = HashLen16(x, v.first);
|
||||
y = HashLen16(y + z, w.first);
|
||||
return ( uint128_t( HashLen16(x + v.second, w.second) + y ) << 64 )
|
||||
+ HashLen16(x + w.second, y + v.second);
|
||||
return uint128( HashLen16(x + v.second, w.second) + y, HashLen16(x + w.second, y + v.second) );
|
||||
}
|
||||
|
||||
uint128_t city_hash128(const char *s, size_t len) {
|
||||
return len >= 16 ?
|
||||
CityHash128WithSeed(s + 16, len - 16,
|
||||
( uint128_t( Fetch64(s) ) << 64 ) + Fetch64(s + 8) + k0) :
|
||||
CityHash128WithSeed(s, len, ( uint128_t(k0) << 64 ) + k1);
|
||||
CityHash128WithSeed( s + 16, len - 16, uint128( Fetch64(s), Fetch64(s + 8) + k0 ) ) :
|
||||
CityHash128WithSeed( s, len, uint128( k0, k1 ) );
|
||||
}
|
||||
|
||||
//#ifdef __SSE4_2__
|
||||
|
|
@ -648,10 +639,9 @@ uint128_t CityHashCrc128WithSeed(const char *s, size_t len, uint128_t seed) {
|
|||
} else {
|
||||
uint64_t result[4];
|
||||
CityHashCrc256(s, len, result);
|
||||
uint64_t u = Uint128High64(seed) + result[0];
|
||||
uint64_t v = Uint128Low64(seed) + result[1];
|
||||
return ( uint128_t( HashLen16(u, v + result[2]) ) << 64 )
|
||||
+ HashLen16(Rotate(v, 32), u * k0 + result[3]);
|
||||
uint64_t u = uint128_hi64(seed) + result[0];
|
||||
uint64_t v = uint128_lo64(seed) + result[1];
|
||||
return uint128( HashLen16(u, v + result[2]), HashLen16(Rotate(v, 32), u * k0 + result[3]) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -661,7 +651,7 @@ uint128_t city_hash_crc_128(const char *s, size_t len) {
|
|||
} else {
|
||||
uint64_t result[4];
|
||||
CityHashCrc256(s, len, result);
|
||||
return ( uint128_t(result[2]) << 64 ) + result[3];
|
||||
return uint128( result[2], result[3] );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue