use std::collections::BTreeSet;
fn first_fields(csv: &str) -> BTreeSet<String> {
let mut out = BTreeSet::new();
for line in csv.lines().skip(1) {
let name = if let Some(quoted) = line.strip_prefix('"') {
let Some(end) = quoted.find('"') else {
continue;
};
quoted[..end].to_string()
} else {
match line.split_once(',') {
Some((first, _)) => first.to_string(),
None => line.to_string(),
}
};
if !name.is_empty() {
out.insert(name);
}
}
out
}
fn main() {
let coder = std::env::args()
.find(|a| a == "ans" || a == "range")
.unwrap_or("ans".to_string());
let iterations: usize = std::env::args()
.filter_map(|a| a.parse().ok())
.next()
.unwrap_or(2000);
let csv = std::fs::read_to_string("comparison/src/meteorites.csv")
.or_else(|_| std::fs::read_to_string("../comparison/src/meteorites.csv"))
.expect("run from the workspace root so comparison/src/meteorites.csv is found");
let names = first_fields(&csv);
println!("decoding {} meteorite names with {coder}", names.len());
let mut total = 0usize;
match coder.as_str() {
"ans" => {
let encoded = compactly::v2::Ans::encode(&names);
println!("encoded size {}", encoded.len());
for _ in 0..iterations {
total += std::hint::black_box(
compactly::v2::Ans::decode::<BTreeSet<String>>(&encoded).unwrap(),
)
.len();
}
}
"range" => {
let encoded = compactly::v2::encode(&names);
println!("encoded size {}", encoded.len());
for _ in 0..iterations {
total += std::hint::black_box(
compactly::v2::decode::<BTreeSet<String>>(&encoded).unwrap(),
)
.len();
}
}
_ => unreachable!(),
}
println!("total decoded {total}");
}