##// END OF EJS Templates
rhg: Make Repo::dirstate_parents a LazyCell...
Simon Sapin -
r49247:c8659e61 default
parent child Browse files
Show More
@@ -16,7 +16,7 b' use crate::utils::SliceExt;'
16 use crate::vfs::{is_dir, is_file, Vfs};
16 use crate::vfs::{is_dir, is_file, Vfs};
17 use crate::{requirements, NodePrefix};
17 use crate::{requirements, NodePrefix};
18 use crate::{DirstateError, Revision};
18 use crate::{DirstateError, Revision};
19 use std::cell::{Cell, Ref, RefCell, RefMut};
19 use std::cell::{Ref, RefCell, RefMut};
20 use std::collections::HashSet;
20 use std::collections::HashSet;
21 use std::path::{Path, PathBuf};
21 use std::path::{Path, PathBuf};
22
22
@@ -27,8 +27,7 b' pub struct Repo {'
27 store: PathBuf,
27 store: PathBuf,
28 requirements: HashSet<String>,
28 requirements: HashSet<String>,
29 config: Config,
29 config: Config,
30 // None means not known/initialized yet
30 dirstate_parents: LazyCell<DirstateParents, HgError>,
31 dirstate_parents: Cell<Option<DirstateParents>>,
32 dirstate_map: LazyCell<OwningDirstateMap, DirstateError>,
31 dirstate_map: LazyCell<OwningDirstateMap, DirstateError>,
33 changelog: LazyCell<Changelog, HgError>,
32 changelog: LazyCell<Changelog, HgError>,
34 manifestlog: LazyCell<Manifestlog, HgError>,
33 manifestlog: LazyCell<Manifestlog, HgError>,
@@ -203,7 +202,7 b' impl Repo {'
203 store: store_path,
202 store: store_path,
204 dot_hg,
203 dot_hg,
205 config: repo_config,
204 config: repo_config,
206 dirstate_parents: Cell::new(None),
205 dirstate_parents: LazyCell::new(Self::read_dirstate_parents),
207 dirstate_map: LazyCell::new(Self::new_dirstate_map),
206 dirstate_map: LazyCell::new(Self::new_dirstate_map),
208 changelog: LazyCell::new(Changelog::open),
207 changelog: LazyCell::new(Changelog::open),
209 manifestlog: LazyCell::new(Manifestlog::open),
208 manifestlog: LazyCell::new(Manifestlog::open),
@@ -273,9 +272,10 b' impl Repo {'
273 }
272 }
274
273
275 pub fn dirstate_parents(&self) -> Result<DirstateParents, HgError> {
274 pub fn dirstate_parents(&self) -> Result<DirstateParents, HgError> {
276 if let Some(parents) = self.dirstate_parents.get() {
275 Ok(*self.dirstate_parents.get_or_init(self)?)
277 return Ok(parents);
276 }
278 }
277
278 fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> {
279 let dirstate = self.dirstate_file_contents()?;
279 let dirstate = self.dirstate_file_contents()?;
280 let parents = if dirstate.is_empty() {
280 let parents = if dirstate.is_empty() {
281 DirstateParents::NULL
281 DirstateParents::NULL
@@ -285,20 +285,20 b' impl Repo {'
285 crate::dirstate::parsers::parse_dirstate_parents(&dirstate)?
285 crate::dirstate::parsers::parse_dirstate_parents(&dirstate)?
286 .clone()
286 .clone()
287 };
287 };
288 self.dirstate_parents.set(Some(parents));
288 self.dirstate_parents.set(parents);
289 Ok(parents)
289 Ok(parents)
290 }
290 }
291
291
292 fn new_dirstate_map(&self) -> Result<OwningDirstateMap, DirstateError> {
292 fn new_dirstate_map(&self) -> Result<OwningDirstateMap, DirstateError> {
293 let dirstate_file_contents = self.dirstate_file_contents()?;
293 let dirstate_file_contents = self.dirstate_file_contents()?;
294 if dirstate_file_contents.is_empty() {
294 if dirstate_file_contents.is_empty() {
295 self.dirstate_parents.set(Some(DirstateParents::NULL));
295 self.dirstate_parents.set(DirstateParents::NULL);
296 Ok(OwningDirstateMap::new_empty(Vec::new()))
296 Ok(OwningDirstateMap::new_empty(Vec::new()))
297 } else if self.has_dirstate_v2() {
297 } else if self.has_dirstate_v2() {
298 let docket = crate::dirstate_tree::on_disk::read_docket(
298 let docket = crate::dirstate_tree::on_disk::read_docket(
299 &dirstate_file_contents,
299 &dirstate_file_contents,
300 )?;
300 )?;
301 self.dirstate_parents.set(Some(docket.parents()));
301 self.dirstate_parents.set(docket.parents());
302 let data_size = docket.data_size();
302 let data_size = docket.data_size();
303 let metadata = docket.tree_metadata();
303 let metadata = docket.tree_metadata();
304 let mut map = if let Some(data_mmap) = self
304 let mut map = if let Some(data_mmap) = self
@@ -318,7 +318,7 b' impl Repo {'
318 let (on_disk, placeholder) = map.get_pair_mut();
318 let (on_disk, placeholder) = map.get_pair_mut();
319 let (inner, parents) = DirstateMap::new_v1(on_disk)?;
319 let (inner, parents) = DirstateMap::new_v1(on_disk)?;
320 self.dirstate_parents
320 self.dirstate_parents
321 .set(Some(parents.unwrap_or(DirstateParents::NULL)));
321 .set(parents.unwrap_or(DirstateParents::NULL));
322 *placeholder = inner;
322 *placeholder = inner;
323 Ok(map)
323 Ok(map)
324 }
324 }
@@ -402,6 +402,10 b' impl<T, E> LazyCell<T, E> {'
402 }
402 }
403 }
403 }
404
404
405 fn set(&self, value: T) {
406 *self.value.borrow_mut() = Some(value)
407 }
408
405 fn get_or_init(&self, repo: &Repo) -> Result<Ref<T>, E> {
409 fn get_or_init(&self, repo: &Repo) -> Result<Ref<T>, E> {
406 let mut borrowed = self.value.borrow();
410 let mut borrowed = self.value.borrow();
407 if borrowed.is_none() {
411 if borrowed.is_none() {
@@ -415,7 +419,7 b' impl<T, E> LazyCell<T, E> {'
415 Ok(Ref::map(borrowed, |option| option.as_ref().unwrap()))
419 Ok(Ref::map(borrowed, |option| option.as_ref().unwrap()))
416 }
420 }
417
421
418 pub fn get_mut_or_init(&self, repo: &Repo) -> Result<RefMut<T>, E> {
422 fn get_mut_or_init(&self, repo: &Repo) -> Result<RefMut<T>, E> {
419 let mut borrowed = self.value.borrow_mut();
423 let mut borrowed = self.value.borrow_mut();
420 if borrowed.is_none() {
424 if borrowed.is_none() {
421 *borrowed = Some((self.init)(repo)?);
425 *borrowed = Some((self.init)(repo)?);
General Comments 0
You need to be logged in to leave comments. Login now