-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprng.h
61 lines (52 loc) · 1.29 KB
/
prng.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
* This file is part of the CernVM File System.
*
* A simple linear congruential pseudo number generator. Thread-safe since
* there is no global state like with random().
*/
#ifndef CVMFS_PRNG_H_
#define CVMFS_PRNG_H_
#include <sys/time.h>
#include <stdint.h>
#include <cassert>
#include <cstdlib>
#ifdef CVMFS_NAMESPACE_GUARD
namespace CVMFS_NAMESPACE_GUARD {
#endif
/**
* * Pseudo Random Number Generator. See: TAoCP, volume 2
* */
class Prng {
public:
Prng() {
state_ = 0;
}
void InitSeed(const uint64_t seed) {
state_ = seed;
}
void InitLocaltime() {
struct timeval tv_now;
int retval = gettimeofday(&tv_now, NULL);
assert(retval == 0);
state_ = tv_now.tv_usec;
}
/**
* * Returns random number in [0..boundary-1]
* */
uint32_t Next(const uint64_t boundary) {
state_ = a*state_ + c;
double scaled_val = double(state_) * double(boundary) /
double(18446744073709551616.0);
return (uint32_t)scaled_val % boundary;
}
private:
// Magic numbers from MMIX
// //static const uint64_t m = 2^64;
static const uint64_t a = 6364136223846793005LLU;
static const uint64_t c = 1442695040888963407LLU;
uint64_t state_;
}; // class Prng
#ifdef CVMFS_NAMESPACE_GUARD
}
#endif
#endif // CVMFS_PRNG_H_