zstd-complete 0.1.0

A pure Rust Zstandard compressor and decompressor with bounded streaming I/O
Documentation
use alloc::{vec, vec::Vec};

use super::super::cctx_params::LdmParameters;

#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub(crate) struct LdmEntry {
    pub(crate) offset: u32,
    pub(crate) checksum: u32,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) struct LdmHashTable {
    hash_table: Vec<LdmEntry>,
    bucket_offsets: Vec<u8>,
    bucket_size_log: u32,
}

impl LdmHashTable {
    pub(crate) fn new(params: LdmParameters) -> Self {
        debug_assert!(params.hash_log >= params.bucket_size_log);
        let table_entries = 1_usize << params.hash_log;
        let bucket_count = 1_usize << (params.hash_log - params.bucket_size_log);

        Self {
            hash_table: vec![LdmEntry::default(); table_entries],
            bucket_offsets: vec![0; bucket_count],
            bucket_size_log: params.bucket_size_log,
        }
    }

    pub(crate) fn insert_entry(&mut self, hash: usize, entry: LdmEntry) {
        debug_assert!(hash < self.bucket_offsets.len());
        let bucket_size = 1_usize << self.bucket_size_log;
        let offset = self.bucket_offsets[hash] as usize;
        let table_index = (hash << self.bucket_size_log) + offset;

        self.hash_table[table_index] = entry;
        self.bucket_offsets[hash] = ((offset + 1) & (bucket_size - 1)) as u8;
    }

    pub(crate) fn bucket(&self, hash: usize) -> &[LdmEntry] {
        debug_assert!(hash < self.bucket_offsets.len());
        let bucket_size = 1_usize << self.bucket_size_log;
        let bucket_start = hash << self.bucket_size_log;
        &self.hash_table[bucket_start..bucket_start + bucket_size]
    }

    pub(crate) fn bucket_offset(&self, hash: usize) -> u8 {
        self.bucket_offsets[hash]
    }

    pub(crate) fn table_len(&self) -> usize {
        self.hash_table.len()
    }

    pub(crate) fn bucket_count(&self) -> usize {
        self.bucket_offsets.len()
    }
}