//! How many UPDATEs, and how many octets, a table takes when the routes //! that share attributes are grouped only within slices of the table //! taken in shard order, for a few slice sizes: what streaming a table //! out in slices costs against grouping it whole. use std::collections::HashMap; use std::hash::{BuildHasher, RandomState}; use std::path::PathBuf; use bgp_bench::mrt::Dump; fn main() { let path = std::env::var("BENCH_MRT") .map(PathBuf::from) .unwrap_or_else(|_| "crates/bench/data/rrc03-bview.20260915.0000.gz".into()); let dump = Dump::read(&path).expect("a readable dump"); let peers = dump.largest_peers(usize::MAX); let full: Vec = peers .iter() .copied() .filter(|&p| dump.routes[p].len() > 800_000) .collect(); println!("{} peers with a full table", full.len()); let hasher = RandomState::new(); for (what, chosen) in [ ("one full table", vec![full[0]]), ("every full table, every path", full.clone()), ] { // (hash of prefix, attribute set, prefix octets) in shard order. let mut routes: Vec<(u64, u32, usize)> = chosen .iter() .flat_map(|&p| dump.routes[p].iter()) .map(|(prefix, set)| { ( hasher.hash_one(prefix), *set, 1 + usize::from(prefix.length()).div_ceil(8) + 4, ) }) .collect(); routes.sort_unstable_by_key(|r| r.0); println!("== {what}: {} routes", routes.len()); for slice in [4_096usize, 16_384, 65_536, 262_144, usize::MAX] { let mut updates = 0usize; let mut octets = 0usize; for chunk in routes.chunks(slice.min(routes.len())) { let mut groups: HashMap = HashMap::new(); for &(_, set, prefix_octets) in chunk { *groups.entry(set).or_insert(0) += prefix_octets; } for (set, prefix_octets) in groups { // One UPDATE per 4096 octets of prefixes, roughly. let attrs = dump.attribute_sets[set as usize].len(); let messages = prefix_octets.div_ceil(4000 - attrs.min(3000)).max(1); updates += messages; octets += messages * (23 + attrs) + prefix_octets; } } println!( " slice {:>9}: {:>9} UPDATEs, {:>5.1} MB on the wire", if slice == usize::MAX { "whole".to_string() } else { slice.to_string() }, updates, octets as f64 / 1e6 ); } } }