comparison rust/hg-core/src/repo.rs @ 51188:13f58ce70299

rust-revlog: teach the revlog opening code to read the repo options This will become necessary as we start writing revlog data from Rust.
author Rapha?l Gom?s <rgomes@octobus.net>
date Mon, 18 Sep 2023 17:11:11 +0200
parents 532e74ad3ff6
children 69b804c8e09e
comparison
equal deleted inserted replaced
51187:6ec8387eb0be 51188:13f58ce70299
6 use crate::dirstate_tree::owning::OwningDirstateMap; 6 use crate::dirstate_tree::owning::OwningDirstateMap;
7 use crate::errors::HgResultExt; 7 use crate::errors::HgResultExt;
8 use crate::errors::{HgError, IoResultExt}; 8 use crate::errors::{HgError, IoResultExt};
9 use crate::lock::{try_with_lock_no_wait, LockError}; 9 use crate::lock::{try_with_lock_no_wait, LockError};
10 use crate::manifest::{Manifest, Manifestlog}; 10 use crate::manifest::{Manifest, Manifestlog};
11 use crate::requirements::{
12 CHANGELOGV2_REQUIREMENT, GENERALDELTA_REQUIREMENT, NODEMAP_REQUIREMENT,
13 REVLOGV1_REQUIREMENT, REVLOGV2_REQUIREMENT,
14 };
11 use crate::revlog::filelog::Filelog; 15 use crate::revlog::filelog::Filelog;
12 use crate::revlog::RevlogError; 16 use crate::revlog::RevlogError;
13 use crate::utils::debug::debug_wait_for_file_or_print; 17 use crate::utils::debug::debug_wait_for_file_or_print;
14 use crate::utils::files::get_path_from_bytes; 18 use crate::utils::files::get_path_from_bytes;
15 use crate::utils::hg_path::HgPath; 19 use crate::utils::hg_path::HgPath;
16 use crate::utils::SliceExt; 20 use crate::utils::SliceExt;
17 use crate::vfs::{is_dir, is_file, Vfs}; 21 use crate::vfs::{is_dir, is_file, Vfs};
18 use crate::DirstateError; 22 use crate::{
19 use crate::{requirements, NodePrefix, UncheckedRevision}; 23 requirements, NodePrefix, RevlogVersionOptions, UncheckedRevision,
24 };
25 use crate::{DirstateError, RevlogOpenOptions};
20 use std::cell::{Ref, RefCell, RefMut}; 26 use std::cell::{Ref, RefCell, RefMut};
21 use std::collections::HashSet; 27 use std::collections::HashSet;
22 use std::io::Seek; 28 use std::io::Seek;
23 use std::io::SeekFrom; 29 use std::io::SeekFrom;
24 use std::io::Write as IoWrite; 30 use std::io::Write as IoWrite;
521 self.dirstate_map 527 self.dirstate_map
522 .get_mut_or_init(|| self.new_dirstate_map()) 528 .get_mut_or_init(|| self.new_dirstate_map())
523 } 529 }
524 530
525 fn new_changelog(&self) -> Result<Changelog, HgError> { 531 fn new_changelog(&self) -> Result<Changelog, HgError> {
526 Changelog::open(&self.store_vfs(), self.has_nodemap()) 532 Changelog::open(&self.store_vfs(), self.default_revlog_options(true)?)
527 } 533 }
528 534
529 pub fn changelog(&self) -> Result<Ref<Changelog>, HgError> { 535 pub fn changelog(&self) -> Result<Ref<Changelog>, HgError> {
530 self.changelog.get_or_init(|| self.new_changelog()) 536 self.changelog.get_or_init(|| self.new_changelog())
531 } 537 }
533 pub fn changelog_mut(&self) -> Result<RefMut<Changelog>, HgError> { 539 pub fn changelog_mut(&self) -> Result<RefMut<Changelog>, HgError> {
534 self.changelog.get_mut_or_init(|| self.new_changelog()) 540 self.changelog.get_mut_or_init(|| self.new_changelog())
535 } 541 }
536 542
537 fn new_manifestlog(&self) -> Result<Manifestlog, HgError> { 543 fn new_manifestlog(&self) -> Result<Manifestlog, HgError> {
538 Manifestlog::open(&self.store_vfs(), self.has_nodemap()) 544 Manifestlog::open(
545 &self.store_vfs(),
546 self.default_revlog_options(false)?,
547 )
539 } 548 }
540 549
541 pub fn manifestlog(&self) -> Result<Ref<Manifestlog>, HgError> { 550 pub fn manifestlog(&self) -> Result<Ref<Manifestlog>, HgError> {
542 self.manifestlog.get_or_init(|| self.new_manifestlog()) 551 self.manifestlog.get_or_init(|| self.new_manifestlog())
543 } 552 }
579 Ok(false) 588 Ok(false)
580 } 589 }
581 } 590 }
582 591
583 pub fn filelog(&self, path: &HgPath) -> Result<Filelog, HgError> { 592 pub fn filelog(&self, path: &HgPath) -> Result<Filelog, HgError> {
584 Filelog::open(self, path) 593 Filelog::open(self, path, self.default_revlog_options(false)?)
585 } 594 }
586 595
587 /// Write to disk any updates that were made through `dirstate_map_mut`. 596 /// Write to disk any updates that were made through `dirstate_map_mut`.
588 /// 597 ///
589 /// The "wlock" must be held while calling this. 598 /// The "wlock" must be held while calling this.
728 // new data file was written. 737 // new data file was written.
729 vfs.remove_file(format!("dirstate.{}", uuid))?; 738 vfs.remove_file(format!("dirstate.{}", uuid))?;
730 } 739 }
731 Ok(()) 740 Ok(())
732 } 741 }
742
743 pub fn default_revlog_options(
744 &self,
745 changelog: bool,
746 ) -> Result<RevlogOpenOptions, HgError> {
747 let requirements = self.requirements();
748 let version = if changelog
749 && requirements.contains(CHANGELOGV2_REQUIREMENT)
750 {
751 let compute_rank = self
752 .config()
753 .get_bool(b"experimental", b"changelog-v2.compute-rank")?;
754 RevlogVersionOptions::ChangelogV2 { compute_rank }
755 } else if requirements.contains(REVLOGV2_REQUIREMENT) {
756 RevlogVersionOptions::V2
757 } else if requirements.contains(REVLOGV1_REQUIREMENT) {
758 RevlogVersionOptions::V1 {
759 generaldelta: requirements.contains(GENERALDELTA_REQUIREMENT),
760 }
761 } else {
762 RevlogVersionOptions::V0
763 };
764 Ok(RevlogOpenOptions {
765 version,
766 // We don't need to dance around the slow path like in the Python
767 // implementation since we know we have access to the fast code.
768 use_nodemap: requirements.contains(NODEMAP_REQUIREMENT),
769 })
770 }
733 } 771 }
734 772
735 /// Lazily-initialized component of `Repo` with interior mutability 773 /// Lazily-initialized component of `Repo` with interior mutability
736 /// 774 ///
737 /// This differs from `OnceCell` in that the value can still be "deinitialized" 775 /// This differs from `OnceCell` in that the value can still be "deinitialized"