Mercurial > hg
diff rust/hg-core/src/repo.rs @ 48419:c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Unify with the same abstraction used for other lazily-initialized components
Differential Revision: https://phab.mercurial-scm.org/D11837
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 29 Nov 2021 19:00:11 +0100 |
parents | 5734b03ecf3e |
children | c7c23bb036c9 |
line wrap: on
line diff
--- a/rust/hg-core/src/repo.rs Mon Nov 29 18:46:04 2021 +0100 +++ b/rust/hg-core/src/repo.rs Mon Nov 29 19:00:11 2021 +0100 @@ -16,7 +16,7 @@ use crate::vfs::{is_dir, is_file, Vfs}; use crate::{requirements, NodePrefix}; use crate::{DirstateError, Revision}; -use std::cell::{Cell, Ref, RefCell, RefMut}; +use std::cell::{Ref, RefCell, RefMut}; use std::collections::HashSet; use std::path::{Path, PathBuf}; @@ -27,8 +27,7 @@ store: PathBuf, requirements: HashSet<String>, config: Config, - // None means not known/initialized yet - dirstate_parents: Cell<Option<DirstateParents>>, + dirstate_parents: LazyCell<DirstateParents, HgError>, dirstate_map: LazyCell<OwningDirstateMap, DirstateError>, changelog: LazyCell<Changelog, HgError>, manifestlog: LazyCell<Manifestlog, HgError>, @@ -203,7 +202,7 @@ store: store_path, dot_hg, config: repo_config, - dirstate_parents: Cell::new(None), + dirstate_parents: LazyCell::new(Self::read_dirstate_parents), dirstate_map: LazyCell::new(Self::new_dirstate_map), changelog: LazyCell::new(Changelog::open), manifestlog: LazyCell::new(Manifestlog::open), @@ -273,9 +272,10 @@ } pub fn dirstate_parents(&self) -> Result<DirstateParents, HgError> { - if let Some(parents) = self.dirstate_parents.get() { - return Ok(parents); - } + Ok(*self.dirstate_parents.get_or_init(self)?) + } + + fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> { let dirstate = self.dirstate_file_contents()?; let parents = if dirstate.is_empty() { DirstateParents::NULL @@ -285,20 +285,20 @@ crate::dirstate::parsers::parse_dirstate_parents(&dirstate)? .clone() }; - self.dirstate_parents.set(Some(parents)); + self.dirstate_parents.set(parents); Ok(parents) } 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(Some(DirstateParents::NULL)); + self.dirstate_parents.set(DirstateParents::NULL); 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(Some(docket.parents())); + self.dirstate_parents.set(docket.parents()); let data_size = docket.data_size(); let metadata = docket.tree_metadata(); let mut map = if let Some(data_mmap) = self @@ -318,7 +318,7 @@ let (on_disk, placeholder) = map.get_pair_mut(); let (inner, parents) = DirstateMap::new_v1(on_disk)?; self.dirstate_parents - .set(Some(parents.unwrap_or(DirstateParents::NULL))); + .set(parents.unwrap_or(DirstateParents::NULL)); *placeholder = inner; Ok(map) } @@ -402,6 +402,10 @@ } } + fn set(&self, value: T) { + *self.value.borrow_mut() = Some(value) + } + fn get_or_init(&self, repo: &Repo) -> Result<Ref<T>, E> { let mut borrowed = self.value.borrow(); if borrowed.is_none() { @@ -415,7 +419,7 @@ Ok(Ref::map(borrowed, |option| option.as_ref().unwrap())) } - pub fn get_mut_or_init(&self, repo: &Repo) -> Result<RefMut<T>, E> { + fn get_mut_or_init(&self, repo: &Repo) -> Result<RefMut<T>, E> { let mut borrowed = self.value.borrow_mut(); if borrowed.is_none() { *borrowed = Some((self.init)(repo)?);