Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/zlib-rs/src/deflate/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 5 kB image not shown  

Quelle  hash_calc.rs

  Sprache: Rust
 

#![forbid(unsafe_code)]

use crate::deflate::{State, HASH_SIZE, STD_MIN_MATCH};

#[derive(Debug, Clone, Copy)]
pub enum HashCalcVariant {
    Standard,
    Roll,
}

impl HashCalcVariant {
    /// Use rolling hash for deflate_slow algorithm with level 9. It allows us to
    /// properly lookup different hash chains to speed up longest_match search.
    pub fn for_max_chain_length(max_chain_length: u16) -> Self {
        if max_chain_length > 1024 {
            HashCalcVariant::Roll
        } else {
            HashCalcVariant::Standard
        }
    }
}

pub struct StandardHashCalc;

impl StandardHashCalc {
    const HASH_CALC_OFFSET: usize = 0;

    const HASH_CALC_MASK: u32 = (HASH_SIZE - 1as u32;

    fn hash_calc(_: u32, val: u32) -> u32 {
        const HASH_SLIDE: u32 = 16;
        val.wrapping_mul(2654435761) >> HASH_SLIDE
    }

    pub fn update_hash(h: u32, val: u32) -> u32 {
        Self::hash_calc(h, val) & Self::HASH_CALC_MASK
    }

    #[inline]
    pub fn quick_insert_string(state: &mut State, string: usize) -> u16 {
        let slice = &state.window.filled()[string + Self::HASH_CALC_OFFSET..];
        let val = u32::from_le_bytes(slice[..4].try_into().unwrap());

        Self::quick_insert_value(state, string, val)
    }

    #[inline]
    pub fn quick_insert_value(state: &mut State, string: usize, val: u32) -> u16 {
        let hm = Self::update_hash(0, val) as usize;

        let head = state.head.as_slice()[hm];
        if head != string as u16 {
            state.prev.as_mut_slice()[string & state.w_mask()] = head;
            state.head.as_mut_slice()[hm] = string as u16;
        }

        head
    }

    pub fn insert_string(state: &mut State, string: usize, count: usize) {
        let slice = &state.window.filled()[string + Self::HASH_CALC_OFFSET..];

        // it can happen that insufficient bytes are initialized
        // .take(count) generates worse assembly
        let slice = &slice[..Ord::min(slice.len(), count + 3)];

        let w_mask = state.w_mask();
        for (i, w) in slice.windows(4).enumerate() {
            let idx = string as u16 + i as u16;

            let val = u32::from_le_bytes(w.try_into().unwrap());

            let hm = Self::update_hash(0, val) as usize;

            let head = state.head.as_slice()[hm];
            if head != idx {
                state.prev.as_mut_slice()[idx as usize & w_mask] = head;
                state.head.as_mut_slice()[hm] = idx;
            }
        }
    }
}

pub struct RollHashCalc;

impl RollHashCalc {
    const HASH_CALC_OFFSET: usize = STD_MIN_MATCH - 1;

    const HASH_CALC_MASK: u32 = (1 << 15) - 1;

    fn hash_calc(h: u32, val: u32) -> u32 {
        const HASH_SLIDE: u32 = 5;
        (h << HASH_SLIDE) ^ val
    }

    pub fn update_hash(h: u32, val: u32) -> u32 {
        Self::hash_calc(h, val) & Self::HASH_CALC_MASK
    }

    pub fn quick_insert_string(state: &mut State, string: usize) -> u16 {
        let val = state.window.filled()[string + Self::HASH_CALC_OFFSET] as u32;

        state.ins_h = Self::hash_calc(state.ins_h, val);
        state.ins_h &= Self::HASH_CALC_MASK;

        let hm = state.ins_h as usize;

        let head = state.head.as_slice()[hm];
        if head != string as u16 {
            state.prev.as_mut_slice()[string & state.w_mask()] = head;
            state.head.as_mut_slice()[hm] = string as u16;
        }

        head
    }

    pub fn insert_string(state: &mut State, string: usize, count: usize) {
        let slice = &state.window.filled()[string + Self::HASH_CALC_OFFSET..][..count];

        let w_mask = state.w_mask();
        for (i, val) in slice.iter().copied().enumerate() {
            let idx = string as u16 + i as u16;

            state.ins_h = Self::hash_calc(state.ins_h, val as u32);
            state.ins_h &= Self::HASH_CALC_MASK;
            let hm = state.ins_h as usize;

            let head = state.head.as_slice()[hm];
            if head != idx {
                state.prev.as_mut_slice()[idx as usize & w_mask] = head;
                state.head.as_mut_slice()[hm] = idx;
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn roll_hash_calc() {
        assert_eq!(RollHashCalc::hash_calc(256593), 82173);
        assert_eq!(RollHashCalc::hash_calc(1663710), 532394);
        assert_eq!(RollHashCalc::hash_calc(8106100), 259364);
        assert_eq!(RollHashCalc::hash_calc(29988101), 959717);
        assert_eq!(RollHashCalc::hash_calc(944598), 302274);
        assert_eq!(RollHashCalc::hash_calc(7362117), 235573);
        assert_eq!(RollHashCalc::hash_calc(6197103), 198343);
        assert_eq!(RollHashCalc::hash_calc(173532), 55488);
        assert_eq!(RollHashCalc::hash_calc(2272061), 727101);
        assert_eq!(RollHashCalc::hash_calc(620532), 198528);
        assert_eq!(RollHashCalc::hash_calc(3826117), 122421);
        assert_eq!(RollHashCalc::hash_calc(24117101), 771781);
    }

    #[test]
    fn standard_hash_calc() {
        assert_eq!(StandardHashCalc::hash_calc(0807411760), 65468);
        assert_eq!(StandardHashCalc::hash_calc(0540024864), 42837);
        assert_eq!(StandardHashCalc::hash_calc(0538980384), 33760);
        assert_eq!(StandardHashCalc::hash_calc(0775430176), 8925);
        assert_eq!(StandardHashCalc::hash_calc(0941629472), 42053);
    }
}

Messung V0.5 in Prozent
C=93 H=97 G=94

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.