Patchwork D9121: hg-core: fix path encoding usage

login
register
mail settings
Submitter phabricator
Date Sept. 29, 2020, 3:58 p.m.
Message ID <differential-rev-PHID-DREV-tbwpgmxartj4wbldz3up-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47336/
State New
Headers show

Comments

phabricator - Sept. 29, 2020, 3:58 p.m.
acezar created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  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`

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D9121

AFFECTED 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

CHANGE DETAILS




To: acezar, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/rust/hg-core/src/revlog/revlog.rs b/rust/hg-core/src/revlog/revlog.rs
--- a/rust/hg-core/src/revlog/revlog.rs
+++ b/rust/hg-core/src/revlog/revlog.rs
@@ -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,6 +61,8 @@ 
 
         let index = Index::new(Box::new(index_mmap))?;
 
+        let default_data_path = index_path.with_extension("d");
+
         // TODO load data only when needed //
         // type annotation required
         // won't recognize Mmap as Deref<Target = [u8]>
@@ -65,9 +70,9 @@ 
             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))
             };
 
diff --git a/rust/hg-core/src/revlog/manifest.rs b/rust/hg-core/src/revlog/manifest.rs
--- a/rust/hg-core/src/revlog/manifest.rs
+++ b/rust/hg-core/src/revlog/manifest.rs
@@ -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 })
     }
 
diff --git a/rust/hg-core/src/revlog/changelog.rs b/rust/hg-core/src/revlog/changelog.rs
--- a/rust/hg-core/src/revlog/changelog.rs
+++ b/rust/hg-core/src/revlog/changelog.rs
@@ -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 })
     }
 
diff --git a/rust/hg-core/src/operations/debugdata.rs b/rust/hg-core/src/operations/debugdata.rs
--- a/rust/hg-core/src/operations/debugdata.rs
+++ b/rust/hg-core/src/operations/debugdata.rs
@@ -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)
diff --git a/rust/hg-core/src/operations/cat.rs b/rust/hg-core/src/operations/cat.rs
--- a/rust/hg-core/src/operations/cat.rs
+++ b/rust/hg-core/src/operations/cat.rs
@@ -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,7 @@ 
 use crate::revlog::revlog::Revlog;
 use crate::revlog::revlog::RevlogError;
 use crate::revlog::Revision;
-use crate::utils::hg_path::HgPathBuf;
+use crate::utils::hg_path::{HgPath, HgPathBuf};
 
 /// Kind of error encountered by `CatRev`
 #[derive(Debug)]
@@ -119,15 +119,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)?;
@@ -143,3 +141,11 @@ 
         }
     }
 }
+
+fn store_path(root: &Path, hg_path: &HgPath, suffix: &[u8]) -> PathBuf {
+    let encoded_bytes =
+        path_encode(&[b"data/", hg_path.as_bytes(), suffix].concat());
+    let encoded_string =
+        format!(".hg/store/{}", String::from_utf8_lossy(&encoded_bytes),);
+    root.join(&encoded_string)
+}