#![cfg(feature = "dhat-heap")]
use std::hint::black_box;
use xocomil::body::{BodyKind, BodyReader, UNLIMITED_BODY_SIZE};
#[global_allocator]
static ALLOC: dhat::Alloc = dhat::Alloc;
#[test]
fn body_reader_hot_paths_zero_alloc() {
let _profiler = dhat::Profiler::builder().testing().build();
let cl_body = vec![b'x'; 1024];
let chunked_body = build_chunks(&[b"hello world".as_slice(); 16]);
let prefetch_body = build_chunks(&[b"hello world".as_slice()]);
let split = prefetch_body.len() / 2;
let baseline = dhat::HeapStats::get();
for _ in 0..100 {
let mut src: &[u8] = black_box(&cl_body);
let mut r = BodyReader::new(
&mut src,
b"",
BodyKind::ContentLength(1024),
UNLIMITED_BODY_SIZE,
);
let mut sink = std::io::sink();
std::io::copy(&mut r, &mut sink).unwrap();
}
for _ in 0..100 {
let mut src: &[u8] = black_box(&chunked_body);
let mut r = BodyReader::new(&mut src, b"", BodyKind::Chunked, UNLIMITED_BODY_SIZE);
let mut sink = std::io::sink();
std::io::copy(&mut r, &mut sink).unwrap();
}
for _ in 0..100 {
let mut src: &[u8] = black_box(&prefetch_body[split..]);
let mut r = BodyReader::new(
&mut src,
black_box(&prefetch_body[..split]),
BodyKind::Chunked,
UNLIMITED_BODY_SIZE,
);
let mut sink = std::io::sink();
std::io::copy(&mut r, &mut sink).unwrap();
}
let stats = dhat::HeapStats::get();
dhat::assert_eq!(stats.total_blocks - baseline.total_blocks, 0);
dhat::assert_eq!(stats.total_bytes - baseline.total_bytes, 0);
}
fn build_chunks(payloads: &[&[u8]]) -> Vec<u8> {
let mut out = Vec::new();
for p in payloads {
out.extend_from_slice(format!("{:x}\r\n", p.len()).as_bytes());
out.extend_from_slice(p);
out.extend_from_slice(b"\r\n");
}
out.extend_from_slice(b"0\r\n\r\n");
out
}