D10919: rust: Document the DirstateMapMethods trait
SimonSapin
phabricator at mercurial-scm.org
Thu Jul 1 16:51:45 UTC 2021
SimonSapin created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.
REPOSITORY
rHG Mercurial
BRANCH
default
REVISION DETAIL
https://phab.mercurial-scm.org/D10919
AFFECTED FILES
rust/hg-core/src/dirstate_tree/dispatch.rs
rust/hg-core/src/dirstate_tree/on_disk.rs
CHANGE DETAILS
diff --git a/rust/hg-core/src/dirstate_tree/on_disk.rs b/rust/hg-core/src/dirstate_tree/on_disk.rs
--- a/rust/hg-core/src/dirstate_tree/on_disk.rs
+++ b/rust/hg-core/src/dirstate_tree/on_disk.rs
@@ -78,7 +78,7 @@
children: ChildNodes,
pub(super) tracked_descendants_count: Size,
- /// Dependending on the value of `state`:
+ /// Depending on the value of `state`:
///
/// * A null byte: `data` is not used.
///
diff --git a/rust/hg-core/src/dirstate_tree/dispatch.rs b/rust/hg-core/src/dirstate_tree/dispatch.rs
--- a/rust/hg-core/src/dirstate_tree/dispatch.rs
+++ b/rust/hg-core/src/dirstate_tree/dispatch.rs
@@ -16,9 +16,34 @@
use crate::StatusError;
use crate::StatusOptions;
+/// `rust/hg-cpython/src/dirstate/dirstate_map.rs` implements in Rust a
+/// `DirstateMap` Python class that wraps `Box<dyn DirstateMapMethods + Send>`,
+/// a trait object of this trait. Except for constructors, this trait defines
+/// all APIs that the class needs to interact with its inner dirstate map.
+///
+/// A trait object is used to support two different concrete types:
+///
+/// * `rust/hg-core/src/dirstate/dirstate_map.rs` defines the "flat dirstate
+/// map" which is based on a few large `HgPath`-keyed `HashMap` and `HashSet`
+/// fields.
+/// * `rust/hg-core/src/dirstate_tree/dirstate_map.rs` defines the "tree
+/// dirstate map" based on a tree data struture with nodes for directories
+/// containing child nodes for their files and sub-directories. This tree
+/// enables a more efficient algorithm for `hg status`, but its details are
+/// abstracted in this trait.
+///
+/// The dirstate map associates paths of files in the working directory to
+/// various information about the state of those files.
pub trait DirstateMapMethods {
+ /// Remove information about all files in this map
fn clear(&mut self);
+ /// Add or change the information associated to a given file.
+ ///
+ /// `old_state` is the state in the entry that `get` would have returned
+ /// before this call, or `EntryState::Unknown` if there was no such entry.
+ ///
+ /// `entry.state` should never be `EntryState::Unknown`.
fn add_file(
&mut self,
filename: &HgPath,
@@ -26,6 +51,13 @@
entry: DirstateEntry,
) -> Result<(), DirstateError>;
+ /// Mark a file as "removed" (as in `hg rm`).
+ ///
+ /// `old_state` is the state in the entry that `get` would have returned
+ /// before this call, or `EntryState::Unknown` if there was no such entry.
+ ///
+ /// `size` is not actually a size but the 0 or -1 or -2 value that would be
+ /// put in the size field in the dirstate-v1Â format.
fn remove_file(
&mut self,
filename: &HgPath,
@@ -33,62 +65,127 @@
size: i32,
) -> Result<(), DirstateError>;
+ /// Drop information about this file from the map if any, and return
+ /// whether there was any.
+ ///
+ /// `get` will now return `None` for this filename.
+ ///
+ /// `old_state` is the state in the entry that `get` would have returned
+ /// before this call, or `EntryState::Unknown` if there was no such entry.
fn drop_file(
&mut self,
filename: &HgPath,
old_state: EntryState,
) -> Result<bool, DirstateError>;
+ /// Among given files, mark the stored `mtime` as ambiguous if there is one
+ /// (if `state == EntryState::Normal`) equal to the given current Unix
+ /// timestamp.
fn clear_ambiguous_times(
&mut self,
filenames: Vec<HgPathBuf>,
now: i32,
) -> Result<(), DirstateV2ParseError>;
+ /// Return whether the map has an "non-normal" entry for the given
+ /// filename. That is, any entry with a `state` other than
+ /// `EntryState::Normal` or with an ambiguous `mtime`.
fn non_normal_entries_contains(
&mut self,
key: &HgPath,
) -> Result<bool, DirstateV2ParseError>;
+ /// Mark the given path as "normal" file. This is only relevant in the flat
+ /// dirstate map where there is a separate `HashSet` that needs to be kept
+ /// up to date.
fn non_normal_entries_remove(&mut self, key: &HgPath);
+ /// Return an iterator of paths whose respective entry are either
+ /// "non-normal" (see `non_normal_entries_contains`) or "from other
+ /// parent".
+ ///
+ /// If that information is cached, create the cache as needed.
+ ///
+ /// "From other parent" is defined as `state == Normal && size == -2`.
+ ///
+ /// Because parse errors can happen during iteration, the iterated items
+ /// are `Result`s.
fn non_normal_or_other_parent_paths(
&mut self,
) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_>;
+ /// Create the cache for `non_normal_or_other_parent_paths` if needed.
+ ///
+ /// If `force` is true, the cache is re-created even if it already exists.
fn set_non_normal_other_parent_entries(&mut self, force: bool);
+ /// Return an iterator of paths whose respective entry are "non-normal"
+ /// (see `non_normal_entries_contains`).
+ ///
+ /// If that information is cached, create the cache as needed.
+ ///
+ /// Because parse errors can happen during iteration, the iterated items
+ /// are `Result`s.
fn iter_non_normal_paths(
&mut self,
) -> Box<
dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
>;
+ /// Same as `iter_non_normal_paths`, but takes `&self` instead of `&mut
+ /// self`.
+ ///
+ /// Panics if a cache is necessary but does not exist yet.
fn iter_non_normal_paths_panic(
&self,
) -> Box<
dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
>;
+ /// Return an iterator of paths whose respective entry are "from other
+ /// parent".
+ ///
+ /// If that information is cached, create the cache as needed.
+ ///
+ /// "From other parent" is defined as `state == Normal && size == -2`.
+ ///
+ /// Because parse errors can happen during iteration, the iterated items
+ /// are `Result`s.
fn iter_other_parent_paths(
&mut self,
) -> Box<
dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
>;
+ /// Returns whether the sub-tree rooted at the given directory contains any
+ /// tracked file.
+ ///
+ /// A file is tracked if it has a `state` other than `EntryState::Removed`.
fn has_tracked_dir(
&mut self,
directory: &HgPath,
) -> Result<bool, DirstateError>;
+ /// Returns whether the sub-tree rooted at the given directory contains any
+ /// file with a dirstate entry.
fn has_dir(&mut self, directory: &HgPath) -> Result<bool, DirstateError>;
+ /// Clear mtimes that are ambigous with `now` (similar to
+ /// `clear_ambiguous_times` but for all files in the dirstate map), and
+ /// serialize bytes to write the `.hg/dirstate` file to disk in dirstate-v1
+ /// format.
fn pack_v1(
&mut self,
parents: DirstateParents,
now: Timestamp,
) -> Result<Vec<u8>, DirstateError>;
+ /// Clear mtimes that are ambigous with `now` (similar to
+ /// `clear_ambiguous_times` but for all files in the dirstate map), and
+ /// serialize bytes to write the `.hg/dirstate` file to disk in dirstate-v2
+ /// format.
+ ///
+ /// Note: this is only supported by the tree dirstate map.
fn pack_v2(
&mut self,
parents: DirstateParents,
@@ -99,6 +196,11 @@
fn set_dirs(&mut self) -> Result<(), DirstateError>;
+ /// Run the status algorithm.
+ ///
+ /// This is not sematically a method of the dirstate map, but a different
+ /// algorithm is used for the flat v.s. tree dirstate map so having it in
+ /// this trait enables the same dynamic dispatch as with other methods.
fn status<'a>(
&'a mut self,
matcher: &'a (dyn Matcher + Sync),
@@ -107,43 +209,66 @@
options: StatusOptions,
) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>;
+ /// Returns how many files in the dirstate map have a recorded copy source.
fn copy_map_len(&self) -> usize;
+ /// Returns an iterator of `(path, copy_source)` for all files that have a
+ /// copy source.
fn copy_map_iter(&self) -> CopyMapIter<'_>;
+ /// Returns whether the givef file has a copy source.
fn copy_map_contains_key(
&self,
key: &HgPath,
) -> Result<bool, DirstateV2ParseError>;
+ /// Returns the copy source for the given file.
fn copy_map_get(
&self,
key: &HgPath,
) -> Result<Option<&HgPath>, DirstateV2ParseError>;
+ /// Removes the recorded copy source if any for the given file, and returns
+ /// it.
fn copy_map_remove(
&mut self,
key: &HgPath,
) -> Result<Option<HgPathBuf>, DirstateV2ParseError>;
+ /// Set the given `value` copy source for the given `key` file.
fn copy_map_insert(
&mut self,
key: HgPathBuf,
value: HgPathBuf,
) -> Result<Option<HgPathBuf>, DirstateV2ParseError>;
+ /// Returns the number of files that have an entry.
fn len(&self) -> usize;
+ /// Returns whether the given file has an entry.
fn contains_key(&self, key: &HgPath)
-> Result<bool, DirstateV2ParseError>;
+ /// Returns the entry, if any, for the given file.
fn get(
&self,
key: &HgPath,
) -> Result<Option<DirstateEntry>, DirstateV2ParseError>;
+ /// Returns a `(path, entry)` iterator of files that have an entry.
+ ///
+ /// Because parse errors can happen during iteration, the iterated items
+ /// are `Result`s.
fn iter(&self) -> StateMapIter<'_>;
+ /// In the tree dirstate, return an iterator of "directory" (entry-less)
+ /// nodes with the data stored for them. This is for `hg debugdirstate
+ /// --dirs`.
+ ///
+ /// In the flat dirstate, returns an empty iterator.
+ ///
+ /// Because parse errors can happen during iteration, the iterated items
+ /// are `Result`s.
fn iter_directories(
&self,
) -> Box<
To: SimonSapin, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
More information about the Mercurial-devel
mailing list