pub use linflate::deflate_scan::{FlushBoundary, find_all_flushes, find_next_flush};
#[cfg(target_arch = "x86_64")]
use linflate::deflate_scan::{find_next_flush_avx2, find_next_flush_avx512};
use linflate::deflate_scan::find_next_flush_scalar;
pub fn find_next_valid_flush(buf: &[u8], from: usize) -> Option<FlushBoundary> {
#[cfg(target_arch = "x86_64")]
{
if std::arch::is_x86_feature_detected!("avx512bw") {
return unsafe { find_next_valid_flush_avx512(buf, from) };
}
if std::arch::is_x86_feature_detected!("avx2") {
return unsafe { find_next_valid_flush_avx2(buf, from) };
}
}
find_next_valid_flush_scalar(buf, from)
}
#[inline]
fn find_next_valid_flush_scalar(buf: &[u8], from: usize) -> Option<FlushBoundary> {
let mut pos = from;
while let Some(b) = find_next_flush_scalar(buf, pos) {
if crate::speculative::probe_decode(&buf[b.start..]) {
return Some(b);
}
pos = b.start;
}
None
}
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "avx2")]
unsafe fn find_next_valid_flush_avx2(buf: &[u8], from: usize) -> Option<FlushBoundary> {
let mut pos = from;
while let Some(b) = unsafe { find_next_flush_avx2(buf, pos) } {
if crate::speculative::probe_decode(&buf[b.start..]) {
return Some(b);
}
pos = b.start;
}
None
}
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "avx512bw")]
unsafe fn find_next_valid_flush_avx512(buf: &[u8], from: usize) -> Option<FlushBoundary> {
let mut pos = from;
while let Some(b) = unsafe { find_next_flush_avx512(buf, pos) } {
if crate::speculative::probe_decode(&buf[b.start..]) {
return Some(b);
}
pos = b.start;
}
None
}
pub fn split_boundaries_parallel(buf: &[u8], n_splits: usize) -> Vec<FlushBoundary> {
if n_splits <= 1 || buf.len() < 8 {
return Vec::new();
}
let mut found: Vec<Option<FlushBoundary>> = gatling::gatling_forkjoin::gatling_for_each(n_splits - 1, 0, |k| {
let i = k + 1;
let nominal = buf.len() * i / n_splits;
find_next_valid_flush(buf, nominal)
});
let mut result: Vec<FlushBoundary> = found.drain(..).flatten().collect();
result.sort_by_key(|b| b.start);
result.dedup_by_key(|b| b.start);
result
}
#[cfg(test)]
mod tests {
use super::*;
fn make_flush_marker() -> Vec<u8> {
vec![0x00, 0x00, 0x00, 0xFF, 0xFF]
}
#[test]
fn raw_scan_finds_synthetic_boundary() {
let mut buf = vec![0xAA; 64];
buf.extend_from_slice(&make_flush_marker());
buf.extend_from_slice(&[0xBB; 64]);
let b = find_next_flush(&buf, 0).unwrap();
assert_eq!(b.start, 69);
}
#[test]
fn parallel_split_rejects_false_positive() {
let mut buf = vec![0xAA; 64];
buf.extend_from_slice(&make_flush_marker());
buf.extend_from_slice(&[0xBB; 64]);
let boundaries = split_boundaries_parallel(&buf, 4);
assert!(boundaries.is_empty());
}
}