11use 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+
11681201impl Default for TrieBuilder {
11691202 fn default ( ) -> Self {
11701203 Self :: new ( )
0 commit comments