From 30b9a7852092f7201de5f764ecf5af9c78fff8a0 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Wed, 15 Jun 2022 17:45:50 +1000 Subject: [PATCH] Optimize `normalize_path`: Avoid copy if possible Signed-off-by: Jiahao XU --- src/drivers/visitor.rs | 3 ++- src/helpers/path_ext.rs | 26 ++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/drivers/visitor.rs b/src/drivers/visitor.rs index 850d7c39..3f354771 100644 --- a/src/drivers/visitor.rs +++ b/src/drivers/visitor.rs @@ -49,7 +49,8 @@ impl TarEntriesVisitor for ManifestVisitor { fn visit(&mut self, entries: Entries<'_, R>) -> Result<(), BinstallError> { for res in entries { let mut entry = res?; - let path = entry.path()?.normalize_path(); + let path = entry.path()?; + let path = path.normalize_path(); let path = if let Ok(path) = path.strip_prefix(&self.manifest_dir_path) { path diff --git a/src/helpers/path_ext.rs b/src/helpers/path_ext.rs index 1e5d2cc7..bf223280 100644 --- a/src/helpers/path_ext.rs +++ b/src/helpers/path_ext.rs @@ -1,16 +1,34 @@ -//! Shamelessly taken from: +//! Shamelessly adapted from: //! https://github.com/rust-lang/cargo/blob/fede83ccf973457de319ba6fa0e36ead454d2e20/src/cargo/util/paths.rs#L61 +use std::borrow::Cow; use std::path::{Component, Path, PathBuf}; pub trait PathExt { /// Similiar to `os.path.normpath`: It does not perform /// any fs operation. - fn normalize_path(&self) -> PathBuf; + fn normalize_path(&self) -> Cow<'_, Path>; +} + +fn is_normalized(path: &Path) -> bool { + for component in path.components() { + match component { + Component::CurDir | Component::ParentDir => { + return false; + } + _ => continue, + } + } + + true } impl PathExt for Path { - fn normalize_path(&self) -> PathBuf { + fn normalize_path(&self) -> Cow<'_, Path> { + if is_normalized(self) { + return Cow::Borrowed(self); + } + let mut components = self.components().peekable(); let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() { components.next(); @@ -34,6 +52,6 @@ impl PathExt for Path { } } } - ret + Cow::Owned(ret) } }