• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
fast_random() -> u6422 pub fn fast_random() -> u64 {
23     thread_local! {
24         static RNG: Cell<Wrapping<u64>> = Cell::new(Wrapping(seed()));
25     }
26 
27     RNG.with(|rng| {
28         let mut s = rng.get();
29         s ^= s >> 12;
30         s ^= s << 25;
31         s ^= s >> 27;
32         rng.set(s);
33         s.0.wrapping_mul(0x2545_f491_4f6c_dd1d)
34     })
35 }
36 
seed() -> u6437 fn seed() -> u64 {
38     let seed = RandomState::new();
39 
40     let mut out = 0;
41     let mut count = 0;
42     while out == 0 {
43         count += 1;
44         let mut hasher = seed.build_hasher();
45         hasher.write_usize(count);
46         out = hasher.finish();
47     }
48     out
49 }
50