reifydb_runtime/context/rng/
mod.rs1use std::sync::Arc;
5
6use getrandom::fill as getrandom_fill;
7use rand::{Rng as RandRng, RngExt, SeedableRng, rngs::StdRng};
8
9use crate::sync::mutex::Mutex;
10
11#[derive(Clone, Default)]
12pub enum Rng {
13 #[default]
14 Os,
15
16 Seeded(SeededRng),
17}
18
19impl Rng {
20 pub fn seeded(seed: u64) -> Self {
21 Rng::Seeded(SeededRng::new(seed))
22 }
23
24 pub fn bytes_16(&self) -> [u8; 16] {
25 match self {
26 Rng::Os => {
27 let mut buf = [0u8; 16];
28 getrandom_fill(&mut buf).expect("getrandom failed");
29 buf
30 }
31 Rng::Seeded(seeded) => {
32 let mut buf = [0u8; 16];
33 let mut rng = seeded.inner.lock();
34 rng.fill_bytes(&mut buf);
35 buf
36 }
37 }
38 }
39
40 pub fn bytes_32(&self) -> [u8; 32] {
41 match self {
42 Rng::Os => {
43 let mut buf = [0u8; 32];
44 getrandom_fill(&mut buf).expect("getrandom failed");
45 buf
46 }
47 Rng::Seeded(seeded) => {
48 let mut buf = [0u8; 32];
49 let mut rng = seeded.inner.lock();
50 rng.fill_bytes(&mut buf);
51 buf
52 }
53 }
54 }
55
56 pub fn bytes_10(&self) -> [u8; 10] {
57 match self {
58 Rng::Os => {
59 let mut buf = [0u8; 10];
60 getrandom_fill(&mut buf).expect("getrandom failed");
61 buf
62 }
63 Rng::Seeded(seeded) => {
64 let mut buf = [0u8; 10];
65 let mut rng = seeded.inner.lock();
66 rng.fill_bytes(&mut buf);
67 buf
68 }
69 }
70 }
71
72 pub fn infra_bytes_10(&self) -> [u8; 10] {
73 match self {
74 Rng::Os => {
75 let mut buf = [0u8; 10];
76 getrandom_fill(&mut buf).expect("getrandom failed");
77 buf
78 }
79 Rng::Seeded(seeded) => {
80 let mut buf = [0u8; 10];
81 let mut rng = seeded.infra.lock();
82 rng.fill_bytes(&mut buf);
83 buf
84 }
85 }
86 }
87
88 pub fn infra_bytes_32(&self) -> [u8; 32] {
89 match self {
90 Rng::Os => {
91 let mut buf = [0u8; 32];
92 getrandom_fill(&mut buf).expect("getrandom failed");
93 buf
94 }
95 Rng::Seeded(seeded) => {
96 let mut buf = [0u8; 32];
97 let mut rng = seeded.infra.lock();
98 rng.fill_bytes(&mut buf);
99 buf
100 }
101 }
102 }
103
104 pub fn infra_u64_inclusive(&self, max_inclusive: u64) -> u64 {
105 if max_inclusive == 0 {
106 return 0;
107 }
108 match self {
109 Rng::Os => {
110 let mut buf = [0u8; 8];
111 getrandom_fill(&mut buf).expect("getrandom failed");
112 let raw = u64::from_le_bytes(buf);
113 if max_inclusive == u64::MAX {
114 raw
115 } else {
116 raw % (max_inclusive + 1)
117 }
118 }
119 Rng::Seeded(seeded) => {
120 let mut rng = seeded.infra.lock();
121 rng.random_range(0..=max_inclusive)
122 }
123 }
124 }
125}
126
127#[derive(Clone)]
128pub struct SeededRng {
129 inner: Arc<Mutex<StdRng>>,
130
131 infra: Arc<Mutex<StdRng>>,
132}
133
134impl SeededRng {
135 pub fn new(seed: u64) -> Self {
136 Self {
137 inner: Arc::new(Mutex::new(StdRng::seed_from_u64(seed))),
138 infra: Arc::new(Mutex::new(StdRng::seed_from_u64(seed ^ 0x5A5A5A5A5A5A5A5A))),
139 }
140 }
141}