xxhash_rust/
const_xxh32.rs1use core::mem;
4
5use crate::xxh32_common::*;
6
7#[inline(always)]
8const fn read_u32(input: &[u8], cursor: usize) -> u32 {
9 input[cursor] as u32 | (input[cursor + 1] as u32) << 8 | (input[cursor + 2] as u32) << 16 | (input[cursor + 3] as u32) << 24
10}
11
12const fn finalize(mut input: u32, data: &[u8], mut cursor: usize) -> u32 {
13 let mut len = data.len() - cursor;
14
15 while len >= 4 {
16 input = input.wrapping_add(
17 read_u32(data, cursor).wrapping_mul(PRIME_3)
18 );
19 cursor += mem::size_of::<u32>();
20 len -= mem::size_of::<u32>();
21 input = input.rotate_left(17).wrapping_mul(PRIME_4);
22 }
23
24 while len > 0 {
25 input = input.wrapping_add((data[cursor] as u32).wrapping_mul(PRIME_5));
26 cursor += mem::size_of::<u8>();
27 len -= mem::size_of::<u8>();
28 input = input.rotate_left(11).wrapping_mul(PRIME_1);
29 }
30
31 avalanche(input)
32}
33
34pub const fn xxh32(input: &[u8], seed: u32) -> u32 {
36 let mut result = input.len() as u32;
37 let mut cursor = 0;
38
39 if input.len() >= CHUNK_SIZE {
40 let mut v1 = seed.wrapping_add(PRIME_1).wrapping_add(PRIME_2);
41 let mut v2 = seed.wrapping_add(PRIME_2);
42 let mut v3 = seed;
43 let mut v4 = seed.wrapping_sub(PRIME_1);
44
45 loop {
46 v1 = round(v1, read_u32(input, cursor));
47 cursor += mem::size_of::<u32>();
48 v2 = round(v2, read_u32(input, cursor));
49 cursor += mem::size_of::<u32>();
50 v3 = round(v3, read_u32(input, cursor));
51 cursor += mem::size_of::<u32>();
52 v4 = round(v4, read_u32(input, cursor));
53 cursor += mem::size_of::<u32>();
54
55 if (input.len() - cursor) < CHUNK_SIZE {
56 break;
57 }
58 }
59
60 result = result.wrapping_add(
61 v1.rotate_left(1).wrapping_add(
62 v2.rotate_left(7).wrapping_add(
63 v3.rotate_left(12).wrapping_add(
64 v4.rotate_left(18)
65 )
66 )
67 )
68 );
69 } else {
70 result = result.wrapping_add(seed.wrapping_add(PRIME_5));
71 }
72
73 finalize(result, input, cursor)
74}