Mercurial > public > mercurial-scm > hg
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()) |