Mercurial > hg
changeset 51867:69b804c8e09e
rust: use new revlog configs in all revlog opening code
This centralizes the more complex logic needed for the upcoming code
and creates stronger APIs with fewer booleans.
We also reuse `RevlogType` where needed.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Wed, 19 Jun 2024 12:49:26 +0200 |
parents | 09ece563609a |
children | db7dbe6f7bb2 |
files | rust/hg-core/src/operations/debugdata.rs rust/hg-core/src/operations/mod.rs rust/hg-core/src/repo.rs rust/hg-core/src/revlog/changelog.rs rust/hg-core/src/revlog/mod.rs rust/rhg/src/commands/debugdata.rs rust/rhg/src/commands/status.rs |
diffstat | 7 files changed, 128 insertions(+), 53 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/operations/debugdata.rs Tue Sep 17 10:18:32 2024 +0200 +++ b/rust/hg-core/src/operations/debugdata.rs Wed Jun 19 12:49:26 2024 +0200 @@ -5,31 +5,33 @@ // This software may be used and distributed according to the terms of the // GNU General Public License version 2 or any later version. +use crate::errors::HgError; use crate::repo::Repo; -use crate::revlog::{Revlog, RevlogError}; - -/// Kind of data to debug -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum DebugDataKind { - Changelog, - Manifest, -} +use crate::revlog::Revlog; +use crate::{exit_codes, RevlogError, RevlogType}; /// Dump the contents data of a revision. pub fn debug_data( repo: &Repo, revset: &str, - kind: DebugDataKind, + kind: RevlogType, ) -> Result<Vec<u8>, RevlogError> { let index_file = match kind { - DebugDataKind::Changelog => "00changelog.i", - DebugDataKind::Manifest => "00manifest.i", + RevlogType::Changelog => "00changelog.i", + RevlogType::Manifestlog => "00manifest.i", + _ => { + return Err(RevlogError::Other(HgError::abort( + format!("invalid revlog type {}", kind), + exit_codes::ABORT, + None, + ))) + } }; let revlog = Revlog::open( &repo.store_vfs(), index_file, None, - repo.default_revlog_options(kind == DebugDataKind::Changelog)?, + repo.default_revlog_options(RevlogType::Changelog)?, )?; let rev = crate::revset::resolve_rev_number_or_hex_prefix(revset, &revlog)?;
--- a/rust/hg-core/src/operations/mod.rs Tue Sep 17 10:18:32 2024 +0200 +++ b/rust/hg-core/src/operations/mod.rs Wed Jun 19 12:49:26 2024 +0200 @@ -7,6 +7,6 @@ mod list_tracked_files; mod status_rev_rev; pub use cat::{cat, CatOutput}; -pub use debugdata::{debug_data, DebugDataKind}; +pub use debugdata::debug_data; pub use list_tracked_files::{list_rev_tracked_files, FilesForRev}; pub use status_rev_rev::{status_rev_rev_no_copies, DiffStatus, StatusRevRev};
--- a/rust/hg-core/src/repo.rs Tue Sep 17 10:18:32 2024 +0200 +++ b/rust/hg-core/src/repo.rs Wed Jun 19 12:49:26 2024 +0200 @@ -20,7 +20,8 @@ use crate::utils::SliceExt; use crate::vfs::{is_dir, is_file, Vfs}; use crate::{ - requirements, NodePrefix, RevlogVersionOptions, UncheckedRevision, + requirements, NodePrefix, RevlogDataConfig, RevlogDeltaConfig, + RevlogFeatureConfig, RevlogType, RevlogVersionOptions, UncheckedRevision, }; use crate::{DirstateError, RevlogOpenOptions}; use std::cell::{Ref, RefCell, RefMut}; @@ -529,7 +530,10 @@ } fn new_changelog(&self) -> Result<Changelog, HgError> { - Changelog::open(&self.store_vfs(), self.default_revlog_options(true)?) + Changelog::open( + &self.store_vfs(), + self.default_revlog_options(RevlogType::Changelog)?, + ) } pub fn changelog(&self) -> Result<Ref<Changelog>, HgError> { @@ -543,7 +547,7 @@ fn new_manifestlog(&self) -> Result<Manifestlog, HgError> { Manifestlog::open( &self.store_vfs(), - self.default_revlog_options(false)?, + self.default_revlog_options(RevlogType::Manifestlog)?, ) } @@ -590,9 +594,12 @@ } pub fn filelog(&self, path: &HgPath) -> Result<Filelog, HgError> { - Filelog::open(self, path, self.default_revlog_options(false)?) + Filelog::open( + self, + path, + self.default_revlog_options(RevlogType::Filelog)?, + ) } - /// Write to disk any updates that were made through `dirstate_map_mut`. /// /// The "wlock" must be held while calling this. @@ -742,10 +749,11 @@ pub fn default_revlog_options( &self, - changelog: bool, + revlog_type: RevlogType, ) -> Result<RevlogOpenOptions, HgError> { let requirements = self.requirements(); - let version = if changelog + let is_changelog = revlog_type == RevlogType::Changelog; + let version = if is_changelog && requirements.contains(CHANGELOGV2_REQUIREMENT) { let compute_rank = self @@ -756,7 +764,8 @@ RevlogVersionOptions::V2 } else if requirements.contains(REVLOGV1_REQUIREMENT) { RevlogVersionOptions::V1 { - generaldelta: requirements.contains(GENERALDELTA_REQUIREMENT), + general_delta: requirements.contains(GENERALDELTA_REQUIREMENT), + inline: !is_changelog, } } else { RevlogVersionOptions::V0 @@ -766,6 +775,19 @@ // We don't need to dance around the slow path like in the Python // implementation since we know we have access to the fast code. use_nodemap: requirements.contains(NODEMAP_REQUIREMENT), + delta_config: RevlogDeltaConfig::new( + self.config(), + self.requirements(), + revlog_type, + )?, + data_config: RevlogDataConfig::new( + self.config(), + self.requirements(), + )?, + feature_config: RevlogFeatureConfig::new( + self.config(), + requirements, + )?, }) } }
--- a/rust/hg-core/src/revlog/changelog.rs Tue Sep 17 10:18:32 2024 +0200 +++ b/rust/hg-core/src/revlog/changelog.rs Wed Jun 19 12:49:26 2024 +0200 @@ -501,7 +501,10 @@ mod tests { use super::*; use crate::vfs::Vfs; - use crate::NULL_REVISION; + use crate::{ + RevlogDataConfig, RevlogDeltaConfig, RevlogFeatureConfig, + NULL_REVISION, + }; use pretty_assertions::assert_eq; #[test] @@ -562,9 +565,19 @@ let temp = tempfile::tempdir().unwrap(); let vfs = Vfs { base: temp.path() }; std::fs::write(temp.path().join("foo.i"), b"").unwrap(); - let revlog = - Revlog::open(&vfs, "foo.i", None, RevlogOpenOptions::new()) - .unwrap(); + std::fs::write(temp.path().join("foo.d"), b"").unwrap(); + let revlog = Revlog::open( + &vfs, + "foo.i", + None, + RevlogOpenOptions::new( + false, + RevlogDataConfig::default(), + RevlogDeltaConfig::default(), + RevlogFeatureConfig::default(), + ), + ) + .unwrap(); let changelog = Changelog { revlog }; assert_eq!(
--- a/rust/hg-core/src/revlog/mod.rs Tue Sep 17 10:18:32 2024 +0200 +++ b/rust/hg-core/src/revlog/mod.rs Wed Jun 19 12:49:26 2024 +0200 @@ -223,7 +223,7 @@ } } -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(derive_more::Display, Debug, Copy, Clone, PartialEq, Eq)] pub enum RevlogType { Changelog, Manifestlog, @@ -368,8 +368,8 @@ } } - if let Some(mmap_index_threshold) = - config.get_byte_size(b"experimental", b"mmapindexthreshold")? + if let Some(mmap_index_threshold) = config + .get_byte_size(b"storage", b"revlog.mmap.index:size-threshold")? { data_config.mmap_index_threshold = Some(mmap_index_threshold); } @@ -618,10 +618,10 @@ } } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq)] pub enum RevlogVersionOptions { V0, - V1 { generaldelta: bool }, + V1 { general_delta: bool, inline: bool }, V2, ChangelogV2 { compute_rank: bool }, } @@ -634,24 +634,65 @@ pub version: RevlogVersionOptions, /// Whether the revlog uses a persistent nodemap. pub use_nodemap: bool, - // TODO other non-header/version options, + pub delta_config: RevlogDeltaConfig, + pub data_config: RevlogDataConfig, + pub feature_config: RevlogFeatureConfig, +} + +#[cfg(test)] +impl Default for RevlogOpenOptions { + fn default() -> Self { + Self { + version: RevlogVersionOptions::V1 { + general_delta: true, + inline: false, + }, + use_nodemap: true, + data_config: Default::default(), + delta_config: Default::default(), + feature_config: Default::default(), + } + } } impl RevlogOpenOptions { - pub fn new() -> Self { + pub fn new( + inline: bool, + data_config: RevlogDataConfig, + delta_config: RevlogDeltaConfig, + feature_config: RevlogFeatureConfig, + ) -> Self { Self { - version: RevlogVersionOptions::V1 { generaldelta: true }, + version: RevlogVersionOptions::V1 { + general_delta: data_config.general_delta, + inline, + }, use_nodemap: false, + data_config, + delta_config, + feature_config, } } - fn default_index_header(&self) -> index::IndexHeader { + pub fn index_header(&self) -> index::IndexHeader { index::IndexHeader { header_bytes: match self.version { RevlogVersionOptions::V0 => [0, 0, 0, 0], - RevlogVersionOptions::V1 { generaldelta } => { - [0, if generaldelta { 3 } else { 1 }, 0, 1] - } + RevlogVersionOptions::V1 { + general_delta, + inline, + } => [ + 0, + if general_delta && inline { + 3 + } else if general_delta { + 2 + } else { + u8::from(inline) + }, + 0, + 1, + ], RevlogVersionOptions::V2 => 0xDEADu32.to_be_bytes(), RevlogVersionOptions::ChangelogV2 { compute_rank: _ } => { 0xD34Du32.to_be_bytes() @@ -661,12 +702,6 @@ } } -impl Default for RevlogOpenOptions { - fn default() -> Self { - Self::new() - } -} - impl Revlog { /// Open a revlog index file. /// @@ -693,12 +728,12 @@ match store_vfs.mmap_open_opt(index_path)? { None => Index::new( Box::<Vec<_>>::default(), - options.default_index_header(), + options.index_header(), ), Some(index_mmap) => { let index = Index::new( Box::new(index_mmap), - options.default_index_header(), + options.index_header(), )?; Ok(index) } @@ -1265,8 +1300,9 @@ let temp = tempfile::tempdir().unwrap(); let vfs = Vfs { base: temp.path() }; std::fs::write(temp.path().join("foo.i"), b"").unwrap(); + std::fs::write(temp.path().join("foo.d"), b"").unwrap(); let revlog = - Revlog::open(&vfs, "foo.i", None, RevlogOpenOptions::new()) + Revlog::open(&vfs, "foo.i", None, RevlogOpenOptions::default()) .unwrap(); assert!(revlog.is_empty()); assert_eq!(revlog.len(), 0); @@ -1309,7 +1345,7 @@ .collect_vec(); std::fs::write(temp.path().join("foo.i"), contents).unwrap(); let revlog = - Revlog::open(&vfs, "foo.i", None, RevlogOpenOptions::new()) + Revlog::open(&vfs, "foo.i", None, RevlogOpenOptions::default()) .unwrap(); let entry0 = revlog.get_entry(0.into()).ok().unwrap(); @@ -1381,7 +1417,7 @@ &vfs, "foo.i", None, - RevlogOpenOptions::new(), + RevlogOpenOptions::default(), Some(idx.nt), ) .unwrap();
--- a/rust/rhg/src/commands/debugdata.rs Tue Sep 17 10:18:32 2024 +0200 +++ b/rust/rhg/src/commands/debugdata.rs Wed Jun 19 12:49:26 2024 +0200 @@ -1,7 +1,8 @@ use crate::error::CommandError; use clap::Arg; use clap::ArgGroup; -use hg::operations::{debug_data, DebugDataKind}; +use hg::operations::debug_data; +use hg::RevlogType; pub const HELP_TEXT: &str = " Dump the contents of a data file revision @@ -45,8 +46,8 @@ args.get_one::<bool>("changelog").unwrap(), args.get_one::<bool>("manifest").unwrap(), ) { - (true, false) => DebugDataKind::Changelog, - (false, true) => DebugDataKind::Manifest, + (true, false) => RevlogType::Changelog, + (false, true) => RevlogType::Manifestlog, (true, true) => { unreachable!("Should not happen since options are exclusive") }
--- a/rust/rhg/src/commands/status.rs Tue Sep 17 10:18:32 2024 +0200 +++ b/rust/rhg/src/commands/status.rs Wed Jun 19 12:49:26 2024 +0200 @@ -28,12 +28,12 @@ get_bytes_from_os_str, get_bytes_from_os_string, get_path_from_bytes, }; use hg::utils::hg_path::{hg_path_to_path_buf, HgPath}; -use hg::PatternFileWarning; use hg::Revision; use hg::StatusError; use hg::StatusOptions; use hg::{self, narrow, sparse}; use hg::{DirstateStatus, RevlogOpenOptions}; +use hg::{PatternFileWarning, RevlogType}; use log::info; use rayon::prelude::*; use std::borrow::Cow; @@ -383,7 +383,8 @@ })?; let working_directory_vfs = repo.working_directory_vfs(); let store_vfs = repo.store_vfs(); - let revlog_open_options = repo.default_revlog_options(false)?; + let revlog_open_options = + repo.default_revlog_options(RevlogType::Manifestlog)?; let res: Vec<_> = take(&mut ds_status.unsure) .into_par_iter() .map(|to_check| {