memgraph/utils/random/xorshift.hpp
2015-06-28 11:43:52 +02:00

56 lines
1.3 KiB
C++

#ifndef MEMGRAPH_UTILS_RANDOM_XORSHIFT_HPP
#define MEMGRAPH_UTILS_RANDOM_XORSHIFT_HPP
#include <cstdlib>
#include <random>
namespace xorshift
{
static uint64_t s[2];
uint64_t avalance(uint64_t s)
{
// MurmurHash3 finalizer
s ^= s >> 33;
s *= 0xff51afd7ed558ccd;
s ^= s >> 33;
s *= 0xc4ceb9fe1a85ec53;
s ^= s >> 33;
return s;
}
void init()
{
// TODO
// not sure if this thread local means anything for other threads
// fix this!!!!
// use a slow, more complex rnd generator to initialize a fast one
// make sure to call this before requesting any random numbers!
std::random_device rd;
std::mt19937_64 gen(rd());
std::uniform_int_distribution<unsigned long long> dist;
// the number generated by MT can be full of zeros and xorshift
// doesn't like this so we use MurmurHash3 64bit finalizer to
// make it less biased
s[0] = avalance(dist(gen));
s[1] = avalance(dist(gen));
}
uint64_t next()
{
uint64_t s1 = s[0];
const uint64_t s0 = s[1];
s[0] = s0;
s1 ^= s1 << 23;
return (s[1] = (s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26))) + s0;
}
}
#endif