Skip to content

Commit 7d26e72

Browse files
committed
refactor: use better PRNG
1 parent c380ec8 commit 7d26e72

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

src/dictionary/trie.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::{
2+
cell::Cell,
23
cmp::Ordering,
34
collections::VecDeque,
45
error::Error,
@@ -1150,10 +1151,7 @@ impl DictionaryBuilder for TrieBuilder {
11501151

11511152
fn build(&mut self, path: &Path) -> Result<(), BuildDictionaryError> {
11521153
let mut tmpname = path.to_path_buf();
1153-
let pseudo_random = SystemTime::now()
1154-
.duration_since(SystemTime::UNIX_EPOCH)
1155-
.map(|du| du.subsec_micros())
1156-
.unwrap_or_default();
1154+
let pseudo_random = rand();
11571155
tmpname.set_file_name(format!("chewing-{pseudo_random}.dat"));
11581156
let database = File::create(&tmpname)?;
11591157
let mut writer = BufWriter::new(&database);
@@ -1165,6 +1163,41 @@ impl DictionaryBuilder for TrieBuilder {
11651163
}
11661164
}
11671165

1166+
// xoshiro256** PRNG
1167+
//
1168+
// Ref: <https://en.wikipedia.org/wiki/Xorshift#xoshiro256**>
1169+
fn rand() -> u64 {
1170+
thread_local! {
1171+
static PRNG_STATE: Cell<[u64; 4]> = SystemTime::now()
1172+
.duration_since(SystemTime::UNIX_EPOCH)
1173+
.map(|du| {
1174+
Cell::new([
1175+
du.as_secs(),
1176+
du.subsec_millis() as u64,
1177+
du.subsec_micros() as u64,
1178+
du.subsec_nanos() as u64,
1179+
])
1180+
})
1181+
.unwrap_or_default();
1182+
}
1183+
fn rol64(x: u64, k: u32) -> u64 {
1184+
x.wrapping_shl(k) | x.wrapping_shr(64 - k)
1185+
}
1186+
PRNG_STATE.with(|state| {
1187+
let mut s = state.get();
1188+
let result = rol64(s[1].wrapping_mul(5), 7).wrapping_mul(9);
1189+
let t = s[1].wrapping_shl(17);
1190+
s[2] ^= s[0];
1191+
s[3] ^= s[1];
1192+
s[1] ^= s[2];
1193+
s[0] ^= s[3];
1194+
s[2] ^= t;
1195+
s[3] = rol64(s[3], 45);
1196+
state.set(s);
1197+
result
1198+
})
1199+
}
1200+
11681201
impl Default for TrieBuilder {
11691202
fn default() -> Self {
11701203
Self::new()

0 commit comments

Comments
 (0)