1 use crate::header::{Entry, HeaderMap, OccupiedEntry};
2 
3 // xor-shift
4 #[cfg(not(target_arch = "wasm32"))]
fast_random() -> u645 pub(crate) fn fast_random() -> u64 {
6     use std::cell::Cell;
7     use std::collections::hash_map::RandomState;
8     use std::hash::{BuildHasher, Hasher};
9     use std::num::Wrapping;
10 
11     thread_local! {
12         static RNG: Cell<Wrapping<u64>> = Cell::new(Wrapping(seed()));
13     }
14 
15     fn seed() -> u64 {
16         let seed = RandomState::new();
17 
18         let mut out = 0;
19         let mut cnt = 0;
20         while out == 0 {
21             cnt += 1;
22             let mut hasher = seed.build_hasher();
23             hasher.write_usize(cnt);
24             out = hasher.finish();
25         }
26         out
27     }
28 
29     RNG.with(|rng| {
30         let mut n = rng.get();
31         debug_assert_ne!(n.0, 0);
32         n ^= n >> 12;
33         n ^= n << 25;
34         n ^= n >> 27;
35         rng.set(n);
36         n.0.wrapping_mul(0x2545_f491_4f6c_dd1d)
37     })
38 }
39 
replace_headers(dst: &mut HeaderMap, src: HeaderMap)40 pub(crate) fn replace_headers(dst: &mut HeaderMap, src: HeaderMap) {
41     // IntoIter of HeaderMap yields (Option<HeaderName>, HeaderValue).
42     // The first time a name is yielded, it will be Some(name), and if
43     // there are more values with the same name, the next yield will be
44     // None.
45 
46     let mut prev_entry: Option<OccupiedEntry<_>> = None;
47     for (key, value) in src {
48         match key {
49             Some(key) => match dst.entry(key) {
50                 Entry::Occupied(mut e) => {
51                     e.insert(value);
52                     prev_entry = Some(e);
53                 }
54                 Entry::Vacant(e) => {
55                     let e = e.insert_entry(value);
56                     prev_entry = Some(e);
57                 }
58             },
59             None => match prev_entry {
60                 Some(ref mut entry) => {
61                     entry.append(value);
62                 }
63                 None => unreachable!("HeaderMap::into_iter yielded None first"),
64             },
65         }
66     }
67 }
68