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.
--- 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| {