Mercurial > hg
changeset 48420:c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
The `dirstate_parents`, `dirstate_data_file_uuid`, and `dirstate_map` members
of `Repo` can be access in any order and the `.hg/dirstate` file should only
be opened once.
Differential Revision: https://phab.mercurial-scm.org/D11838
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Thu, 02 Dec 2021 12:05:36 +0100 |
parents | c8659e61073d |
children | 2097f63575a5 |
files | rust/hg-core/src/dirstate_tree/on_disk.rs rust/hg-core/src/repo.rs |
diffstat | 2 files changed, 37 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/dirstate_tree/on_disk.rs Mon Nov 29 19:00:11 2021 +0100 +++ b/rust/hg-core/src/dirstate_tree/on_disk.rs Thu Dec 02 12:05:36 2021 +0100 @@ -61,7 +61,7 @@ pub struct Docket<'on_disk> { header: &'on_disk DocketHeader, - uuid: &'on_disk [u8], + pub uuid: &'on_disk [u8], } /// Fields are documented in the *Tree metadata in the docket file*
--- a/rust/hg-core/src/repo.rs Mon Nov 29 19:00:11 2021 +0100 +++ b/rust/hg-core/src/repo.rs Thu Dec 02 12:05:36 2021 +0100 @@ -28,6 +28,7 @@ requirements: HashSet<String>, config: Config, dirstate_parents: LazyCell<DirstateParents, HgError>, + dirstate_data_file_uuid: LazyCell<Option<Vec<u8>>, HgError>, dirstate_map: LazyCell<OwningDirstateMap, DirstateError>, changelog: LazyCell<Changelog, HgError>, manifestlog: LazyCell<Manifestlog, HgError>, @@ -203,6 +204,9 @@ dot_hg, config: repo_config, dirstate_parents: LazyCell::new(Self::read_dirstate_parents), + dirstate_data_file_uuid: LazyCell::new( + Self::read_dirstate_data_file_uuid, + ), dirstate_map: LazyCell::new(Self::new_dirstate_map), changelog: LazyCell::new(Changelog::open), manifestlog: LazyCell::new(Manifestlog::open), @@ -278,9 +282,16 @@ fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> { let dirstate = self.dirstate_file_contents()?; let parents = if dirstate.is_empty() { + if self.has_dirstate_v2() { + self.dirstate_data_file_uuid.set(None); + } DirstateParents::NULL } else if self.has_dirstate_v2() { - crate::dirstate_tree::on_disk::read_docket(&dirstate)?.parents() + let docket = + crate::dirstate_tree::on_disk::read_docket(&dirstate)?; + self.dirstate_data_file_uuid + .set(Some(docket.uuid.to_owned())); + docket.parents() } else { crate::dirstate::parsers::parse_dirstate_parents(&dirstate)? .clone() @@ -289,16 +300,40 @@ Ok(parents) } + fn read_dirstate_data_file_uuid( + &self, + ) -> Result<Option<Vec<u8>>, HgError> { + assert!( + self.has_dirstate_v2(), + "accessing dirstate data file ID without dirstate-v2" + ); + let dirstate = self.dirstate_file_contents()?; + if dirstate.is_empty() { + self.dirstate_parents.set(DirstateParents::NULL); + Ok(None) + } else { + let docket = + crate::dirstate_tree::on_disk::read_docket(&dirstate)?; + self.dirstate_parents.set(docket.parents()); + Ok(Some(docket.uuid.to_owned())) + } + } + fn new_dirstate_map(&self) -> Result<OwningDirstateMap, DirstateError> { let dirstate_file_contents = self.dirstate_file_contents()?; if dirstate_file_contents.is_empty() { self.dirstate_parents.set(DirstateParents::NULL); + if self.has_dirstate_v2() { + self.dirstate_data_file_uuid.set(None); + } Ok(OwningDirstateMap::new_empty(Vec::new())) } else if self.has_dirstate_v2() { let docket = crate::dirstate_tree::on_disk::read_docket( &dirstate_file_contents, )?; self.dirstate_parents.set(docket.parents()); + self.dirstate_data_file_uuid + .set(Some(docket.uuid.to_owned())); let data_size = docket.data_size(); let metadata = docket.tree_metadata(); let mut map = if let Some(data_mmap) = self