1
#pragma once
2

            
3
#include <limits>
4
#include <memory>
5
#include <string>
6

            
7
#include "envoy/common/pure.h"
8

            
9
#include "source/common/common/interval_value.h"
10

            
11
namespace Envoy {
12
namespace Random {
13

            
14
/**
15
 * Random number generator. Implementations should be thread safe.
16
 */
17
class RandomGenerator {
18
public:
19
331247
  virtual ~RandomGenerator() = default;
20

            
21
  using result_type = uint64_t; // NOLINT(readability-identifier-naming)
22

            
23
  /**
24
   * @return uint64_t a new random number.
25
   */
26
  virtual result_type random() PURE;
27

            
28
  /*
29
   * @return the smallest value that `operator()` may return. The value is
30
   * strictly less than `max()`.
31
   */
32
  constexpr static result_type min() noexcept { return std::numeric_limits<result_type>::min(); };
33

            
34
  /*
35
   * @return the largest value that `operator()` may return. The value is
36
   * strictly greater than `min()`.
37
   */
38
100009
  constexpr static result_type max() noexcept { return std::numeric_limits<result_type>::max(); };
39

            
40
  /*
41
   * @return a value in the closed interval `[min(), max()]`. Has amortized
42
   * constant complexity.
43
   */
44
1413290
  result_type operator()() { return result_type(random()); };
45

            
46
  /**
47
   * @return std::string containing uuid4 of 36 char length.
48
   * for example, 7c25513b-0466-4558-a64c-12c6704f37ed
49
   */
50
  virtual std::string uuid() PURE;
51

            
52
  /**
53
   * @return a random boolean value, with probability `p` equaling true.
54
   */
55
293219
  bool bernoulli(UnitFloat p) {
56
293219
    if (p == UnitFloat::min()) {
57
193165
      return false;
58
293167
    } else if (p == UnitFloat::max()) {
59
47
      return true;
60
47
    }
61
100007
    return random() < static_cast<result_type>(p.value() * static_cast<float>(max()));
62
293219
  }
63
};
64

            
65
using RandomGeneratorPtr = std::unique_ptr<RandomGenerator>;
66

            
67
} // namespace Random
68
} // namespace Envoy