GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/util/prng.h
Date: 2024-04-28 02:33:07
Exec Total Coverage
Lines: 26 26 100.0%
Branches: 1 2 50.0%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 *
4 * A simple linear congruential pseudo number generator. Thread-safe since
5 * there is no global state like with random().
6 */
7
8 #ifndef CVMFS_UTIL_PRNG_H_
9 #define CVMFS_UTIL_PRNG_H_
10
11 #include <stdint.h>
12 #include <sys/time.h>
13
14 #include <limits> // NOLINT
15
16 #include <cassert>
17 #include <cmath>
18 #include <cstdlib>
19
20
21 #ifdef CVMFS_NAMESPACE_GUARD
22 namespace CVMFS_NAMESPACE_GUARD {
23 #endif
24
25 /**
26 * Pseudo Random Number Generator. See: TAoCP, volume 2
27 */
28 class Prng {
29 public:
30 // Cannot throw an exception
31 2251925 Prng() throw() {
32 2251925 state_ = 0;
33 2251925 }
34
35 2000590 void InitSeed(const uint64_t seed) {
36 2000590 state_ = seed;
37 2000590 }
38
39 251320 void InitLocaltime() {
40 struct timeval tv_now;
41 251320 int retval = gettimeofday(&tv_now, NULL);
42
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 251335 times.
251335 assert(retval == 0);
43 251335 state_ = tv_now.tv_usec;
44 251335 }
45
46 /**
47 * Returns random number in [0..boundary-1]
48 */
49 2173947231 uint32_t Next(const uint64_t boundary) {
50 2173947231 state_ = a*state_ + c;
51 2173947231 double scaled_val =
52 2173947231 static_cast<double>(state_) * static_cast<double>(boundary) /
53 static_cast<double>(18446744073709551616.0);
54 2173947231 return static_cast<uint32_t>(static_cast<uint64_t>(scaled_val) % boundary);
55 }
56
57 /**
58 * Returns random double in range [0, 1]
59 */
60 200000 double NextDouble() {
61 200000 state_ = a*state_ + c;
62 200000 double unit_val = static_cast<double>(state_) /
63 static_cast<double>(18446744073709551616.0);
64 200000 return unit_val;
65 }
66 /**
67 * Returns normally distributed random numbers
68 * with mean 0 and variance 1 using the
69 * Box-Muller transform algorithm
70 */
71 100000 double NextNormal() {
72 double z, u1, u2;
73 100000 double pi = atan(1) * 4;
74 100000 u1 = NextDouble();
75 100000 u2 = NextDouble();
76 100000 z = sqrt(-2.0 * log(u1)) * cos(2 * pi * u2);
77 100000 return z;
78 }
79
80
81 private:
82 // Magic numbers from MMIX
83 // static const uint64_t m = 2^64;
84 static const uint64_t a = 6364136223846793005LLU;
85 static const uint64_t c = 1442695040888963407LLU;
86 uint64_t state_;
87 }; // class Prng
88
89 #ifdef CVMFS_NAMESPACE_GUARD
90 } // namespace CVMFS_NAMESPACE_GUARD
91 #endif
92
93 #endif // CVMFS_UTIL_PRNG_H_
94