1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 //! A simple fast pseudorandom implementation, ranges from 0 to usize::MAX 15 //! Reference: xorshift* <https://dl.acm.org/doi/10.1145/2845077> 16 17 use std::cell::Cell; 18 use std::collections::hash_map::RandomState; 19 use std::hash::{BuildHasher, Hasher}; 20 use std::num::Wrapping; 21 22 /// Generates a fast random ranging from 0 to usize::MAX 23 /// 24 /// # Examples 25 /// ```rust 26 /// use ylong_runtime::fastrand::fast_random; 27 /// let rand = fast_random(); 28 /// assert!(rand <= u64::MAX); 29 /// ``` fast_random() -> u6430pub fn fast_random() -> u64 { 31 thread_local! { 32 static RNG: Cell<Wrapping<u64>> = Cell::new(Wrapping(seed())); 33 } 34 35 RNG.with(|rng| { 36 let mut s = rng.get(); 37 s ^= s >> 12; 38 s ^= s << 25; 39 s ^= s >> 27; 40 rng.set(s); 41 s.0.wrapping_mul(0x2545_f491_4f6c_dd1d) 42 }) 43 } 44 seed() -> u6445fn seed() -> u64 { 46 let seed = RandomState::new(); 47 48 let mut out = 0; 49 let mut count = 0; 50 while out == 0 { 51 count += 1; 52 let mut hasher = seed.build_hasher(); 53 hasher.write_usize(count); 54 out = hasher.finish(); 55 } 56 out 57 } 58