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