comparison rust/hg-core/src/repo.rs @ 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
comparison
equal deleted inserted replaced
48419:c8659e61073d 48420:c7c23bb036c9
26 dot_hg: PathBuf, 26 dot_hg: PathBuf,
27 store: PathBuf, 27 store: PathBuf,
28 requirements: HashSet<String>, 28 requirements: HashSet<String>,
29 config: Config, 29 config: Config,
30 dirstate_parents: LazyCell<DirstateParents, HgError>, 30 dirstate_parents: LazyCell<DirstateParents, HgError>,
31 dirstate_data_file_uuid: LazyCell<Option<Vec<u8>>, HgError>,
31 dirstate_map: LazyCell<OwningDirstateMap, DirstateError>, 32 dirstate_map: LazyCell<OwningDirstateMap, DirstateError>,
32 changelog: LazyCell<Changelog, HgError>, 33 changelog: LazyCell<Changelog, HgError>,
33 manifestlog: LazyCell<Manifestlog, HgError>, 34 manifestlog: LazyCell<Manifestlog, HgError>,
34 } 35 }
35 36
201 working_directory, 202 working_directory,
202 store: store_path, 203 store: store_path,
203 dot_hg, 204 dot_hg,
204 config: repo_config, 205 config: repo_config,
205 dirstate_parents: LazyCell::new(Self::read_dirstate_parents), 206 dirstate_parents: LazyCell::new(Self::read_dirstate_parents),
207 dirstate_data_file_uuid: LazyCell::new(
208 Self::read_dirstate_data_file_uuid,
209 ),
206 dirstate_map: LazyCell::new(Self::new_dirstate_map), 210 dirstate_map: LazyCell::new(Self::new_dirstate_map),
207 changelog: LazyCell::new(Changelog::open), 211 changelog: LazyCell::new(Changelog::open),
208 manifestlog: LazyCell::new(Manifestlog::open), 212 manifestlog: LazyCell::new(Manifestlog::open),
209 }; 213 };
210 214
276 } 280 }
277 281
278 fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> { 282 fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> {
279 let dirstate = self.dirstate_file_contents()?; 283 let dirstate = self.dirstate_file_contents()?;
280 let parents = if dirstate.is_empty() { 284 let parents = if dirstate.is_empty() {
285 if self.has_dirstate_v2() {
286 self.dirstate_data_file_uuid.set(None);
287 }
281 DirstateParents::NULL 288 DirstateParents::NULL
282 } else if self.has_dirstate_v2() { 289 } else if self.has_dirstate_v2() {
283 crate::dirstate_tree::on_disk::read_docket(&dirstate)?.parents() 290 let docket =
291 crate::dirstate_tree::on_disk::read_docket(&dirstate)?;
292 self.dirstate_data_file_uuid
293 .set(Some(docket.uuid.to_owned()));
294 docket.parents()
284 } else { 295 } else {
285 crate::dirstate::parsers::parse_dirstate_parents(&dirstate)? 296 crate::dirstate::parsers::parse_dirstate_parents(&dirstate)?
286 .clone() 297 .clone()
287 }; 298 };
288 self.dirstate_parents.set(parents); 299 self.dirstate_parents.set(parents);
289 Ok(parents) 300 Ok(parents)
290 } 301 }
291 302
303 fn read_dirstate_data_file_uuid(
304 &self,
305 ) -> Result<Option<Vec<u8>>, HgError> {
306 assert!(
307 self.has_dirstate_v2(),
308 "accessing dirstate data file ID without dirstate-v2"
309 );
310 let dirstate = self.dirstate_file_contents()?;
311 if dirstate.is_empty() {
312 self.dirstate_parents.set(DirstateParents::NULL);
313 Ok(None)
314 } else {
315 let docket =
316 crate::dirstate_tree::on_disk::read_docket(&dirstate)?;
317 self.dirstate_parents.set(docket.parents());
318 Ok(Some(docket.uuid.to_owned()))
319 }
320 }
321
292 fn new_dirstate_map(&self) -> Result<OwningDirstateMap, DirstateError> { 322 fn new_dirstate_map(&self) -> Result<OwningDirstateMap, DirstateError> {
293 let dirstate_file_contents = self.dirstate_file_contents()?; 323 let dirstate_file_contents = self.dirstate_file_contents()?;
294 if dirstate_file_contents.is_empty() { 324 if dirstate_file_contents.is_empty() {
295 self.dirstate_parents.set(DirstateParents::NULL); 325 self.dirstate_parents.set(DirstateParents::NULL);
326 if self.has_dirstate_v2() {
327 self.dirstate_data_file_uuid.set(None);
328 }
296 Ok(OwningDirstateMap::new_empty(Vec::new())) 329 Ok(OwningDirstateMap::new_empty(Vec::new()))
297 } else if self.has_dirstate_v2() { 330 } else if self.has_dirstate_v2() {
298 let docket = crate::dirstate_tree::on_disk::read_docket( 331 let docket = crate::dirstate_tree::on_disk::read_docket(
299 &dirstate_file_contents, 332 &dirstate_file_contents,
300 )?; 333 )?;
301 self.dirstate_parents.set(docket.parents()); 334 self.dirstate_parents.set(docket.parents());
335 self.dirstate_data_file_uuid
336 .set(Some(docket.uuid.to_owned()));
302 let data_size = docket.data_size(); 337 let data_size = docket.data_size();
303 let metadata = docket.tree_metadata(); 338 let metadata = docket.tree_metadata();
304 let mut map = if let Some(data_mmap) = self 339 let mut map = if let Some(data_mmap) = self
305 .hg_vfs() 340 .hg_vfs()
306 .mmap_open(docket.data_filename()) 341 .mmap_open(docket.data_filename())