Skip to content

Commit 65ddccb

Browse files
committed
checksum: avoid to recompute Regexps
1 parent ed15ca1 commit 65ddccb

File tree

3 files changed

+28
-14
lines changed

3 files changed

+28
-14
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/uucore/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ dns-lookup = { workspace = true, optional = true }
2525
dunce = { version = "1.0.4", optional = true }
2626
wild = "2.2.1"
2727
glob = { workspace = true }
28+
lazy_static = "1.4.0"
2829
# * optional
2930
itertools = { workspace = true, optional = true }
3031
thiserror = { workspace = true, optional = true }

src/uucore/src/lib/features/checksum.rs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// spell-checker:ignore anotherfile invalidchecksum regexes JWZG FFFD xffname prefixfilename
66

77
use data_encoding::BASE64;
8+
use lazy_static::lazy_static;
89
use os_display::Quotable;
910
use regex::bytes::{Match, Regex};
1011
use std::{
@@ -428,35 +429,46 @@ const DOUBLE_SPACE_REGEX: &str = r"^(?P<checksum>[a-fA-F0-9]+)\s{2}(?P<filename>
428429
// In this case, we ignore the *
429430
const SINGLE_SPACE_REGEX: &str = r"^(?P<checksum>[a-fA-F0-9]+)\s(?P<filename>\*?(?-u:.*))$";
430431

432+
lazy_static! {
433+
static ref R_ALGO_BASED: Regex = Regex::new(ALGO_BASED_REGEX).unwrap();
434+
static ref R_DOUBLE_SPACE: Regex = Regex::new(DOUBLE_SPACE_REGEX).unwrap();
435+
static ref R_SINGLE_SPACE: Regex = Regex::new(SINGLE_SPACE_REGEX).unwrap();
436+
static ref R_ALGO_BASED_BASE_64: Regex = Regex::new(ALGO_BASED_REGEX_BASE64).unwrap();
437+
}
438+
431439
/// Hold the data extracted from a checksum line.
432440
struct LineInfo {
433441
algo_name: Option<String>,
434442
algo_bit_len: Option<usize>,
435443
checksum: String,
436444
filename: Vec<u8>,
437445

438-
regex: Regex,
446+
regex: &'static Regex,
439447
}
440448

441449
impl LineInfo {
442-
fn parse(s: impl AsRef<OsStr>, cached_regex: &mut Option<Regex>) -> Option<Self> {
443-
let regexes = [
444-
(Regex::new(ALGO_BASED_REGEX).unwrap(), true),
445-
(Regex::new(DOUBLE_SPACE_REGEX).unwrap(), false),
446-
(Regex::new(SINGLE_SPACE_REGEX).unwrap(), false),
447-
(Regex::new(ALGO_BASED_REGEX_BASE64).unwrap(), false),
450+
fn parse(s: impl AsRef<OsStr>, cached_regex: &mut Option<&'static Regex>) -> Option<Self> {
451+
let regexes: &[(&'static Regex, bool)] = &[
452+
(&R_ALGO_BASED, true),
453+
(&R_DOUBLE_SPACE, false),
454+
(&R_SINGLE_SPACE, false),
455+
(&R_ALGO_BASED_BASE_64, true),
448456
];
449457

450458
let line_bytes = os_str_as_bytes(s.as_ref()).expect("UTF-8 decoding failed");
451459

452-
for (regex, algo_based) in &regexes {
460+
for (regex, algo_based) in regexes {
453461
if !regex.is_match(line_bytes) {
454462
continue;
455463
}
456464

457-
let mut r = regex.clone();
458-
if !algo_based && cached_regex.is_some() {
459-
r = cached_regex.clone().unwrap();
465+
let mut r = *regex;
466+
if !algo_based {
467+
if cached_regex.is_some() {
468+
r = cached_regex.unwrap();
469+
} else {
470+
*cached_regex = Some(r);
471+
}
460472
}
461473

462474
if let Some(caps) = r.captures(line_bytes) {
@@ -470,7 +482,7 @@ impl LineInfo {
470482
.map(|m| match_to_string(m).parse::<usize>().unwrap()),
471483
checksum: caps.name("checksum").map(match_to_string).unwrap(),
472484
filename: caps.name("filename").map(|m| m.as_bytes().into()).unwrap(),
473-
regex: r.clone(),
485+
regex: r,
474486
});
475487
}
476488
}
@@ -638,7 +650,7 @@ fn process_checksum_line(
638650
cli_algo_name: Option<&str>,
639651
cli_algo_length: Option<usize>,
640652
opts: ChecksumOptions,
641-
cached_regex: &mut Option<Regex>,
653+
cached_regex: &mut Option<&'static Regex>,
642654
) -> Result<(), LineCheckError> {
643655
let line_bytes = os_str_as_bytes(line)?;
644656

@@ -652,7 +664,7 @@ fn process_checksum_line(
652664
// its cannot be changed (can't have single and double space regexes
653665
// used in the same file).
654666
if cached_regex.is_none() && !line_info.is_algo_based() {
655-
let _ = cached_regex.insert(line_info.regex.clone());
667+
let _ = cached_regex.insert(line_info.regex);
656668
}
657669

658670
let mut filename_to_check = line_info.filename.as_slice();

0 commit comments

Comments
 (0)