rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
authorSimon Sapin <simon.sapin@octobus.net>
Mon, 13 Sep 2021 13:29:55 +0200
changeset 47959 21d25e9ee58e
parent 47958 fc208d6faed3
child 47960 cfb6e6699b25
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object That way if one of them is accessed multiple times it won’t be reopened from the filesystem. Differential Revision: https://phab.mercurial-scm.org/D11406
rust/hg-core/src/operations/cat.rs
rust/hg-core/src/operations/list_tracked_files.rs
rust/hg-core/src/repo.rs
rust/hg-core/src/revset.rs
--- a/rust/hg-core/src/operations/cat.rs	Mon Sep 13 13:16:10 2021 +0200
+++ b/rust/hg-core/src/operations/cat.rs	Mon Sep 13 13:29:55 2021 +0200
@@ -8,8 +8,6 @@
 use std::path::PathBuf;
 
 use crate::repo::Repo;
-use crate::revlog::changelog::Changelog;
-use crate::revlog::manifest::Manifestlog;
 use crate::revlog::path_encode::path_encode;
 use crate::revlog::revlog::Revlog;
 use crate::revlog::revlog::RevlogError;
@@ -42,8 +40,8 @@
     files: &'a [HgPathBuf],
 ) -> Result<CatOutput, RevlogError> {
     let rev = crate::revset::resolve_single(revset, repo)?;
-    let changelog = Changelog::open(repo)?;
-    let manifest = Manifestlog::open(repo)?;
+    let changelog = repo.changelog()?;
+    let manifest = repo.manifestlog()?;
     let changelog_entry = changelog.get_rev(rev)?;
     let node = *changelog
         .node_from_rev(rev)
--- a/rust/hg-core/src/operations/list_tracked_files.rs	Mon Sep 13 13:16:10 2021 +0200
+++ b/rust/hg-core/src/operations/list_tracked_files.rs	Mon Sep 13 13:29:55 2021 +0200
@@ -9,8 +9,7 @@
 use crate::dirstate_tree::on_disk::{for_each_tracked_path, read_docket};
 use crate::errors::HgError;
 use crate::repo::Repo;
-use crate::revlog::changelog::Changelog;
-use crate::revlog::manifest::{Manifest, Manifestlog};
+use crate::revlog::manifest::Manifest;
 use crate::revlog::node::Node;
 use crate::revlog::revlog::RevlogError;
 use crate::utils::hg_path::HgPath;
@@ -72,8 +71,8 @@
     revset: &str,
 ) -> Result<FilesForRev, RevlogError> {
     let rev = crate::revset::resolve_single(revset, repo)?;
-    let changelog = Changelog::open(repo)?;
-    let manifest = Manifestlog::open(repo)?;
+    let changelog = repo.changelog()?;
+    let manifest = repo.manifestlog()?;
     let changelog_entry = changelog.get_rev(rev)?;
     let manifest_node =
         Node::from_hex_for_repo(&changelog_entry.manifest_node()?)?;
--- a/rust/hg-core/src/repo.rs	Mon Sep 13 13:16:10 2021 +0200
+++ b/rust/hg-core/src/repo.rs	Mon Sep 13 13:29:55 2021 +0200
@@ -1,3 +1,4 @@
+use crate::changelog::Changelog;
 use crate::config::{Config, ConfigError, ConfigParseError};
 use crate::dirstate::DirstateParents;
 use crate::dirstate_tree::dirstate_map::DirstateMap;
@@ -5,7 +6,9 @@
 use crate::errors::HgError;
 use crate::errors::HgResultExt;
 use crate::exit_codes;
+use crate::manifest::Manifestlog;
 use crate::requirements;
+use crate::revlog::revlog::RevlogError;
 use crate::utils::files::get_path_from_bytes;
 use crate::utils::SliceExt;
 use crate::vfs::{is_dir, is_file, Vfs};
@@ -24,6 +27,8 @@
     // None means not known/initialized yet
     dirstate_parents: Cell<Option<DirstateParents>>,
     dirstate_map: LazyCell<OwningDirstateMap, DirstateError>,
+    changelog: LazyCell<Changelog, RevlogError>,
+    manifestlog: LazyCell<Manifestlog, RevlogError>,
 }
 
 #[derive(Debug, derive_more::From)]
@@ -197,6 +202,8 @@
             config: repo_config,
             dirstate_parents: Cell::new(None),
             dirstate_map: LazyCell::new(Self::new_dirstate_map),
+            changelog: LazyCell::new(Changelog::open),
+            manifestlog: LazyCell::new(Manifestlog::open),
         };
 
         requirements::check(&repo)?;
@@ -310,6 +317,22 @@
     ) -> Result<RefMut<OwningDirstateMap>, DirstateError> {
         self.dirstate_map.get_mut_or_init(self)
     }
+
+    pub fn changelog(&self) -> Result<Ref<Changelog>, RevlogError> {
+        self.changelog.get_or_init(self)
+    }
+
+    pub fn changelog_mut(&self) -> Result<RefMut<Changelog>, RevlogError> {
+        self.changelog.get_mut_or_init(self)
+    }
+
+    pub fn manifestlog(&self) -> Result<Ref<Manifestlog>, RevlogError> {
+        self.manifestlog.get_or_init(self)
+    }
+
+    pub fn manifestlog_mut(&self) -> Result<RefMut<Manifestlog>, RevlogError> {
+        self.manifestlog.get_mut_or_init(self)
+    }
 }
 
 /// Lazily-initialized component of `Repo` with interior mutability
--- a/rust/hg-core/src/revset.rs	Mon Sep 13 13:16:10 2021 +0200
+++ b/rust/hg-core/src/revset.rs	Mon Sep 13 13:29:55 2021 +0200
@@ -4,7 +4,6 @@
 
 use crate::errors::HgError;
 use crate::repo::Repo;
-use crate::revlog::changelog::Changelog;
 use crate::revlog::revlog::{Revlog, RevlogError};
 use crate::revlog::NodePrefix;
 use crate::revlog::{Revision, NULL_REVISION, WORKING_DIRECTORY_HEX};
@@ -17,7 +16,7 @@
     input: &str,
     repo: &Repo,
 ) -> Result<Revision, RevlogError> {
-    let changelog = Changelog::open(repo)?;
+    let changelog = repo.changelog()?;
 
     match resolve_rev_number_or_hex_prefix(input, &changelog.revlog) {
         Err(RevlogError::InvalidRevision) => {} // Try other syntax