Coverage Report

Created: 2026-03-26 07:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rkyv-0.8.15/src/hash.rs
Line
Count
Source
1
//! Hashing support for archived hash maps and sets.
2
3
use core::{
4
    hash::{Hash, Hasher},
5
    ops::BitXor as _,
6
};
7
8
use crate::primitive::{FixedIsize, FixedUsize};
9
10
/// A cross-platform 64-bit implementation of fxhash.
11
#[derive(Default)]
12
pub struct FxHasher64 {
13
    hash: u64,
14
}
15
16
#[inline]
17
0
fn hash_word(hash: u64, word: u64) -> u64 {
18
    const ROTATE: u32 = 5;
19
    const SEED: u64 = 0x51_7c_c1_b7_27_22_0a_95;
20
21
0
    hash.rotate_left(ROTATE).bitxor(word).wrapping_mul(SEED)
22
0
}
Unexecuted instantiation: rkyv::hash::hash_word
Unexecuted instantiation: rkyv::hash::hash_word
23
24
#[inline]
25
0
fn hash_bytes(mut hash: u64, bytes: &[u8]) -> u64 {
26
0
    let ptr = bytes.as_ptr();
27
0
    let len = bytes.len();
28
29
0
    for i in 0..len / 8 {
30
0
        let bytes = unsafe { ptr.cast::<[u8; 8]>().add(i).read_unaligned() };
31
0
        hash = hash_word(hash, u64::from_le_bytes(bytes));
32
0
    }
33
34
0
    if bytes.len() & 4 != 0 {
35
0
        let bytes = unsafe {
36
0
            ptr.add(bytes.len() & !7).cast::<[u8; 4]>().read_unaligned()
37
0
        };
38
0
        hash = hash_word(hash, u32::from_le_bytes(bytes).into());
39
0
    }
40
41
0
    if bytes.len() & 2 != 0 {
42
0
        let bytes = unsafe {
43
0
            ptr.add(bytes.len() & !3).cast::<[u8; 2]>().read_unaligned()
44
0
        };
45
0
        hash = hash_word(hash, u16::from_le_bytes(bytes).into());
46
0
    }
47
48
0
    if bytes.len() & 1 != 0 {
49
0
        let byte = unsafe { ptr.add(len - 1).read() };
50
0
        hash = hash_word(hash, byte.into());
51
0
    }
52
53
0
    hash
54
0
}
Unexecuted instantiation: rkyv::hash::hash_bytes
Unexecuted instantiation: rkyv::hash::hash_bytes
55
56
impl Hasher for FxHasher64 {
57
    #[inline]
58
0
    fn write(&mut self, bytes: &[u8]) {
59
0
        self.hash = hash_bytes(self.hash, bytes);
60
0
    }
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write
61
62
    #[inline]
63
0
    fn finish(&self) -> u64 {
64
0
        self.hash
65
0
    }
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::finish
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::finish
66
67
    #[inline]
68
0
    fn write_u8(&mut self, i: u8) {
69
0
        self.hash = hash_word(self.hash, i as u64);
70
0
    }
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_u8
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_u8
71
72
    #[inline]
73
0
    fn write_u16(&mut self, i: u16) {
74
0
        self.hash = hash_word(self.hash, i as u64);
75
0
    }
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_u16
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_u16
76
77
    #[inline]
78
0
    fn write_u32(&mut self, i: u32) {
79
0
        self.hash = hash_word(self.hash, i as u64);
80
0
    }
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_u32
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_u32
81
82
    #[inline]
83
0
    fn write_u64(&mut self, i: u64) {
84
0
        self.hash = hash_word(self.hash, i);
85
0
    }
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_u64
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_u64
86
87
    #[inline]
88
0
    fn write_u128(&mut self, i: u128) {
89
0
        let bytes = i.to_ne_bytes();
90
0
        let ptr = bytes.as_ptr().cast::<[u8; 8]>();
91
        #[cfg(target_endian = "little")]
92
0
        let (first, second) = (unsafe { ptr.read_unaligned() }, unsafe {
93
0
            ptr.add(1).read_unaligned()
94
0
        });
95
        #[cfg(target_endian = "big")]
96
        let (first, second) =
97
            (unsafe { ptr.add(1).read_unaligned() }, unsafe {
98
                ptr.read_unaligned()
99
            });
100
0
        self.hash = hash_word(
101
0
            hash_word(self.hash, u64::from_ne_bytes(first)),
102
0
            u64::from_ne_bytes(second),
103
0
        );
104
0
    }
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_u128
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_u128
105
106
    #[inline]
107
0
    fn write_usize(&mut self, i: usize) {
108
0
        self.hash = hash_word(self.hash, i as FixedUsize as u64);
109
0
    }
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_usize
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_usize
110
111
    #[inline]
112
0
    fn write_isize(&mut self, i: isize) {
113
0
        self.write_i64(i as FixedIsize as i64)
114
0
    }
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_isize
Unexecuted instantiation: <rkyv::hash::FxHasher64 as core::hash::Hasher>::write_isize
115
}
116
117
/// Hashes the given value with the default value of the specified `Hasher`.
118
0
pub fn hash_value<Q, H: Hasher + Default>(value: &Q) -> u64
119
0
where
120
0
    Q: Hash + ?Sized,
121
{
122
0
    let mut state = H::default();
123
0
    value.hash(&mut state);
124
0
    state.finish()
125
0
}
Unexecuted instantiation: rkyv::hash::hash_value::<wasmer_types::module::ImportKey, rkyv::hash::FxHasher64>
Unexecuted instantiation: rkyv::hash::hash_value::<alloc::string::String, rkyv::hash::FxHasher64>
Unexecuted instantiation: rkyv::hash::hash_value::<_, _>
Unexecuted instantiation: rkyv::hash::hash_value::<wasmer_types::module::ImportKey, rkyv::hash::FxHasher64>
Unexecuted instantiation: rkyv::hash::hash_value::<alloc::string::String, rkyv::hash::FxHasher64>
Unexecuted instantiation: rkyv::hash::hash_value::<_, _>