Mercurial > hg
annotate rust/hg-core/src/dirstate_tree/path_with_basename.rs @ 47119:15395fd8ab28
dirstate-tree: Use HashMap instead of BTreeMap
BTreeMap has the advantage of its "natural" iteration order being the one we need
in the status algorithm. With HashMap however, iteration order is undefined so
we need to allocate a Vec and sort it explicitly.
Unfortunately many BTreeMap operations are slower than in HashMap, and skipping
that extra allocation and sort is not enough to compensate.
Switching to HashMap + sort makes `hg status` 17% faster in one test case,
as measure with hyperfine:
```
Benchmark #1: ../hg2/hg status -R $REPO --config=experimental.dirstate-tree.in-memory=1
Time (mean ± σ): 765.0 ms ± 8.8 ms [User: 1.352 s, System: 0.747 s]
Range (min … max): 751.8 ms … 778.7 ms 10 runs
Benchmark #2: ./hg status -R $REPO --config=experimental.dirstate-tree.in-memory=1
Time (mean ± σ): 651.8 ms ± 9.9 ms [User: 1.251 s, System: 0.799 s]
Range (min … max): 642.2 ms … 671.8 ms 10 runs
Summary
'./hg status -R $REPO --config=experimental.dirstate-tree.in-memory=1' ran
1.17 ± 0.02 times faster than '../hg2/hg status -R $REPO --config=experimental.dirstate-tree.in-memory=1'
```
* ./hg is this revision
* ../hg2/hg is its parent
* $REPO is an old snapshot of mozilla-central
Differential Revision: https://phab.mercurial-scm.org/D10553
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Thu, 29 Apr 2021 11:32:57 +0200 |
parents | 3c11c24b82b6 |
children | ecfe0819ada5 |
rev | line source |
---|---|
47096
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
1 use crate::utils::hg_path::HgPath; |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
2 use std::borrow::Borrow; |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
3 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
4 /// Wraps `HgPath` or `HgPathBuf` to make it behave "as" its last path |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
5 /// component, a.k.a. its base name (as in Python’s `os.path.basename`), but |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
6 /// also allow recovering the full path. |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
7 /// |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
8 /// "Behaving as" means that equality and comparison consider only the base |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
9 /// name, and `std::borrow::Borrow` is implemented to return only the base |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
10 /// name. This allows using the base name as a map key while still being able |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
11 /// to recover the full path, in a single memory allocation. |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
12 #[derive(Debug)] |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
13 pub struct WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
14 full_path: T, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
15 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
16 /// The position after the last slash separator in `full_path`, or `0` |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
17 /// if there is no slash. |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
18 base_name_start: usize, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
19 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
20 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
21 impl<T> WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
22 pub fn full_path(&self) -> &T { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
23 &self.full_path |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
24 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
25 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
26 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
27 impl<T: AsRef<HgPath>> WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
28 pub fn new(full_path: T) -> Self { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
29 let base_name_start = if let Some(last_slash_position) = full_path |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
30 .as_ref() |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
31 .as_bytes() |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
32 .iter() |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
33 .rposition(|&byte| byte == b'/') |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
34 { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
35 last_slash_position + 1 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
36 } else { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
37 0 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
38 }; |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
39 Self { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
40 base_name_start, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
41 full_path, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
42 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
43 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
44 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
45 pub fn base_name(&self) -> &HgPath { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
46 HgPath::new( |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
47 &self.full_path.as_ref().as_bytes()[self.base_name_start..], |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
48 ) |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
49 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
50 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
51 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
52 impl<T: AsRef<HgPath>> Borrow<HgPath> for WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
53 fn borrow(&self) -> &HgPath { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
54 self.base_name() |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
55 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
56 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
57 |
47119
15395fd8ab28
dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47096
diff
changeset
|
58 impl<T: AsRef<HgPath>> std::hash::Hash for WithBasename<T> { |
15395fd8ab28
dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47096
diff
changeset
|
59 fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) { |
15395fd8ab28
dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47096
diff
changeset
|
60 self.base_name().hash(hasher) |
15395fd8ab28
dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47096
diff
changeset
|
61 } |
15395fd8ab28
dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47096
diff
changeset
|
62 } |
15395fd8ab28
dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47096
diff
changeset
|
63 |
47096
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
64 impl<T: AsRef<HgPath> + PartialEq> PartialEq for WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
65 fn eq(&self, other: &Self) -> bool { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
66 self.base_name() == other.base_name() |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
67 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
68 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
69 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
70 impl<T: AsRef<HgPath> + Eq> Eq for WithBasename<T> {} |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
71 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
72 impl<T: AsRef<HgPath> + PartialOrd> PartialOrd for WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
73 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
74 self.base_name().partial_cmp(other.base_name()) |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
75 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
76 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
77 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
78 impl<T: AsRef<HgPath> + Ord> Ord for WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
79 fn cmp(&self, other: &Self) -> std::cmp::Ordering { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
80 self.base_name().cmp(other.base_name()) |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
81 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
82 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
83 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
84 impl<T: ?Sized + ToOwned> WithBasename<&'_ T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
85 pub fn to_owned(&self) -> WithBasename<T::Owned> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
86 WithBasename { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
87 full_path: self.full_path.to_owned(), |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
88 base_name_start: self.base_name_start, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
89 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
90 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
91 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
92 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
93 impl<'a> WithBasename<&'a HgPath> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
94 /// Returns an iterator of `WithBasename<&HgPath>` for the ancestor |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
95 /// directory paths of the given `path`, as well as `path` itself. |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
96 /// |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
97 /// For example, the full paths of inclusive ancestors of "a/b/c" are "a", |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
98 /// "a/b", and "a/b/c" in that order. |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
99 pub fn inclusive_ancestors_of( |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
100 path: &'a HgPath, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
101 ) -> impl Iterator<Item = WithBasename<&'a HgPath>> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
102 let mut slash_positions = |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
103 path.as_bytes().iter().enumerate().filter_map(|(i, &byte)| { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
104 if byte == b'/' { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
105 Some(i) |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
106 } else { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
107 None |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
108 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
109 }); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
110 let mut opt_next_component_start = Some(0); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
111 std::iter::from_fn(move || { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
112 opt_next_component_start.take().map(|next_component_start| { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
113 if let Some(slash_pos) = slash_positions.next() { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
114 opt_next_component_start = Some(slash_pos + 1); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
115 Self { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
116 full_path: HgPath::new(&path.as_bytes()[..slash_pos]), |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
117 base_name_start: next_component_start, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
118 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
119 } else { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
120 // Not setting `opt_next_component_start` here: there will |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
121 // be no iteration after this one because `.take()` set it |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
122 // to `None`. |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
123 Self { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
124 full_path: path, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
125 base_name_start: next_component_start, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
126 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
127 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
128 }) |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
129 }) |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
130 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
131 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
132 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
133 #[test] |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
134 fn test() { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
135 let a = WithBasename::new(HgPath::new("a").to_owned()); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
136 assert_eq!(&**a.full_path(), HgPath::new(b"a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
137 assert_eq!(a.base_name(), HgPath::new(b"a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
138 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
139 let cba = WithBasename::new(HgPath::new("c/b/a").to_owned()); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
140 assert_eq!(&**cba.full_path(), HgPath::new(b"c/b/a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
141 assert_eq!(cba.base_name(), HgPath::new(b"a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
142 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
143 assert_eq!(a, cba); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
144 let borrowed: &HgPath = cba.borrow(); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
145 assert_eq!(borrowed, HgPath::new("a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
146 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
147 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
148 #[test] |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
149 fn test_inclusive_ancestors() { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
150 let mut iter = WithBasename::inclusive_ancestors_of(HgPath::new("a/bb/c")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
151 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
152 let next = iter.next().unwrap(); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
153 assert_eq!(*next.full_path(), HgPath::new("a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
154 assert_eq!(next.base_name(), HgPath::new("a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
155 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
156 let next = iter.next().unwrap(); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
157 assert_eq!(*next.full_path(), HgPath::new("a/bb")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
158 assert_eq!(next.base_name(), HgPath::new("bb")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
159 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
160 let next = iter.next().unwrap(); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
161 assert_eq!(*next.full_path(), HgPath::new("a/bb/c")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
162 assert_eq!(next.base_name(), HgPath::new("c")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
163 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
164 assert!(iter.next().is_none()); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
165 } |