Mercurial > hg
changeset 45806:7252f5237352
hg-core: fix path encoding usage
1. Hash encoded path are in `.hg/store/dh` instead of `.hg/store/data`.
2. Path encoded index and data files may not have the same parent path.
It is not just about replacing `.i` by `.d`
Differential Revision: https://phab.mercurial-scm.org/D9121
author | Antoine cezar<acezar@chwitlabs.fr> |
---|---|
date | Mon, 28 Sep 2020 17:13:15 +0200 |
parents | 49535e56fab8 |
children | f90943d753ef |
files | rust/hg-core/src/operations/cat.rs rust/hg-core/src/operations/debugdata.rs rust/hg-core/src/revlog/changelog.rs rust/hg-core/src/revlog/manifest.rs rust/hg-core/src/revlog/revlog.rs |
diffstat | 5 files changed, 33 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/operations/cat.rs Mon Oct 26 11:45:32 2020 +0100 +++ b/rust/hg-core/src/operations/cat.rs Mon Sep 28 17:13:15 2020 +0200 @@ -6,7 +6,7 @@ // GNU General Public License version 2 or any later version. use std::convert::From; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use crate::revlog::changelog::Changelog; use crate::revlog::manifest::{Manifest, ManifestEntry}; @@ -14,7 +14,8 @@ use crate::revlog::revlog::Revlog; use crate::revlog::revlog::RevlogError; use crate::revlog::Revision; -use crate::utils::hg_path::HgPathBuf; +use crate::utils::files::get_path_from_bytes; +use crate::utils::hg_path::{HgPath, HgPathBuf}; const METADATA_DELIMITER: [u8; 2] = [b'\x01', b'\n']; @@ -121,15 +122,13 @@ { for cat_file in self.files.iter() { if cat_file.as_bytes() == manifest_file.as_bytes() { - let encoded_bytes = - path_encode(manifest_file.as_bytes()); - let revlog_index_string = format!( - ".hg/store/data/{}.i", - String::from_utf8_lossy(&encoded_bytes), - ); - let revlog_index_path = - self.root.join(&revlog_index_string); - let file_log = Revlog::open(&revlog_index_path)?; + let index_path = + store_path(self.root, manifest_file, b".i"); + let data_path = + store_path(self.root, manifest_file, b".d"); + + let file_log = + Revlog::open(&index_path, Some(&data_path))?; let file_node = hex::decode(&node_bytes) .map_err(|_| CatRevErrorKind::CorruptedRevlog)?; let file_rev = file_log.get_node_rev(&file_node)?; @@ -156,3 +155,15 @@ } } } + +fn store_path(root: &Path, hg_path: &HgPath, suffix: &[u8]) -> PathBuf { + let encoded_bytes = + path_encode(&[b"data/", hg_path.as_bytes(), suffix].concat()); + [ + root, + &Path::new(".hg/store/"), + get_path_from_bytes(&encoded_bytes), + ] + .iter() + .collect() +}
--- a/rust/hg-core/src/operations/debugdata.rs Mon Oct 26 11:45:32 2020 +0100 +++ b/rust/hg-core/src/operations/debugdata.rs Mon Sep 28 17:13:15 2020 +0200 @@ -102,7 +102,7 @@ DebugDataKind::Changelog => root.join(".hg/store/00changelog.i"), DebugDataKind::Manifest => root.join(".hg/store/00manifest.i"), }; - let revlog = Revlog::open(&index_file)?; + let revlog = Revlog::open(&index_file, None)?; let data = revlog.get_rev_data(rev)?; Ok(data)
--- a/rust/hg-core/src/revlog/changelog.rs Mon Oct 26 11:45:32 2020 +0100 +++ b/rust/hg-core/src/revlog/changelog.rs Mon Sep 28 17:13:15 2020 +0200 @@ -12,7 +12,7 @@ /// Open the `changelog` of a repository given by its root. pub fn open(root: &PathBuf) -> Result<Self, RevlogError> { let index_file = root.join(".hg/store/00changelog.i"); - let revlog = Revlog::open(&index_file)?; + let revlog = Revlog::open(&index_file, None)?; Ok(Self { revlog }) }
--- a/rust/hg-core/src/revlog/manifest.rs Mon Oct 26 11:45:32 2020 +0100 +++ b/rust/hg-core/src/revlog/manifest.rs Mon Sep 28 17:13:15 2020 +0200 @@ -13,7 +13,7 @@ /// Open the `manifest` of a repository given by its root. pub fn open(root: &PathBuf) -> Result<Self, RevlogError> { let index_file = root.join(".hg/store/00manifest.i"); - let revlog = Revlog::open(&index_file)?; + let revlog = Revlog::open(&index_file, None)?; Ok(Self { revlog }) }
--- a/rust/hg-core/src/revlog/revlog.rs Mon Oct 26 11:45:32 2020 +0100 +++ b/rust/hg-core/src/revlog/revlog.rs Mon Sep 28 17:13:15 2020 +0200 @@ -47,7 +47,10 @@ /// It will also open the associated data file if index and data are not /// interleaved. #[timed] - pub fn open(index_path: &Path) -> Result<Self, RevlogError> { + pub fn open( + index_path: &Path, + data_path: Option<&Path>, + ) -> Result<Self, RevlogError> { let index_mmap = mmap_open(&index_path).map_err(RevlogError::IoError)?; @@ -58,16 +61,17 @@ let index = Index::new(Box::new(index_mmap))?; - // TODO load data only when needed // + let default_data_path = index_path.with_extension("d"); + // type annotation required // won't recognize Mmap as Deref<Target = [u8]> let data_bytes: Option<Box<dyn Deref<Target = [u8]> + Send>> = if index.is_inline() { None } else { - let data_path = index_path.with_extension("d"); + let data_path = data_path.unwrap_or(&default_data_path); let data_mmap = - mmap_open(&data_path).map_err(RevlogError::IoError)?; + mmap_open(data_path).map_err(RevlogError::IoError)?; Some(Box::new(data_mmap)) };