Mercurial > hg
changeset 50221:1891086f6c7f stable
dirstate: use more than a bool to control append behavior
When writing dirstate-v2, we might either append to the existing file, or
create a new file.
We are about to introduce some configuration to control this behavior.
As a prelude, we change the current way the behavior was automatically
controlled to make the change smaller/clearer.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Fri, 24 Feb 2023 18:21:54 +0100 |
parents | 35ea3c139104 |
children | ecd28d89c29e |
files | mercurial/dirstatemap.py rust/hg-core/src/dirstate_tree/dirstate_map.rs rust/hg-core/src/dirstate_tree/on_disk.rs rust/hg-core/src/repo.rs rust/hg-cpython/src/dirstate/dirstate_map.rs |
diffstat | 5 files changed, 40 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/dirstatemap.py Fri Feb 24 01:15:45 2023 +0100 +++ b/mercurial/dirstatemap.py Fri Feb 24 18:21:54 2023 +0100 @@ -31,6 +31,9 @@ rangemask = 0x7FFFFFFF +WRITE_MODE_AUTO = 0 +WRITE_MODE_FORCE_NEW = 1 + class _dirstatemapcommon: """ @@ -609,8 +612,10 @@ return # We can only append to an existing data file if there is one - can_append = self.docket.uuid is not None - packed, meta, append = self._map.write_v2(can_append) + write_mode = WRITE_MODE_AUTO + if self.docket.uuid is None: + write_mode = WRITE_MODE_FORCE_NEW + packed, meta, append = self._map.write_v2(write_mode) if append: docket = self.docket data_filename = docket.data_filename()
--- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs Fri Feb 24 01:15:45 2023 +0100 +++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs Fri Feb 24 18:21:54 2023 +0100 @@ -38,6 +38,12 @@ V2, } +#[derive(Debug, PartialEq, Eq)] +pub enum DirstateMapWriteMode { + Auto, + ForceNewDataFile, +} + #[derive(Debug)] pub struct DirstateMap<'on_disk> { /// Contents of the `.hg/dirstate` file @@ -1251,11 +1257,11 @@ #[timed] pub fn pack_v2( &self, - can_append: bool, + write_mode: DirstateMapWriteMode, ) -> Result<(Vec<u8>, on_disk::TreeMetadata, bool, usize), DirstateError> { let map = self.get_map(); - on_disk::write(map, can_append) + on_disk::write(map, write_mode) } /// `callback` allows the caller to process and do something with the @@ -1812,7 +1818,7 @@ )?; let (packed, metadata, _should_append, _old_data_size) = - map.pack_v2(false)?; + map.pack_v2(DirstateMapWriteMode::ForceNewDataFile)?; let packed_len = packed.len(); assert!(packed_len > 0);
--- a/rust/hg-core/src/dirstate_tree/on_disk.rs Fri Feb 24 01:15:45 2023 +0100 +++ b/rust/hg-core/src/dirstate_tree/on_disk.rs Fri Feb 24 18:21:54 2023 +0100 @@ -4,7 +4,9 @@ use crate::dirstate::{DirstateV2Data, TruncatedTimestamp}; use crate::dirstate_tree::dirstate_map::DirstateVersion; -use crate::dirstate_tree::dirstate_map::{self, DirstateMap, NodeRef}; +use crate::dirstate_tree::dirstate_map::{ + self, DirstateMap, DirstateMapWriteMode, NodeRef, +}; use crate::dirstate_tree::path_with_basename::WithBasename; use crate::errors::HgError; use crate::utils::hg_path::HgPath; @@ -634,9 +636,12 @@ /// (false), and the previous size of data on disk. pub(super) fn write( dirstate_map: &DirstateMap, - can_append: bool, + write_mode: DirstateMapWriteMode, ) -> Result<(Vec<u8>, TreeMetadata, bool, usize), DirstateError> { - let append = can_append && dirstate_map.write_should_append(); + let append = match write_mode { + DirstateMapWriteMode::Auto => dirstate_map.write_should_append(), + DirstateMapWriteMode::ForceNewDataFile => false, + }; if append { log::trace!("appending to the dirstate data file"); } else {
--- a/rust/hg-core/src/repo.rs Fri Feb 24 01:15:45 2023 +0100 +++ b/rust/hg-core/src/repo.rs Fri Feb 24 18:21:54 2023 +0100 @@ -1,6 +1,7 @@ use crate::changelog::Changelog; use crate::config::{Config, ConfigError, ConfigParseError}; use crate::dirstate::DirstateParents; +use crate::dirstate_tree::dirstate_map::DirstateMapWriteMode; use crate::dirstate_tree::on_disk::Docket as DirstateDocket; use crate::dirstate_tree::owning::OwningDirstateMap; use crate::errors::HgResultExt; @@ -436,9 +437,13 @@ .dirstate_data_file_uuid .get_or_init(|| self.read_dirstate_data_file_uuid())?; let uuid_opt = uuid_opt.as_ref(); - let can_append = uuid_opt.is_some(); + let write_mode = if uuid_opt.is_some() { + DirstateMapWriteMode::Auto + } else { + DirstateMapWriteMode::ForceNewDataFile + }; let (data, tree_metadata, append, old_data_size) = - map.pack_v2(can_append)?; + map.pack_v2(write_mode)?; // Reuse the uuid, or generate a new one, keeping the old for // deletion.
--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs Fri Feb 24 01:15:45 2023 +0100 +++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs Fri Feb 24 18:21:54 2023 +0100 @@ -23,7 +23,8 @@ pybytes_deref::PyBytesDeref, }; use hg::{ - dirstate::StateMapIter, dirstate_tree::on_disk::DirstateV2ParseError, + dirstate::StateMapIter, dirstate_tree::dirstate_map::DirstateMapWriteMode, + dirstate_tree::on_disk::DirstateV2ParseError, dirstate_tree::owning::OwningDirstateMap, revlog::Node, utils::files::normalize_case, utils::hg_path::HgPath, DirstateEntry, DirstateError, DirstateParents, @@ -247,10 +248,15 @@ /// instead of written to a new data file (False). def write_v2( &self, - can_append: bool, + write_mode: usize, ) -> PyResult<PyObject> { let inner = self.inner(py).borrow(); - let result = inner.pack_v2(can_append); + let rust_write_mode = match write_mode { + 0 => DirstateMapWriteMode::Auto, + 1 => DirstateMapWriteMode::ForceNewDataFile, + _ => DirstateMapWriteMode::Auto, // XXX should we error out? + }; + let result = inner.pack_v2(rust_write_mode); match result { Ok((packed, tree_metadata, append, _old_data_size)) => { let packed = PyBytes::new(py, &packed);