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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }