sthash 0.2.16

A very fast cryptographic hash function for large data.
Documentation
use std::io::Cursor;

use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};

use super::*;

impl Hasher {
    #[inline(always)]
    pub(crate) fn hash(&self, out: &mut Vec<u8>, msg: &[u8]) {
        let mut cursor = Cursor::new(msg);
        let mut remaining = msg.len();
        let (mut s0, mut s1, mut s2, mut s3) = (0u64, 0u64, 0u64, 0u64);
        let mut key_ = &self.key[..];

        debug_assert_eq!(NH_NUM_PASSES, 4);
        debug_assert_eq!(remaining % NH_MESSAGE_UNIT, 0);
        debug_assert!(key_.len() >= remaining / NH_MESSAGE_UNIT * 16);
        while remaining > 0 {
            let m0 = cursor.read_u32::<LittleEndian>().unwrap();
            let m1 = cursor.read_u32::<LittleEndian>().unwrap();
            let m2 = cursor.read_u32::<LittleEndian>().unwrap();
            let m3 = cursor.read_u32::<LittleEndian>().unwrap();

            s0 = s0.wrapping_add(
                ((m0.wrapping_add(key_[0])) as u64).wrapping_mul(m2.wrapping_add(key_[2]) as u64),
            );
            s1 = s1.wrapping_add(
                ((m0.wrapping_add(key_[4])) as u64).wrapping_mul(m2.wrapping_add(key_[6]) as u64),
            );
            s2 = s2.wrapping_add(
                ((m0.wrapping_add(key_[8])) as u64).wrapping_mul(m2.wrapping_add(key_[10]) as u64),
            );
            s3 = s3.wrapping_add(
                ((m0.wrapping_add(key_[12])) as u64).wrapping_mul(m2.wrapping_add(key_[14]) as u64),
            );
            s0 = s0.wrapping_add(
                ((m1.wrapping_add(key_[1])) as u64).wrapping_mul(m3.wrapping_add(key_[3]) as u64),
            );
            s1 = s1.wrapping_add(
                ((m1.wrapping_add(key_[5])) as u64).wrapping_mul(m3.wrapping_add(key_[7]) as u64),
            );
            s2 = s2.wrapping_add(
                ((m1.wrapping_add(key_[9])) as u64).wrapping_mul(m3.wrapping_add(key_[11]) as u64),
            );
            s3 = s3.wrapping_add(
                ((m1.wrapping_add(key_[13])) as u64).wrapping_mul(m3.wrapping_add(key_[15]) as u64),
            );

            key_ = &key_[NH_MESSAGE_UNIT / 4..];
            remaining -= NH_MESSAGE_UNIT;
        }
        out.write_u64::<LittleEndian>(s0).unwrap();
        out.write_u64::<LittleEndian>(s1).unwrap();
        out.write_u64::<LittleEndian>(s2).unwrap();
        out.write_u64::<LittleEndian>(s3).unwrap();
    }
}