Details
Details
- Reviewers
pulkit - Group Reviewers
hg-reviewers - Commits
- rHG8851acad5906: rust: Document the DirstateMapMethods trait
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Branch
- default
- Lint
No Linters Available - Unit
No Unit Test Coverage
( )
| pulkit |
| hg-reviewers |
| No Linters Available |
| No Unit Test Coverage |
| Path | Packages | |||
|---|---|---|---|---|
| M | rust/hg-core/src/dirstate_tree/dispatch.rs (125 lines) | |||
| M | rust/hg-core/src/dirstate_tree/on_disk.rs (2 lines) |
| Commit | Parents | Author | Summary | Date |
|---|---|---|---|---|
| 7a076ce2b8f7 | 5045ba2a3afd | Simon Sapin | Jul 1 2021, 12:51 PM |
| use crate::DirstateParents; | use crate::DirstateParents; | ||||
| use crate::DirstateStatus; | use crate::DirstateStatus; | ||||
| use crate::EntryState; | use crate::EntryState; | ||||
| use crate::PatternFileWarning; | use crate::PatternFileWarning; | ||||
| use crate::StateMapIter; | use crate::StateMapIter; | ||||
| use crate::StatusError; | use crate::StatusError; | ||||
| use crate::StatusOptions; | 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 { | pub trait DirstateMapMethods { | ||||
| /// Remove information about all files in this map | |||||
| fn clear(&mut self); | 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( | fn add_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| old_state: EntryState, | old_state: EntryState, | ||||
| entry: DirstateEntry, | entry: DirstateEntry, | ||||
| ) -> Result<(), DirstateError>; | ) -> 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( | fn remove_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| old_state: EntryState, | old_state: EntryState, | ||||
| size: i32, | size: i32, | ||||
| ) -> Result<(), DirstateError>; | ) -> 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( | fn drop_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| old_state: EntryState, | old_state: EntryState, | ||||
| ) -> Result<bool, DirstateError>; | ) -> 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( | fn clear_ambiguous_times( | ||||
| &mut self, | &mut self, | ||||
| filenames: Vec<HgPathBuf>, | filenames: Vec<HgPathBuf>, | ||||
| now: i32, | now: i32, | ||||
| ) -> Result<(), DirstateV2ParseError>; | ) -> 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( | fn non_normal_entries_contains( | ||||
| &mut self, | &mut self, | ||||
| key: &HgPath, | key: &HgPath, | ||||
| ) -> Result<bool, DirstateV2ParseError>; | ) -> 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); | 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( | fn non_normal_or_other_parent_paths( | ||||
| &mut self, | &mut self, | ||||
| ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_>; | ) -> 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); | 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( | fn iter_non_normal_paths( | ||||
| &mut self, | &mut self, | ||||
| ) -> Box< | ) -> Box< | ||||
| dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | 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( | fn iter_non_normal_paths_panic( | ||||
| &self, | &self, | ||||
| ) -> Box< | ) -> Box< | ||||
| dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | 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( | fn iter_other_parent_paths( | ||||
| &mut self, | &mut self, | ||||
| ) -> Box< | ) -> Box< | ||||
| dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | 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( | fn has_tracked_dir( | ||||
| &mut self, | &mut self, | ||||
| directory: &HgPath, | directory: &HgPath, | ||||
| ) -> Result<bool, DirstateError>; | ) -> 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>; | 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( | fn pack_v1( | ||||
| &mut self, | &mut self, | ||||
| parents: DirstateParents, | parents: DirstateParents, | ||||
| now: Timestamp, | now: Timestamp, | ||||
| ) -> Result<Vec<u8>, DirstateError>; | ) -> 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( | fn pack_v2( | ||||
| &mut self, | &mut self, | ||||
| parents: DirstateParents, | parents: DirstateParents, | ||||
| now: Timestamp, | now: Timestamp, | ||||
| ) -> Result<Vec<u8>, DirstateError>; | ) -> Result<Vec<u8>, DirstateError>; | ||||
| fn set_all_dirs(&mut self) -> Result<(), DirstateError>; | fn set_all_dirs(&mut self) -> Result<(), DirstateError>; | ||||
| fn set_dirs(&mut self) -> Result<(), DirstateError>; | 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>( | fn status<'a>( | ||||
| &'a mut self, | &'a mut self, | ||||
| matcher: &'a (dyn Matcher + Sync), | matcher: &'a (dyn Matcher + Sync), | ||||
| root_dir: PathBuf, | root_dir: PathBuf, | ||||
| ignore_files: Vec<PathBuf>, | ignore_files: Vec<PathBuf>, | ||||
| options: StatusOptions, | options: StatusOptions, | ||||
| ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>; | ) -> 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; | 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<'_>; | fn copy_map_iter(&self) -> CopyMapIter<'_>; | ||||
| /// Returns whether the givef file has a copy source. | |||||
| fn copy_map_contains_key( | fn copy_map_contains_key( | ||||
| &self, | &self, | ||||
| key: &HgPath, | key: &HgPath, | ||||
| ) -> Result<bool, DirstateV2ParseError>; | ) -> Result<bool, DirstateV2ParseError>; | ||||
| /// Returns the copy source for the given file. | |||||
| fn copy_map_get( | fn copy_map_get( | ||||
| &self, | &self, | ||||
| key: &HgPath, | key: &HgPath, | ||||
| ) -> Result<Option<&HgPath>, DirstateV2ParseError>; | ) -> Result<Option<&HgPath>, DirstateV2ParseError>; | ||||
| /// Removes the recorded copy source if any for the given file, and returns | |||||
| /// it. | |||||
| fn copy_map_remove( | fn copy_map_remove( | ||||
| &mut self, | &mut self, | ||||
| key: &HgPath, | key: &HgPath, | ||||
| ) -> Result<Option<HgPathBuf>, DirstateV2ParseError>; | ) -> Result<Option<HgPathBuf>, DirstateV2ParseError>; | ||||
| /// Set the given `value` copy source for the given `key` file. | |||||
| fn copy_map_insert( | fn copy_map_insert( | ||||
| &mut self, | &mut self, | ||||
| key: HgPathBuf, | key: HgPathBuf, | ||||
| value: HgPathBuf, | value: HgPathBuf, | ||||
| ) -> Result<Option<HgPathBuf>, DirstateV2ParseError>; | ) -> Result<Option<HgPathBuf>, DirstateV2ParseError>; | ||||
| /// Returns the number of files that have an entry. | |||||
| fn len(&self) -> usize; | fn len(&self) -> usize; | ||||
| /// Returns whether the given file has an entry. | |||||
| fn contains_key(&self, key: &HgPath) | fn contains_key(&self, key: &HgPath) | ||||
| -> Result<bool, DirstateV2ParseError>; | -> Result<bool, DirstateV2ParseError>; | ||||
| /// Returns the entry, if any, for the given file. | |||||
| fn get( | fn get( | ||||
| &self, | &self, | ||||
| key: &HgPath, | key: &HgPath, | ||||
| ) -> Result<Option<DirstateEntry>, DirstateV2ParseError>; | ) -> 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<'_>; | 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( | fn iter_directories( | ||||
| &self, | &self, | ||||
| ) -> Box< | ) -> Box< | ||||
| dyn Iterator< | dyn Iterator< | ||||
| Item = Result< | Item = Result< | ||||
| (&HgPath, Option<Timestamp>), | (&HgPath, Option<Timestamp>), | ||||
| DirstateV2ParseError, | DirstateV2ParseError, | ||||
| >, | >, | ||||
| /// In bytes from `self.full_path.start` | /// In bytes from `self.full_path.start` | ||||
| base_name_start: Size, | base_name_start: Size, | ||||
| copy_source: OptPathSlice, | copy_source: OptPathSlice, | ||||
| children: ChildNodes, | children: ChildNodes, | ||||
| pub(super) tracked_descendants_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. | /// * A null byte: `data` is not used. | ||||
| /// | /// | ||||
| /// * A `n`, `a`, `r`, or `m` ASCII byte: `state` and `data` together | /// * A `n`, `a`, `r`, or `m` ASCII byte: `state` and `data` together | ||||
| /// represent a dirstate entry like in the v1 format. | /// represent a dirstate entry like in the v1 format. | ||||
| /// | /// | ||||
| /// * A `d` ASCII byte: the bytes of `data` should instead be interpreted | /// * A `d` ASCII byte: the bytes of `data` should instead be interpreted | ||||
| /// as the `Timestamp` for the mtime of a cached directory. | /// as the `Timestamp` for the mtime of a cached directory. | ||||