Read about our upcoming Code of Conduct on this issue

Commit 5e85e10d authored by Arseniy Alekseyev's avatar Arseniy Alekseyev
Browse files

rhg: more efficient `HgPath::join`

This commit makes `HgPath::join` slightly more efficient
by avoiding one copy.

It also avoids a particularly inefficient (quadratic) use of
`HgPath::join` by using a new mutating function `HgPathBuf::push` instead.

The name for `HgPathBuf::push` is chosen by analogy to `PathBuf::push`.

Differential Revision: https://phab.mercurial-scm.org/D11721
parent 229f5ee1a08a
Pipeline #28773 passed with stages
in 55 minutes and 30 seconds
......@@ -536,7 +536,7 @@ impl SubInclude {
Ok(Self {
prefix: path_to_hg_path_buf(prefix).and_then(|mut p| {
if !p.is_empty() {
p.push(b'/');
p.push_byte(b'/');
}
Ok(p)
})?,
......
......@@ -391,8 +391,7 @@ fn roots_and_dirs(
} = ignore_pattern;
match syntax {
PatternSyntax::RootGlob | PatternSyntax::Glob => {
let mut root = vec![];
let mut root = HgPathBuf::new();
for p in pattern.split(|c| *c == b'/') {
if p.iter().any(|c| match *c {
b'[' | b'{' | b'*' | b'?' => true,
......@@ -400,11 +399,9 @@ fn roots_and_dirs(
}) {
break;
}
root.push(HgPathBuf::from_bytes(p));
root.push(HgPathBuf::from_bytes(p).as_ref());
}
let buf =
root.iter().fold(HgPathBuf::new(), |acc, r| acc.join(r));
roots.push(buf);
roots.push(root);
}
PatternSyntax::Path | PatternSyntax::RelPath => {
let pat = HgPath::new(if pattern == b"." {
......
......@@ -220,13 +220,11 @@ impl HgPath {
),
}
}
pub fn join<T: ?Sized + AsRef<Self>>(&self, other: &T) -> HgPathBuf {
let mut inner = self.inner.to_owned();
if !inner.is_empty() && inner.last() != Some(&b'/') {
inner.push(b'/');
}
inner.extend(other.as_ref().bytes());
HgPathBuf::from_bytes(&inner)
pub fn join(&self, path: &HgPath) -> HgPathBuf {
let mut buf = self.to_owned();
buf.push(path);
buf
}
pub fn components(&self) -> impl Iterator<Item = &HgPath> {
......@@ -405,7 +403,15 @@ impl HgPathBuf {
pub fn new() -> Self {
Default::default()
}
pub fn push(&mut self, byte: u8) {
pub fn push<T: ?Sized + AsRef<HgPath>>(&mut self, other: &T) -> () {
if !self.inner.is_empty() && self.inner.last() != Some(&b'/') {
self.inner.push(b'/');
}
self.inner.extend(other.as_ref().bytes())
}
pub fn push_byte(&mut self, byte: u8) {
self.inner.push(byte);
}
pub fn from_bytes(s: &[u8]) -> HgPathBuf {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment