GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/util/prng.h
Date: 2025-06-22 02:36:02
Exec Total Coverage
Lines: 22 22 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 <cassert>
15 #include <cmath>
16 #include <cstdlib>
17 #include <limits> // NOLINT
18
19
20 #ifdef CVMFS_NAMESPACE_GUARD
21 namespace CVMFS_NAMESPACE_GUARD {
22 #endif
23
24 /**
25 * Pseudo Random Number Generator. See: TAoCP, volume 2
26 */
27 class Prng {
28 public:
29 // Cannot throw an exception
30 16309050 Prng() throw() { state_ = 0; }
31
32 16017343 void InitSeed(const uint64_t seed) { state_ = seed; }
33
34 290656 void InitLocaltime() {
35 struct timeval tv_now;
36 290656 const int retval = gettimeofday(&tv_now, NULL);
37
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 290700 times.
290700 assert(retval == 0);
38 290700 state_ = tv_now.tv_usec;
39 290700 }
40
41 /**
42 * Returns random number in [0..boundary-1]
43 */
44 43938441461 uint32_t Next(const uint64_t boundary) {
45 43938441461 state_ = a * state_ + c;
46 43938441461 const double scaled_val = static_cast<double>(state_) *
47 43938441461 static_cast<double>(boundary) /
48 static_cast<double>(18446744073709551616.0);
49 43938441461 return static_cast<uint32_t>(static_cast<uint64_t>(scaled_val) % boundary);
50 }
51
52 /**
53 * Returns random double in range [0, 1]
54 */
55 400000 double NextDouble() {
56 400000 state_ = a * state_ + c;
57 400000 const double unit_val = static_cast<double>(state_) /
58 static_cast<double>(18446744073709551616.0);
59 400000 return unit_val;
60 }
61 /**
62 * Returns normally distributed random numbers
63 * with mean 0 and variance 1 using the
64 * Box-Muller transform algorithm
65 */
66 200000 double NextNormal() {
67 double z, u1, u2;
68 200000 const double pi = atan(1) * 4;
69 200000 u1 = NextDouble();
70 200000 u2 = NextDouble();
71 200000 z = sqrt(-2.0 * log(u1)) * cos(2 * pi * u2);
72 200000 return z;
73 }
74
75
76 private:
77 // Magic numbers from MMIX
78 // static const uint64_t m = 2^64;
79 static const uint64_t a = 6364136223846793005LLU;
80 static const uint64_t c = 1442695040888963407LLU;
81 uint64_t state_;
82 }; // class Prng
83
84 #ifdef CVMFS_NAMESPACE_GUARD
85 } // namespace CVMFS_NAMESPACE_GUARD
86 #endif
87
88 #endif // CVMFS_UTIL_PRNG_H_
89