##// END OF EJS Templates
dirstate-tree: optimize HashMap lookups with raw_entry_mut...
dirstate-tree: optimize HashMap lookups with raw_entry_mut This switches to using `HashMap` from the hashbrown crate, in order to use its `raw_entry_mut` method. The standard library’s `HashMap` is also based on this same crate, but `raw_entry_mut` is not yet stable there: https://github.com/rust-lang/rust/issues/56167 Using version 0.9 because 0.10 is yanked and 0.11 requires Rust 1.49 This replaces in `DirstateMap::get_or_insert_node` a call to `HashMap<K, V>::entry` with `K = WithBasename<Cow<'on_disk, HgPath>>`. `entry` takes and consumes an "owned" `key: K` parameter, in case a new entry ends up inserted. This key is converted by `to_cow` from a value that borrows the `'path` lifetime. When this function is called by `Dirstate::new_v1`, `'path` is in fact the same as `'on_disk` so `to_cow` can return an owned key that contains `Cow::Borrowed`. For other callers, `to_cow` needs to create a `Cow::Owned` and thus make a costly heap memory allocation. This is wasteful if this key was already present in the map. Even when inserting a new node this is typically the case for its ancestor nodes (assuming most directories have numerous descendants). Differential Revision: https://phab.mercurial-scm.org/D12317

File last commit:

r49284:9b0e1f64 default
r49805:11c0411b default
Show More
path_utils.rs
55 lines | 1.7 KiB | application/rls-services+xml | RustLexer
// path utils module
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
use hg::errors::HgError;
use hg::repo::Repo;
use hg::utils::current_dir;
use hg::utils::files::{get_bytes_from_path, relativize_path};
use hg::utils::hg_path::HgPath;
use hg::utils::hg_path::HgPathBuf;
use std::borrow::Cow;
pub struct RelativizePaths {
repo_root: HgPathBuf,
cwd: HgPathBuf,
outside_repo: bool,
}
impl RelativizePaths {
pub fn new(repo: &Repo) -> Result<Self, HgError> {
let cwd = current_dir()?;
let repo_root = repo.working_directory_path();
let repo_root = cwd.join(repo_root); // Make it absolute
let repo_root_hgpath =
HgPathBuf::from(get_bytes_from_path(repo_root.to_owned()));
if let Ok(cwd_relative_to_repo) = cwd.strip_prefix(&repo_root) {
// The current directory is inside the repo, so we can work with
// relative paths
Ok(Self {
repo_root: repo_root_hgpath,
cwd: HgPathBuf::from(get_bytes_from_path(
cwd_relative_to_repo,
)),
outside_repo: false,
})
} else {
Ok(Self {
repo_root: repo_root_hgpath,
cwd: HgPathBuf::from(get_bytes_from_path(cwd)),
outside_repo: true,
})
}
}
pub fn relativize<'a>(&self, path: &'a HgPath) -> Cow<'a, [u8]> {
if self.outside_repo {
let joined = self.repo_root.join(path);
Cow::Owned(relativize_path(&joined, &self.cwd).into_owned())
} else {
relativize_path(path, &self.cwd)
}
}
}