use std::collections::BTreeMap;
pub const ZSTD_LEVEL: i32 = 3;
pub struct Workload {
pub name: &'static str,
pub pairs: Vec<(Vec<u8>, Vec<u8>)>,
}
impl Workload {
pub fn bytes(&self) -> u64 {
self.pairs
.iter()
.map(|(k, v)| (k.len() + v.len()) as u64)
.sum()
}
}
/// shaped like stream chunks, plus extremes where the per-pair overhead or the copy dominates
pub fn workloads() -> Vec<Workload> {
let mut rng = 0x9e37_79b9_7f4a_7c15_u64;
let mut next = move || {
rng ^= rng << 13;
rng ^= rng >> 7;
rng ^= rng << 17;
rng
};
let mut value = |len: usize| -> Vec<u8> {
// small alphabet so zstd has something to compress
(0..len)
.map(|_| b"abcdefghij{}:\"0123"[next() as usize % 18])
.collect()
};
let id = |i: usize| (i as u64).to_be_bytes().to_vec();
let events = (0..20_000)
.map(|i| {
let len = 200 + (i * 7919) % 1800;
(id(i), value(len))
})
.collect();
let tiny = (0..100_000).map(|i| (id(i), value(16))).collect();
let large = (0..32).map(|i| (id(i), value(1 << 20))).collect();
vec![
Workload {
name: "events",
pairs: events,
},
Workload {
name: "tiny",
pairs: tiny,
},
Workload {
name: "large",
pairs: large,
},
]
}
pub fn meta() -> BTreeMap<&'static str, &'static str> {
BTreeMap::from([
("$type", "systems.gaze.hydrant.streamChunk"),
("stream", "bench"),
])
}
pub fn write(out: &mut impl std::io::Write, w: &Workload) {
dasl_star::write_header(out, &meta()).unwrap();
for (key, value) in &w.pairs {
dasl_star::write_pair(out, key, value).unwrap();
}
dasl_star::write_end(out).unwrap();
}
pub fn encode(w: &Workload) -> Vec<u8> {
let mut out = Vec::new();
write(&mut out, w);
out
}
pub fn encode_zstd(w: &Workload) -> Vec<u8> {
zstd::encode_all(encode(w).as_slice(), ZSTD_LEVEL).unwrap()
}
/// sums every pair so the compiler can't optimize the reading away
pub fn read(r: impl std::io::BufRead) -> u64 {
let mut reader = dasl_star::Reader::new(r).unwrap();
let mut sum = 0u64;
while let Some((key, value)) = reader.next_pair().unwrap() {
sum = sum.wrapping_add(key.len() as u64 + value.len() as u64);
sum = sum.wrapping_add(u64::from(*value.last().unwrap_or(&0)));
}
sum
}
pub fn read_owned(r: impl std::io::BufRead) -> u64 {
let mut sum = 0u64;
for pair in dasl_star::Reader::new(r).unwrap() {
let (key, value) = pair.unwrap();
sum = sum.wrapping_add(key.len() as u64 + value.len() as u64);
sum = sum.wrapping_add(u64::from(*value.last().unwrap_or(&0)));
}
sum
}