Rewrite path::Display to reduce unnecessary allocation

This commit is contained in:
Kevin Ballard 2014-02-07 19:45:48 -08:00
parent 086c0dd33f
commit 1d17c2129e
6 changed files with 24 additions and 50 deletions

View File

@ -442,9 +442,7 @@ fn check_error_patterns(props: &TestProps,
testfile: &Path, testfile: &Path,
ProcRes: &ProcRes) { ProcRes: &ProcRes) {
if props.error_patterns.is_empty() { if props.error_patterns.is_empty() {
testfile.display().with_str(|s| { fatal(~"no error pattern specified in " + testfile.display().as_maybe_owned().as_slice());
fatal(~"no error pattern specified in " + s);
})
} }
if ProcRes.status.success() { if ProcRes.status.success() {

View File

@ -436,7 +436,7 @@ impl<'a> SourceCollector<'a> {
cur.push(p.filename().expect("source has no filename") + bytes!(".html")); cur.push(p.filename().expect("source has no filename") + bytes!(".html"));
let mut w = BufferedWriter::new(if_ok!(File::create(&cur))); let mut w = BufferedWriter::new(if_ok!(File::create(&cur)));
let title = cur.filename_display().with_str(|s| format!("{} -- source", s)); let title = format!("{} -- source", cur.filename_display());
let page = layout::Page { let page = layout::Page {
title: title, title: title,
ty: "source", ty: "source",

View File

@ -70,7 +70,7 @@ use fmt;
use iter::Iterator; use iter::Iterator;
use option::{Option, None, Some}; use option::{Option, None, Some};
use str; use str;
use str::{OwnedStr, Str, StrSlice}; use str::{MaybeOwned, OwnedStr, Str, StrSlice, from_utf8_lossy};
use to_str::ToStr; use to_str::ToStr;
use vec; use vec;
use vec::{CloneableVector, OwnedCloneableVector, OwnedVector, Vector}; use vec::{CloneableVector, OwnedCloneableVector, OwnedVector, Vector};
@ -495,7 +495,7 @@ pub struct Display<'a, P> {
impl<'a, P: GenericPath> fmt::Show for Display<'a, P> { impl<'a, P: GenericPath> fmt::Show for Display<'a, P> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.with_str(|s| f.pad(s)) self.as_maybe_owned().as_slice().fmt(f)
} }
} }
@ -505,33 +505,25 @@ impl<'a, P: GenericPath> ToStr for Display<'a, P> {
/// If the path is not UTF-8, invalid sequences with be replaced with the /// If the path is not UTF-8, invalid sequences with be replaced with the
/// unicode replacement char. This involves allocation. /// unicode replacement char. This involves allocation.
fn to_str(&self) -> ~str { fn to_str(&self) -> ~str {
if self.filename { self.as_maybe_owned().into_owned()
match self.path.filename() {
None => ~"",
Some(v) => str::from_utf8_lossy(v).into_owned()
}
} else {
str::from_utf8_lossy(self.path.as_vec()).into_owned()
}
} }
} }
impl<'a, P: GenericPath> Display<'a, P> { impl<'a, P: GenericPath> Display<'a, P> {
/// Provides the path as a string to a closure /// Returns the path as a possibly-owned string.
/// ///
/// If the path is not UTF-8, invalid sequences will be replaced with the /// If the path is not UTF-8, invalid sequences will be replaced with the
/// unicode replacement char. This involves allocation. /// unicode replacement char. This involves allocation.
#[inline] #[inline]
pub fn with_str<T>(&self, f: |&str| -> T) -> T { pub fn as_maybe_owned(&self) -> MaybeOwned<'a> {
let opt = if self.filename { self.path.filename_str() } from_utf8_lossy(if self.filename {
else { self.path.as_str() }; match self.path.filename() {
match opt { None => &[],
Some(s) => f(s), Some(v) => v
None => {
let s = self.to_str();
f(s.as_slice())
} }
} } else {
self.path.as_vec()
})
} }
} }

View File

@ -564,24 +564,16 @@ mod tests {
macro_rules! t( macro_rules! t(
($path:expr, $exp:expr) => ( ($path:expr, $exp:expr) => (
{ {
let mut called = false;
let path = Path::new($path); let path = Path::new($path);
path.display().with_str(|s| { let mo = path.display().as_maybe_owned();
assert_eq!(s, $exp); assert_eq!(mo.as_slice(), $exp);
called = true;
});
assert!(called);
} }
); );
($path:expr, $exp:expr, filename) => ( ($path:expr, $exp:expr, filename) => (
{ {
let mut called = false;
let path = Path::new($path); let path = Path::new($path);
path.filename_display().with_str(|s| { let mo = path.filename_display().as_maybe_owned();
assert_eq!(s, $exp); assert_eq!(mo.as_slice(), $exp);
called = true;
});
assert!(called);
} }
) )
) )

View File

@ -1278,20 +1278,12 @@ mod tests {
let path = Path::new(b!("\\")); let path = Path::new(b!("\\"));
assert_eq!(path.filename_display().to_str(), ~""); assert_eq!(path.filename_display().to_str(), ~"");
let mut called = false;
let path = Path::new("foo"); let path = Path::new("foo");
path.display().with_str(|s| { let mo = path.display().as_maybe_owned();
assert_eq!(s, "foo"); assert_eq!(mo.as_slice(), "foo");
called = true;
});
assert!(called);
called = false;
let path = Path::new(b!("\\")); let path = Path::new(b!("\\"));
path.filename_display().with_str(|s| { let mo = path.filename_display().as_maybe_owned();
assert_eq!(s, ""); assert_eq!(mo.as_slice(), "");
called = true;
});
assert!(called);
} }
#[test] #[test]

View File

@ -4200,10 +4200,10 @@ impl Parser {
let mut err = ~"circular modules: "; let mut err = ~"circular modules: ";
let len = included_mod_stack.get().len(); let len = included_mod_stack.get().len();
for p in included_mod_stack.get().slice(i, len).iter() { for p in included_mod_stack.get().slice(i, len).iter() {
p.display().with_str(|s| err.push_str(s)); err.push_str(p.display().as_maybe_owned().as_slice());
err.push_str(" -> "); err.push_str(" -> ");
} }
path.display().with_str(|s| err.push_str(s)); err.push_str(path.display().as_maybe_owned().as_slice());
self.span_fatal(id_sp, err); self.span_fatal(id_sp, err);
} }
None => () None => ()