Mercurial > hg
changeset 47491:8851acad5906
rust: Document the DirstateMapMethods trait
Differential Revision: https://phab.mercurial-scm.org/D10919
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Thu, 01 Jul 2021 18:51:18 +0200 |
parents | 084ed6a7c6fd |
children | f03e9d30258e |
files | rust/hg-core/src/dirstate_tree/dispatch.rs rust/hg-core/src/dirstate_tree/on_disk.rs |
diffstat | 2 files changed, 126 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/dirstate_tree/dispatch.rs Fri Jul 02 02:36:07 2021 +0200 +++ b/rust/hg-core/src/dirstate_tree/dispatch.rs Thu Jul 01 18:51:18 2021 +0200 @@ -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,68 +65,138 @@ 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, now: Timestamp, ) -> Result<Vec<u8>, 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), @@ -103,43 +205,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<
--- a/rust/hg-core/src/dirstate_tree/on_disk.rs Fri Jul 02 02:36:07 2021 +0200 +++ b/rust/hg-core/src/dirstate_tree/on_disk.rs Thu Jul 01 18:51:18 2021 +0200 @@ -79,7 +79,7 @@ pub(super) descendants_with_entry_count: Size, 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. ///