lzip_parallel/
deflate_scan.rs1use linflate::deflate_scan::find_next_flush;
8use rayon::prelude::*;
9
10pub use linflate::deflate_scan::{FlushBoundary, find_all_flushes};
11
12pub fn split_boundaries_parallel(buf: &[u8], n_splits: usize) -> Vec<FlushBoundary> {
18 if n_splits <= 1 || buf.len() < 8 {
19 return Vec::new();
20 }
21
22 let mut found: Vec<Option<FlushBoundary>> = crate::thread_pool().install(|| {
23 (1..n_splits)
24 .into_par_iter()
25 .map(|i| {
26 let nominal = buf.len() * i / n_splits;
27 find_next_flush(buf, nominal)
28 })
29 .collect()
30 });
31
32 let mut result: Vec<FlushBoundary> = found.drain(..).flatten().collect();
33 result.sort_by_key(|b| b.start);
34 result.dedup_by_key(|b| b.start);
35 result
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41
42 fn make_flush_marker() -> Vec<u8> {
43 vec![0x00, 0x00, 0x00, 0xFF, 0xFF]
44 }
45
46 #[test]
47 fn split_finds_markers() {
48 let mut buf = Vec::new();
49 buf.extend_from_slice(&[0xAA; 32]);
50 buf.extend_from_slice(&make_flush_marker());
51 buf.extend_from_slice(&[0xBB; 32]);
52 let all = find_all_flushes(&buf);
54 assert_eq!(all.len(), 1);
55 assert_eq!(all[0].start, 37);
56 }
57}