From 09da703b20be5133c93c13fca1fc0fc85641702b Mon Sep 17 00:00:00 2001 From: Keenan Tims Date: Thu, 16 Nov 2023 19:19:24 -0800 Subject: [PATCH] Specialize on truncate arg for ~5% speedup in truncate case Use a generic param to specialize on the truncate arg to avoid needing to check it and/or host bits if we'll end up accepting it regardless when truncate is enabled. Refactor host bits check into iputils. --- src/iputils.rs | 3 +++ src/main.rs | 26 +++++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/iputils.rs b/src/iputils.rs index 97751fb..ea1f006 100644 --- a/src/iputils.rs +++ b/src/iputils.rs @@ -140,6 +140,9 @@ impl IpOrNet { pub fn network(&self) -> IpAddr { self.0.network() } + pub fn has_host_bits(&self) -> bool { + self.0.addr() != self.0.network() + } } impl FromStr for IpOrNet { diff --git a/src/main.rs b/src/main.rs index 4c140a0..851eebc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -60,16 +60,17 @@ struct App { } impl App { - fn add_prefix(&mut self, pfx: IpOrNet) { + fn add_prefix(&mut self, pfx: IpOrNet) { // Parser accepts host bits set, so detect that case and error if not truncate mode // Note: aggregate6 errors in this case regardless of -4, -6 so do the same - if !self.args.truncate { - if pfx.addr() != pfx.network() { - eprintln!("ERROR: '{}' is not a valid IP network, ignoring.", pfx); - return; - } + if !TRUNCATE && pfx.has_host_bits() { + // We don't have the original string any more so our error + // differs from `aggregate6` in that it prints the pfxlen as + // parsed, not as in the source. + eprintln!("ERROR: '{}' is not a valid IP network, ignoring.", pfx); + return; } - // Don't bother saving if we won't display. + if self.args.only_v4 && pfx.is_ipv6() { return; } else if self.args.only_v6 && pfx.is_ipv4() { @@ -79,14 +80,14 @@ impl App { self.prefixes.add(pfx); } } - fn consume_input(&mut self, input: &mut Input) { + fn consume_input(&mut self, input: &mut Input) { for line in input.lock().lines() { match line { Ok(line) => { - for net in line.split_whitespace() { + for net in line.split_ascii_whitespace() { let pnet = net.parse::(); match pnet { - Ok(pnet) => self.add_prefix(pnet), + Ok(pnet) => self.add_prefix::(pnet), Err(_e) => { eprintln!("ERROR: '{}' is not a valid IP network, ignoring.", net); } @@ -103,7 +104,10 @@ impl App { fn simplify_inputs(&mut self) { let inputs = self.args.input.to_owned(); for mut input in inputs { - self.consume_input(&mut input); + match self.args.truncate { + true => self.consume_input::(&mut input), + false => self.consume_input::(&mut input), + } } self.prefixes.simplify(); }