use super::CompressionLevel;
use crate::common::MAX_BLOCK_SIZE;
use alloc::vec;
use alloc::vec::Vec;
#[derive(Debug, Default)]
pub(crate) struct SeenContentGrid {
slots: Vec<u64>,
tags: Vec<u8>,
epoch: u16,
frame_offset: u64,
repeat_until: u64,
asked: bool,
}
#[derive(Debug, Default, Clone, Copy)]
pub(crate) struct SeenSample {
fingerprint: u16,
epoch: u16,
at_step: u32,
}
impl SeenSample {
#[inline]
fn pack(self) -> u64 {
u64::from(self.fingerprint)
| (u64::from(self.epoch) << 16)
| (u64::from(self.at_step) << 32)
}
#[inline]
fn unpack(word: u64) -> Self {
Self {
fingerprint: word as u16,
epoch: (word >> 16) as u16,
at_step: (word >> 32) as u32,
}
}
}
impl SeenContentGrid {
const SLOTS: usize = 64 * 1024;
const MIN_SLOTS: usize = 64;
const KEY_LEN: usize = 8;
const RECORD_STEP: usize = 512;
const PROBE_RUN: usize = Self::RECORD_STEP;
const PROBE_RUNS_PER_BLOCK: usize = 2;
const REBASE_RETAIN_BYTES: u64 = 1 << 31;
const STICKY_REACH: u64 = 2 * MAX_BLOCK_SIZE as u64;
pub(crate) fn reset_for_frame(&mut self) {
self.retire_for_rebase();
}
#[cold]
#[inline(never)]
fn rebase_offsets(&mut self) {
let step = Self::RECORD_STEP as u64;
let retain_steps = Self::REBASE_RETAIN_BYTES / step;
let Some(base_steps) = (self.frame_offset / step).checked_sub(retain_steps) else {
return;
};
let base_steps32 = u32::try_from(base_steps).unwrap_or(u32::MAX);
for (word, tag) in self.slots.iter_mut().zip(self.tags.iter_mut()) {
let mut held = SeenSample::unpack(*word);
if held.epoch != self.epoch {
continue;
}
match held.at_step.checked_sub(base_steps32) {
Some(rebased) => {
held.at_step = rebased;
*word = held.pack();
}
None => {
*word = 0;
*tag = 0;
}
}
}
self.frame_offset -= base_steps * step;
self.repeat_until = self.repeat_until.saturating_sub(base_steps * step);
}
fn retire_for_rebase(&mut self) {
self.epoch = self.epoch.wrapping_add(1);
if self.epoch == 0 {
self.slots.fill(0);
self.tags.fill(0);
self.epoch = 1;
}
self.frame_offset = 0;
self.repeat_until = 0;
self.asked = false;
}
pub(crate) fn heap_size(&self) -> usize {
self.slots.capacity() * core::mem::size_of::<u64>() + self.tags.capacity()
}
#[inline]
unsafe fn key_at(&self, block_ptr: *const u8, at: usize, mask: usize) -> (usize, u16, u8) {
let key = unsafe { block_ptr.add(at).cast::<u64>().read_unaligned() }.to_le();
let mixed = Self::avalanche(key);
(
(mixed >> 32) as usize & mask,
(mixed as u16) | 1,
(mixed >> 16) as u8 | 1,
)
}
#[inline]
unsafe fn probe_key(&self, block_ptr: *const u8, at: usize, reach: u64, mask: usize) -> bool {
let (slot, fingerprint, tag) = unsafe { self.key_at(block_ptr, at, mask) };
if unsafe { *self.tags.get_unchecked(slot) } != tag {
return false;
}
let held = SeenSample::unpack(unsafe { *self.slots.get_unchecked(slot) });
let here = self.frame_offset + at as u64;
if held.epoch != self.epoch || held.fingerprint != fingerprint {
return false;
}
let recorded = u64::from(held.at_step) * Self::RECORD_STEP as u64;
debug_assert!(recorded <= here, "a record ahead of the probe that met it");
here.checked_sub(recorded)
.is_some_and(|apart| apart <= reach)
}
#[inline]
unsafe fn record_key(&mut self, block_ptr: *const u8, at: usize, mask: usize) {
let (slot, fingerprint, tag) = unsafe { self.key_at(block_ptr, at, mask) };
unsafe {
*self.tags.get_unchecked_mut(slot) = tag;
}
let here = self.frame_offset + at as u64;
debug_assert!(
here.is_multiple_of(Self::RECORD_STEP as u64),
"records sit on the grid, which is what lets the offset be stored in steps",
);
let packed = SeenSample {
fingerprint,
epoch: self.epoch,
at_step: (here / Self::RECORD_STEP as u64) as u32,
}
.pack();
unsafe {
*self.slots.get_unchecked_mut(slot) = packed;
}
}
pub(crate) fn record_and_report_repeat(&mut self, block: &[u8], window_size: usize) -> bool {
self.asked = true;
self.take_block(block, window_size, true)
}
pub(crate) fn record_searched(&mut self, block: &[u8], window_size: usize) {
if !self.asked {
self.skip_block(block.len());
return;
}
self.take_block(block, window_size, false);
}
pub(crate) fn skip_recording(&mut self, len: usize) {
self.skip_block(len);
}
#[inline]
fn skip_block(&mut self, len: usize) {
let step = Self::RECORD_STEP as u64;
if (self.frame_offset + len as u64) / step > u64::from(u32::MAX) {
self.rebase_offsets();
}
self.frame_offset += len as u64;
}
fn take_block(&mut self, block: &[u8], window_size: usize, probe: bool) -> bool {
if block.len() < Self::KEY_LEN {
self.skip_block(block.len());
return false;
}
let wanted = Self::slots_for(window_size);
if self.slots.len() < wanted {
self.slots = vec![0u64; wanted];
self.tags = vec![0u8; wanted];
self.epoch = self.epoch.max(1);
}
let mask = self.slots.len() - 1;
let reach = if window_size == 0 {
u64::MAX
} else {
window_size as u64
};
let mut repeat = false;
let last = block.len() - Self::KEY_LEN;
let block_ptr = block.as_ptr();
let step = Self::RECORD_STEP as u64;
let run = Self::PROBE_RUN.min((block.len() / 16).max(8));
if (self.frame_offset + last as u64) / step > u64::from(u32::MAX) {
self.rebase_offsets();
}
let mut abs = self.frame_offset.next_multiple_of(step);
let block_end = self.frame_offset + last as u64;
let runs = Self::PROBE_RUNS_PER_BLOCK;
for idx in 0..runs {
let start = idx * (block.len() / runs);
let until = self.frame_offset + start as u64;
while abs < until && abs <= block_end {
let at = (abs - self.frame_offset) as usize;
unsafe { self.record_key(block_ptr, at, mask) };
abs += step;
}
if probe && !repeat && (self.frame_offset != 0 || start != 0) {
let end = (start + run).min(last + 1);
for at in start..end {
if unsafe { self.probe_key(block_ptr, at, reach, mask) } {
repeat = true;
break;
}
}
}
if idx + 1 == runs {
while abs <= block_end {
let at = (abs - self.frame_offset) as usize;
unsafe { self.record_key(block_ptr, at, mask) };
abs += step;
}
}
}
self.frame_offset += block.len() as u64;
if repeat {
self.repeat_until = self.frame_offset + Self::STICKY_REACH;
}
repeat || self.frame_offset <= self.repeat_until
}
fn slots_for(window_size: usize) -> usize {
if window_size == 0 {
return Self::SLOTS;
}
let records = (window_size / Self::RECORD_STEP).max(1) as u64;
let wanted = (records * 4).next_power_of_two();
(wanted as usize).clamp(Self::MIN_SLOTS, Self::SLOTS)
}
#[inline]
fn avalanche(key: u64) -> u64 {
let mut z = key.wrapping_mul(0x9E37_79B9_7F4A_7C15);
z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
z ^ (z >> 31)
}
}
pub(crate) const RAW_FAST_PATH_MIN_BLOCK_LEN: usize = 512;
pub(crate) const RAW_FAST_PATH_MAX_SAMPLE_LEN: usize = 4096;
pub(crate) const RAW_FAST_PATH_MIN_SAMPLE_LEN: usize = 32;
pub(crate) const RAW_SKIP_INDEX_STEP: usize = 512;
const RAW_FAST_PATH_MAX_WINDOW_LOG: u8 = 23;
const RAW_FAST_PATH_MAX_WINDOW_SIZE_BYTES: u64 = 1u64 << RAW_FAST_PATH_MAX_WINDOW_LOG;
const INCOMPRESSIBLE_REPEAT_TABLE_BITS: usize = 10;
const INCOMPRESSIBLE_REPEAT_TABLE_LEN: usize = 1 << INCOMPRESSIBLE_REPEAT_TABLE_BITS;
const INCOMPRESSIBLE_REPEAT_OCCUPANCY_WORDS: usize = INCOMPRESSIBLE_REPEAT_TABLE_LEN / 64;
const INCOMPRESSIBLE_REPEAT_HASH_MULT: u32 = 0x9E37_79B1;
const INCOMPRESSIBLE_MIN_DISTINCT_BYTES: usize = 200;
const INCOMPRESSIBLE_MAX_SYMBOL_DIVISOR: usize = 24;
const INCOMPRESSIBLE_REPEAT_DIVISOR: usize = 64;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
struct StrictProbeSelection {
probe_len: usize,
tail_start: Option<usize>,
mid_start: Option<usize>,
}
impl StrictProbeSelection {
#[inline]
const fn reuses_full_block_classification(self) -> bool {
self.tail_start.is_none()
}
}
#[inline]
fn select_strict_probes(block_len: usize) -> StrictProbeSelection {
let probe_len = RAW_FAST_PATH_MIN_BLOCK_LEN.min(block_len);
if probe_len == block_len {
StrictProbeSelection {
probe_len,
tail_start: None,
mid_start: None,
}
} else {
let tail_start = block_len - probe_len;
if tail_start < probe_len {
StrictProbeSelection {
probe_len,
tail_start: None,
mid_start: None,
}
} else if tail_start < 2 * probe_len {
StrictProbeSelection {
probe_len,
tail_start: Some(tail_start),
mid_start: None,
}
} else {
StrictProbeSelection {
probe_len,
tail_start: Some(tail_start),
mid_start: Some(tail_start / 2),
}
}
}
}
#[inline]
pub(crate) fn compression_level_allows_raw_fast_path(
level: CompressionLevel,
window_size: u64,
) -> bool {
match level {
CompressionLevel::Fastest
| CompressionLevel::Default
| CompressionLevel::Better
| CompressionLevel::Best
| CompressionLevel::Level(_) => window_size <= RAW_FAST_PATH_MAX_WINDOW_SIZE_BYTES,
CompressionLevel::Uncompressed => false,
}
}
#[inline]
fn scan_sample_region(
sample: &[u8],
counts: &mut [u32; 256],
repeat_table: &mut [u32; INCOMPRESSIBLE_REPEAT_TABLE_LEN],
repeat_occupied: &mut [u64; INCOMPRESSIBLE_REPEAT_OCCUPANCY_WORDS],
repeats: &mut usize,
repeat_guard: usize,
) -> bool {
let mut idx = 0usize;
let len = sample.len();
while idx + 4 <= len {
counts[sample[idx] as usize] += 1;
counts[sample[idx + 1] as usize] += 1;
counts[sample[idx + 2] as usize] += 1;
counts[sample[idx + 3] as usize] += 1;
let quad = u32::from_le_bytes([
sample[idx],
sample[idx + 1],
sample[idx + 2],
sample[idx + 3],
]);
let slot = (quad.wrapping_mul(INCOMPRESSIBLE_REPEAT_HASH_MULT) as usize)
>> (32 - INCOMPRESSIBLE_REPEAT_TABLE_BITS);
let word = slot / 64;
let bit = 1_u64 << (slot % 64);
let occupied = (repeat_occupied[word] & bit) != 0;
if occupied && repeat_table[slot] == quad {
*repeats += 1;
if *repeats > repeat_guard {
return true;
}
} else {
repeat_table[slot] = quad;
repeat_occupied[word] |= bit;
}
idx += 4;
}
while idx < len {
counts[sample[idx] as usize] += 1;
idx += 1;
}
false
}
#[inline]
pub(crate) fn block_looks_incompressible(block: &[u8]) -> bool {
if block.len() < RAW_FAST_PATH_MIN_BLOCK_LEN {
return false;
}
sample_looks_incompressible(block)
}
#[inline]
pub(crate) fn block_looks_incompressible_strict(block: &[u8]) -> bool {
if block.len() < RAW_FAST_PATH_MIN_BLOCK_LEN {
return false;
}
if !sample_looks_incompressible(block) {
return false;
}
let selection = select_strict_probes(block.len());
if selection.reuses_full_block_classification() {
return true;
}
let probe_len = selection.probe_len;
let tail_start = selection
.tail_start
.expect("strict probe tail_start should be present for split probes");
let head = &block[..probe_len];
let tail = &block[tail_start..tail_start + probe_len];
if let Some(mid_start) = selection.mid_start {
let mid = &block[mid_start..mid_start + probe_len];
sample_looks_incompressible(head)
&& sample_looks_incompressible(mid)
&& sample_looks_incompressible(tail)
} else {
sample_looks_incompressible(head) && sample_looks_incompressible(tail)
}
}
#[inline]
fn sample_looks_incompressible(block: &[u8]) -> bool {
sample_looks_incompressible_capped(block, RAW_FAST_PATH_MAX_SAMPLE_LEN)
}
fn sample_looks_incompressible_capped(block: &[u8], max_sample_len: usize) -> bool {
let sample_len = block.len().min(max_sample_len);
if sample_len < RAW_FAST_PATH_MIN_SAMPLE_LEN {
return false;
}
let mut regions: [&[u8]; 3] = [&[], &[], &[]];
let region_count = if sample_len == block.len() {
regions[0] = block;
1
} else {
let head_len = sample_len / 3;
let mid_len = sample_len / 3;
let tail_len = sample_len - head_len - mid_len;
let mid_start = (block.len() - mid_len) / 2;
regions[0] = &block[..head_len];
regions[1] = &block[mid_start..mid_start + mid_len];
regions[2] = &block[block.len() - tail_len..];
3
};
let max_symbol_guard = sample_len / INCOMPRESSIBLE_MAX_SYMBOL_DIVISOR;
let total_quads: usize = regions[..region_count].iter().map(|r| r.len() / 4).sum();
let repeat_guard = total_quads / INCOMPRESSIBLE_REPEAT_DIVISOR + 1;
let mut counts = [0u32; 256];
let mut repeat_table = [u32::MAX; INCOMPRESSIBLE_REPEAT_TABLE_LEN];
let mut repeat_occupied = [0_u64; INCOMPRESSIBLE_REPEAT_OCCUPANCY_WORDS];
let mut repeats = 0usize;
for region in ®ions[..region_count] {
if scan_sample_region(
region,
&mut counts,
&mut repeat_table,
&mut repeat_occupied,
&mut repeats,
repeat_guard,
) {
return false;
}
}
let distinct = counts.iter().filter(|&&count| count != 0).count();
let max_freq = counts.iter().copied().max().unwrap_or(0) as usize;
distinct >= INCOMPRESSIBLE_MIN_DISTINCT_BYTES
&& max_freq <= max_symbol_guard
&& repeats <= repeat_guard
}
#[cfg(test)]
mod tests;