Show More
@@ -29,11 +29,11 b' pub struct Repo {' | |||||
29 | store: PathBuf, |
|
29 | store: PathBuf, | |
30 | requirements: HashSet<String>, |
|
30 | requirements: HashSet<String>, | |
31 | config: Config, |
|
31 | config: Config, | |
32 |
dirstate_parents: LazyCell<DirstateParents |
|
32 | dirstate_parents: LazyCell<DirstateParents>, | |
33 |
dirstate_data_file_uuid: LazyCell<Option<Vec<u8>> |
|
33 | dirstate_data_file_uuid: LazyCell<Option<Vec<u8>>>, | |
34 |
dirstate_map: LazyCell<OwningDirstateMap |
|
34 | dirstate_map: LazyCell<OwningDirstateMap>, | |
35 |
changelog: LazyCell<Changelog |
|
35 | changelog: LazyCell<Changelog>, | |
36 |
manifestlog: LazyCell<Manifestlog |
|
36 | manifestlog: LazyCell<Manifestlog>, | |
37 | } |
|
37 | } | |
38 |
|
38 | |||
39 | #[derive(Debug, derive_more::From)] |
|
39 | #[derive(Debug, derive_more::From)] | |
@@ -182,13 +182,11 b' impl Repo {' | |||||
182 | store: store_path, |
|
182 | store: store_path, | |
183 | dot_hg, |
|
183 | dot_hg, | |
184 | config: repo_config, |
|
184 | config: repo_config, | |
185 |
dirstate_parents: LazyCell::new( |
|
185 | dirstate_parents: LazyCell::new(), | |
186 | dirstate_data_file_uuid: LazyCell::new( |
|
186 | dirstate_data_file_uuid: LazyCell::new(), | |
187 | Self::read_dirstate_data_file_uuid, |
|
187 | dirstate_map: LazyCell::new(), | |
188 | ), |
|
188 | changelog: LazyCell::new(), | |
189 |
|
|
189 | manifestlog: LazyCell::new(), | |
190 | changelog: LazyCell::new(Self::new_changelog), |
|
|||
191 | manifestlog: LazyCell::new(Self::new_manifestlog), |
|
|||
192 | }; |
|
190 | }; | |
193 |
|
191 | |||
194 | requirements::check(&repo)?; |
|
192 | requirements::check(&repo)?; | |
@@ -260,7 +258,9 b' impl Repo {' | |||||
260 | } |
|
258 | } | |
261 |
|
259 | |||
262 | pub fn dirstate_parents(&self) -> Result<DirstateParents, HgError> { |
|
260 | pub fn dirstate_parents(&self) -> Result<DirstateParents, HgError> { | |
263 | Ok(*self.dirstate_parents.get_or_init(self)?) |
|
261 | Ok(*self | |
|
262 | .dirstate_parents | |||
|
263 | .get_or_init(|| self.read_dirstate_parents())?) | |||
264 | } |
|
264 | } | |
265 |
|
265 | |||
266 | fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> { |
|
266 | fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> { | |
@@ -340,13 +340,14 b' impl Repo {' | |||||
340 | pub fn dirstate_map( |
|
340 | pub fn dirstate_map( | |
341 | &self, |
|
341 | &self, | |
342 | ) -> Result<Ref<OwningDirstateMap>, DirstateError> { |
|
342 | ) -> Result<Ref<OwningDirstateMap>, DirstateError> { | |
343 | self.dirstate_map.get_or_init(self) |
|
343 | self.dirstate_map.get_or_init(|| self.new_dirstate_map()) | |
344 | } |
|
344 | } | |
345 |
|
345 | |||
346 | pub fn dirstate_map_mut( |
|
346 | pub fn dirstate_map_mut( | |
347 | &self, |
|
347 | &self, | |
348 | ) -> Result<RefMut<OwningDirstateMap>, DirstateError> { |
|
348 | ) -> Result<RefMut<OwningDirstateMap>, DirstateError> { | |
349 |
self.dirstate_map |
|
349 | self.dirstate_map | |
|
350 | .get_mut_or_init(|| self.new_dirstate_map()) | |||
350 | } |
|
351 | } | |
351 |
|
352 | |||
352 | fn new_changelog(&self) -> Result<Changelog, HgError> { |
|
353 | fn new_changelog(&self) -> Result<Changelog, HgError> { | |
@@ -354,11 +355,11 b' impl Repo {' | |||||
354 | } |
|
355 | } | |
355 |
|
356 | |||
356 | pub fn changelog(&self) -> Result<Ref<Changelog>, HgError> { |
|
357 | pub fn changelog(&self) -> Result<Ref<Changelog>, HgError> { | |
357 | self.changelog.get_or_init(self) |
|
358 | self.changelog.get_or_init(|| self.new_changelog()) | |
358 | } |
|
359 | } | |
359 |
|
360 | |||
360 | pub fn changelog_mut(&self) -> Result<RefMut<Changelog>, HgError> { |
|
361 | pub fn changelog_mut(&self) -> Result<RefMut<Changelog>, HgError> { | |
361 | self.changelog.get_mut_or_init(self) |
|
362 | self.changelog.get_mut_or_init(|| self.new_changelog()) | |
362 | } |
|
363 | } | |
363 |
|
364 | |||
364 | fn new_manifestlog(&self) -> Result<Manifestlog, HgError> { |
|
365 | fn new_manifestlog(&self) -> Result<Manifestlog, HgError> { | |
@@ -366,11 +367,11 b' impl Repo {' | |||||
366 | } |
|
367 | } | |
367 |
|
368 | |||
368 | pub fn manifestlog(&self) -> Result<Ref<Manifestlog>, HgError> { |
|
369 | pub fn manifestlog(&self) -> Result<Ref<Manifestlog>, HgError> { | |
369 | self.manifestlog.get_or_init(self) |
|
370 | self.manifestlog.get_or_init(|| self.new_manifestlog()) | |
370 | } |
|
371 | } | |
371 |
|
372 | |||
372 | pub fn manifestlog_mut(&self) -> Result<RefMut<Manifestlog>, HgError> { |
|
373 | pub fn manifestlog_mut(&self) -> Result<RefMut<Manifestlog>, HgError> { | |
373 | self.manifestlog.get_mut_or_init(self) |
|
374 | self.manifestlog.get_mut_or_init(|| self.new_manifestlog()) | |
374 | } |
|
375 | } | |
375 |
|
376 | |||
376 | /// Returns the manifest of the *changeset* with the given node ID |
|
377 | /// Returns the manifest of the *changeset* with the given node ID | |
@@ -424,7 +425,9 b' impl Repo {' | |||||
424 | // itβs unset |
|
425 | // itβs unset | |
425 | let parents = self.dirstate_parents()?; |
|
426 | let parents = self.dirstate_parents()?; | |
426 | let (packed_dirstate, old_uuid_to_remove) = if self.has_dirstate_v2() { |
|
427 | let (packed_dirstate, old_uuid_to_remove) = if self.has_dirstate_v2() { | |
427 | let uuid_opt = self.dirstate_data_file_uuid.get_or_init(self)?; |
|
428 | let uuid_opt = self | |
|
429 | .dirstate_data_file_uuid | |||
|
430 | .get_or_init(|| self.read_dirstate_data_file_uuid())?; | |||
428 | let uuid_opt = uuid_opt.as_ref(); |
|
431 | let uuid_opt = uuid_opt.as_ref(); | |
429 | let can_append = uuid_opt.is_some(); |
|
432 | let can_append = uuid_opt.is_some(); | |
430 | let (data, tree_metadata, append, old_data_size) = |
|
433 | let (data, tree_metadata, append, old_data_size) = | |
@@ -508,19 +511,17 b' impl Repo {' | |||||
508 | /// Lazily-initialized component of `Repo` with interior mutability |
|
511 | /// Lazily-initialized component of `Repo` with interior mutability | |
509 | /// |
|
512 | /// | |
510 | /// This differs from `OnceCell` in that the value can still be "deinitialized" |
|
513 | /// This differs from `OnceCell` in that the value can still be "deinitialized" | |
511 | /// later by setting its inner `Option` to `None`. |
|
514 | /// later by setting its inner `Option` to `None`. It also takes the | |
512 | struct LazyCell<T, E> { |
|
515 | /// initialization function as an argument when the value is requested, not | |
|
516 | /// when the instance is created. | |||
|
517 | struct LazyCell<T> { | |||
513 | value: RefCell<Option<T>>, |
|
518 | value: RefCell<Option<T>>, | |
514 | // `Fn`s that donβt capture environment are zero-size, so this box does |
|
|||
515 | // not allocate: |
|
|||
516 | init: Box<dyn Fn(&Repo) -> Result<T, E>>, |
|
|||
517 | } |
|
519 | } | |
518 |
|
520 | |||
519 |
impl<T |
|
521 | impl<T> LazyCell<T> { | |
520 | fn new(init: impl Fn(&Repo) -> Result<T, E> + 'static) -> Self { |
|
522 | fn new() -> Self { | |
521 | Self { |
|
523 | Self { | |
522 | value: RefCell::new(None), |
|
524 | value: RefCell::new(None), | |
523 | init: Box::new(init), |
|
|||
524 | } |
|
525 | } | |
525 | } |
|
526 | } | |
526 |
|
527 | |||
@@ -528,23 +529,29 b' impl<T, E> LazyCell<T, E> {' | |||||
528 | *self.value.borrow_mut() = Some(value) |
|
529 | *self.value.borrow_mut() = Some(value) | |
529 | } |
|
530 | } | |
530 |
|
531 | |||
531 | fn get_or_init(&self, repo: &Repo) -> Result<Ref<T>, E> { |
|
532 | fn get_or_init<E>( | |
|
533 | &self, | |||
|
534 | init: impl Fn() -> Result<T, E>, | |||
|
535 | ) -> Result<Ref<T>, E> { | |||
532 | let mut borrowed = self.value.borrow(); |
|
536 | let mut borrowed = self.value.borrow(); | |
533 | if borrowed.is_none() { |
|
537 | if borrowed.is_none() { | |
534 | drop(borrowed); |
|
538 | drop(borrowed); | |
535 | // Only use `borrow_mut` if it is really needed to avoid panic in |
|
539 | // Only use `borrow_mut` if it is really needed to avoid panic in | |
536 | // case there is another outstanding borrow but mutation is not |
|
540 | // case there is another outstanding borrow but mutation is not | |
537 | // needed. |
|
541 | // needed. | |
538 |
*self.value.borrow_mut() = Some(( |
|
542 | *self.value.borrow_mut() = Some(init()?); | |
539 | borrowed = self.value.borrow() |
|
543 | borrowed = self.value.borrow() | |
540 | } |
|
544 | } | |
541 | Ok(Ref::map(borrowed, |option| option.as_ref().unwrap())) |
|
545 | Ok(Ref::map(borrowed, |option| option.as_ref().unwrap())) | |
542 | } |
|
546 | } | |
543 |
|
547 | |||
544 | fn get_mut_or_init(&self, repo: &Repo) -> Result<RefMut<T>, E> { |
|
548 | fn get_mut_or_init<E>( | |
|
549 | &self, | |||
|
550 | init: impl Fn() -> Result<T, E>, | |||
|
551 | ) -> Result<RefMut<T>, E> { | |||
545 | let mut borrowed = self.value.borrow_mut(); |
|
552 | let mut borrowed = self.value.borrow_mut(); | |
546 | if borrowed.is_none() { |
|
553 | if borrowed.is_none() { | |
547 |
*borrowed = Some(( |
|
554 | *borrowed = Some(init()?); | |
548 | } |
|
555 | } | |
549 | Ok(RefMut::map(borrowed, |option| option.as_mut().unwrap())) |
|
556 | Ok(RefMut::map(borrowed, |option| option.as_mut().unwrap())) | |
550 | } |
|
557 | } |
General Comments 0
You need to be logged in to leave comments.
Login now