Mercurial > hg
annotate rust/hg-core/src/dirstate/dirs_multiset.rs @ 48068:bf8837e3d7ce
dirstate: Remove the flat Rust DirstateMap implementation
Before this changeset we had two Rust implementations of `DirstateMap`.
This removes the "flat" DirstateMap so that the "tree" DirstateMap is always
used when Rust enabled. This simplifies the code a lot, and will enable
(in the next changeset) further removal of a trait abstraction.
This is a performance regression when:
* Rust is enabled, and
* The repository uses the legacy dirstate-v1 file format, and
* For `hg status`, unknown files are not listed (such as with `-mard`)
The regression is about 100 milliseconds for `hg status -mard` on a
semi-large repository (mozilla-central), from ~320ms to ~420ms.
We deem this to be small enough to be worth it.
The new dirstate-v2 is still experimental at this point, but we aim to
stabilize it (though not yet enable it by default for new repositories)
in Mercurial 6.0. Eventually, upgrating repositories to dirsate-v2 will
eliminate this regression (and enable other performance improvements).
# Background
The flat DirstateMap was introduced with the first Rust implementation of the
status algorithm. It works similarly to the previous Python + C one, with a
single `HashMap` that associates file paths to a `DirstateEntry` (where Python
has a dict).
We later added the tree DirstateMap where the root of the tree contains nodes
for files and directories that are directly at the root of the repository,
and nodes for directories can contain child nodes representing the files and
directly that *they* contain directly. The shape of this tree mirrors that of
the working directory in the filesystem. This enables the status algorithm to
traverse this tree in tandem with traversing the filesystem tree, which in
turns enables a more efficient algorithm.
Furthermore, the new dirstate-v2 file format is also based on a tree of the
same shape. The tree DirstateMap can access a dirstate-v2 file without parsing
it: binary data in a single large (possibly memory-mapped) bytes buffer is
traversed on demand. This allows `DirstateMap` creation to take `O(1)` time.
(Mutation works by creating new in-memory nodes with copy-on-write semantics,
and serialization is append-mostly.)
The tradeoff is that for "legacy" repositories that use the dirstate-v1 file
format, parsing that file into a tree DirstateMap takes more time. Profiling
shows that this time is dominated by `HashMap`. For a dirstate containing `F`
files with an average `D` directory depth, the flat DirstateMap does parsing
in `O(F)` number of HashMap operations but the tree DirstateMap in `O(F × D)`
operations, since each node has its own HashMap containing its child nodes.
This slower costs ~140ms on an old snapshot of mozilla-central, and ~80ms
on an old snapshot of the Netbeans repository.
The status algorithm is faster, but with `-mard` (when not listing unknown
files) it is typically not faster *enough* to compensate the slower parsing.
Both Rust implementations are always faster than the Python + C implementation
# Benchmark results
All benchmarks are run on changeset 98c0408324e6, with repositories that use
the dirstate-v1 file format, on a server with 4 CPU cores and 4 CPU threads
(no HyperThreading).
`hg status` benchmarks show wall clock times of the entire command as the
average and standard deviation of serveral runs, collected by
https://github.com/sharkdp/hyperfine and reformated.
Parsing benchmarks are wall clock time of the Rust function that converts a
bytes buffer of the dirstate file into the `DirstateMap` data structure as
used by the status algorithm. A single run each, collected by running
`hg status` this environment variable:
RUST_LOG=hg::dirstate::dirstate_map=trace,hg::dirstate_tree::dirstate_map=trace
Benchmark 1: Rust flat DirstateMap → Rust tree DirstateMap
hg status
mozilla-clean 562.3 ms ± 2.0 ms → 462.5 ms ± 0.6 ms 1.22 ± 0.00 times faster
mozilla-dirty 859.6 ms ± 2.2 ms → 719.5 ms ± 3.2 ms 1.19 ± 0.01 times faster
mozilla-ignored 558.2 ms ± 3.0 ms → 457.9 ms ± 2.9 ms 1.22 ± 0.01 times faster
mozilla-unknowns 859.4 ms ± 5.7 ms → 716.0 ms ± 4.7 ms 1.20 ± 0.01 times faster
netbeans-clean 336.5 ms ± 0.9 ms → 339.5 ms ± 0.4 ms 0.99 ± 0.00 times faster
netbeans-dirty 491.4 ms ± 1.6 ms → 475.1 ms ± 1.2 ms 1.03 ± 0.00 times faster
netbeans-ignored 343.7 ms ± 1.0 ms → 347.8 ms ± 0.4 ms 0.99 ± 0.00 times faster
netbeans-unknowns 484.3 ms ± 1.0 ms → 466.0 ms ± 1.2 ms 1.04 ± 0.00 times faster
hg status -mard
mozilla-clean 317.3 ms ± 0.6 ms → 422.5 ms ± 1.2 ms 0.75 ± 0.00 times faster
mozilla-dirty 315.4 ms ± 0.6 ms → 417.7 ms ± 1.1 ms 0.76 ± 0.00 times faster
mozilla-ignored 314.6 ms ± 0.6 ms → 417.4 ms ± 1.0 ms 0.75 ± 0.00 times faster
mozilla-unknowns 312.9 ms ± 0.9 ms → 417.3 ms ± 1.6 ms 0.75 ± 0.00 times faster
netbeans-clean 212.0 ms ± 0.6 ms → 283.6 ms ± 0.8 ms 0.75 ± 0.00 times faster
netbeans-dirty 211.4 ms ± 1.0 ms → 283.4 ms ± 1.6 ms 0.75 ± 0.01 times faster
netbeans-ignored 211.4 ms ± 0.9 ms → 283.9 ms ± 0.8 ms 0.74 ± 0.01 times faster
netbeans-unknowns 211.1 ms ± 0.6 ms → 283.4 ms ± 1.0 ms 0.74 ± 0.00 times faster
Parsing
mozilla-clean 38.4ms → 177.6ms
mozilla-dirty 38.8ms → 177.0ms
mozilla-ignored 38.8ms → 178.0ms
mozilla-unknowns 38.7ms → 176.9ms
netbeans-clean 16.5ms → 97.3ms
netbeans-dirty 16.5ms → 98.4ms
netbeans-ignored 16.9ms → 97.4ms
netbeans-unknowns 16.9ms → 96.3ms
Benchmark 2: Python + C dirstatemap → Rust tree DirstateMap
hg status
mozilla-clean 1261.0 ms ± 3.6 ms → 461.1 ms ± 0.5 ms 2.73 ± 0.00 times faster
mozilla-dirty 2293.4 ms ± 9.1 ms → 719.6 ms ± 3.6 ms 3.19 ± 0.01 times faster
mozilla-ignored 1240.4 ms ± 2.3 ms → 457.7 ms ± 1.9 ms 2.71 ± 0.00 times faster
mozilla-unknowns 2283.3 ms ± 9.0 ms → 719.7 ms ± 3.8 ms 3.17 ± 0.01 times faster
netbeans-clean 879.7 ms ± 3.5 ms → 339.9 ms ± 0.5 ms 2.59 ± 0.00 times faster
netbeans-dirty 1257.3 ms ± 4.7 ms → 474.6 ms ± 1.6 ms 2.65 ± 0.01 times faster
netbeans-ignored 943.9 ms ± 1.9 ms → 347.3 ms ± 1.1 ms 2.72 ± 0.00 times faster
netbeans-unknowns 1188.1 ms ± 5.0 ms → 465.2 ms ± 2.3 ms 2.55 ± 0.01 times faster
hg status -mard
mozilla-clean 903.2 ms ± 3.6 ms → 423.4 ms ± 2.2 ms 2.13 ± 0.01 times faster
mozilla-dirty 884.6 ms ± 4.5 ms → 417.3 ms ± 1.4 ms 2.12 ± 0.01 times faster
mozilla-ignored 881.9 ms ± 1.3 ms → 417.3 ms ± 0.8 ms 2.11 ± 0.00 times faster
mozilla-unknowns 878.5 ms ± 1.9 ms → 416.4 ms ± 0.9 ms 2.11 ± 0.00 times faster
netbeans-clean 434.9 ms ± 1.8 ms → 284.0 ms ± 0.8 ms 1.53 ± 0.01 times faster
netbeans-dirty 434.1 ms ± 0.8 ms → 283.1 ms ± 0.8 ms 1.53 ± 0.00 times faster
netbeans-ignored 431.7 ms ± 1.1 ms → 283.6 ms ± 1.8 ms 1.52 ± 0.01 times faster
netbeans-unknowns 433.0 ms ± 1.3 ms → 283.5 ms ± 0.7 ms 1.53 ± 0.00 times faster
Differential Revision: https://phab.mercurial-scm.org/D11516
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 27 Sep 2021 12:09:15 +0200 |
parents | f2a9db29cb2d |
children | 66e22a4d856b |
rev | line source |
---|---|
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
1 // dirs_multiset.rs |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
2 // |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
3 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
4 // |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
5 // This software may be used and distributed according to the terms of the |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
6 // GNU General Public License version 2 or any later version. |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
7 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
8 //! A multiset of directory names. |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
9 //! |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
10 //! Used to counts the references to directories in a manifest or dirstate. |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
11 use crate::dirstate_tree::on_disk::DirstateV2ParseError; |
42749
7ceded4419a3
rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents:
42748
diff
changeset
|
12 use crate::{ |
44267
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
13 dirstate::EntryState, |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
14 utils::{ |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
15 files, |
44283
934a79697c36
rust-dirs-multiset: improve temporary error message
Raphaël Gomès <rgomes@octobus.net>
parents:
44267
diff
changeset
|
16 hg_path::{HgPath, HgPathBuf, HgPathError}, |
44267
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
17 }, |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
18 DirstateEntry, DirstateError, DirstateMapError, FastHashMap, |
42749
7ceded4419a3
rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents:
42748
diff
changeset
|
19 }; |
44267
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
20 use std::collections::{hash_map, hash_map::Entry, HashMap, HashSet}; |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
21 |
42885
a03a29462c0a
rust-dirstate: specify concrete return type of DirsMultiset::iter()
Yuya Nishihara <yuya@tcha.org>
parents:
42841
diff
changeset
|
22 // could be encapsulated if we care API stability more seriously |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
23 pub type DirsMultisetIter<'a> = hash_map::Keys<'a, HgPathBuf, u32>; |
42885
a03a29462c0a
rust-dirstate: specify concrete return type of DirsMultiset::iter()
Yuya Nishihara <yuya@tcha.org>
parents:
42841
diff
changeset
|
24 |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
25 #[derive(PartialEq, Debug)] |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
26 pub struct DirsMultiset { |
43826
5ac243a92e37
rust-performance: introduce FastHashMap type alias for HashMap
Raphaël Gomès <rgomes@octobus.net>
parents:
43788
diff
changeset
|
27 inner: FastHashMap<HgPathBuf, u32>, |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
28 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
29 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
30 impl DirsMultiset { |
42802
2e1f74cc3350
rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents:
42750
diff
changeset
|
31 /// Initializes the multiset from a dirstate. |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
32 /// |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
33 /// If `skip_state` is provided, skips dirstate entries with equal state. |
47332
4ee9f419c52e
rust: Return owned instead of borrowed DirstateEntry in DirstateMap APIs
Simon Sapin <simon.sapin@octobus.net>
parents:
47124
diff
changeset
|
34 pub fn from_dirstate<I, P>( |
47124
cd8ca38fccff
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents:
47093
diff
changeset
|
35 dirstate: I, |
47944
e02f9af7aed1
pathutil: replace the `skip` argument of `dirs` with a boolean
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
47335
diff
changeset
|
36 only_tracked: bool, |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
37 ) -> Result<Self, DirstateError> |
47124
cd8ca38fccff
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents:
47093
diff
changeset
|
38 where |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
39 I: IntoIterator< |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
40 Item = Result<(P, DirstateEntry), DirstateV2ParseError>, |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
41 >, |
47124
cd8ca38fccff
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents:
47093
diff
changeset
|
42 P: AsRef<HgPath>, |
cd8ca38fccff
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents:
47093
diff
changeset
|
43 { |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
44 let mut multiset = DirsMultiset { |
43826
5ac243a92e37
rust-performance: introduce FastHashMap type alias for HashMap
Raphaël Gomès <rgomes@octobus.net>
parents:
43788
diff
changeset
|
45 inner: FastHashMap::default(), |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
46 }; |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
47 for item in dirstate { |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
48 let (filename, entry) = item?; |
47124
cd8ca38fccff
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents:
47093
diff
changeset
|
49 let filename = filename.as_ref(); |
42802
2e1f74cc3350
rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents:
42750
diff
changeset
|
50 // This `if` is optimized out of the loop |
47944
e02f9af7aed1
pathutil: replace the `skip` argument of `dirs` with a boolean
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
47335
diff
changeset
|
51 if only_tracked { |
48022
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
47944
diff
changeset
|
52 if entry.state() != EntryState::Removed { |
43863
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
53 multiset.add_path(filename)?; |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
54 } |
42802
2e1f74cc3350
rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents:
42750
diff
changeset
|
55 } else { |
43863
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
56 multiset.add_path(filename)?; |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
57 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
58 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
59 |
43863
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
60 Ok(multiset) |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
61 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
62 |
42802
2e1f74cc3350
rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents:
42750
diff
changeset
|
63 /// Initializes the multiset from a manifest. |
43863
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
64 pub fn from_manifest( |
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
65 manifest: &[impl AsRef<HgPath>], |
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
66 ) -> Result<Self, DirstateMapError> { |
42802
2e1f74cc3350
rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents:
42750
diff
changeset
|
67 let mut multiset = DirsMultiset { |
43826
5ac243a92e37
rust-performance: introduce FastHashMap type alias for HashMap
Raphaël Gomès <rgomes@octobus.net>
parents:
43788
diff
changeset
|
68 inner: FastHashMap::default(), |
42802
2e1f74cc3350
rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents:
42750
diff
changeset
|
69 }; |
2e1f74cc3350
rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents:
42750
diff
changeset
|
70 |
43831
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
71 for filename in manifest { |
43863
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
72 multiset.add_path(filename.as_ref())?; |
42802
2e1f74cc3350
rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents:
42750
diff
changeset
|
73 } |
2e1f74cc3350
rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents:
42750
diff
changeset
|
74 |
43863
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
75 Ok(multiset) |
42802
2e1f74cc3350
rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents:
42750
diff
changeset
|
76 } |
2e1f74cc3350
rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents:
42750
diff
changeset
|
77 |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
78 /// Increases the count of deepest directory contained in the path. |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
79 /// |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
80 /// If the directory is not yet in the map, adds its parents. |
43831
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
81 pub fn add_path( |
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
82 &mut self, |
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
83 path: impl AsRef<HgPath>, |
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
84 ) -> Result<(), DirstateMapError> { |
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
85 for subpath in files::find_dirs(path.as_ref()) { |
43788
1fe2e574616e
rust-dirs: address failing tests for `dirs` impl with a temporary fix
Raphaël Gomès <rgomes@octobus.net>
parents:
42957
diff
changeset
|
86 if subpath.as_bytes().last() == Some(&b'/') { |
1fe2e574616e
rust-dirs: address failing tests for `dirs` impl with a temporary fix
Raphaël Gomès <rgomes@octobus.net>
parents:
42957
diff
changeset
|
87 // TODO Remove this once PathAuditor is certified |
1fe2e574616e
rust-dirs: address failing tests for `dirs` impl with a temporary fix
Raphaël Gomès <rgomes@octobus.net>
parents:
42957
diff
changeset
|
88 // as the only entrypoint for path data |
44283
934a79697c36
rust-dirs-multiset: improve temporary error message
Raphaël Gomès <rgomes@octobus.net>
parents:
44267
diff
changeset
|
89 let second_slash_index = subpath.len() - 1; |
934a79697c36
rust-dirs-multiset: improve temporary error message
Raphaël Gomès <rgomes@octobus.net>
parents:
44267
diff
changeset
|
90 |
934a79697c36
rust-dirs-multiset: improve temporary error message
Raphaël Gomès <rgomes@octobus.net>
parents:
44267
diff
changeset
|
91 return Err(DirstateMapError::InvalidPath( |
934a79697c36
rust-dirs-multiset: improve temporary error message
Raphaël Gomès <rgomes@octobus.net>
parents:
44267
diff
changeset
|
92 HgPathError::ConsecutiveSlashes { |
934a79697c36
rust-dirs-multiset: improve temporary error message
Raphaël Gomès <rgomes@octobus.net>
parents:
44267
diff
changeset
|
93 bytes: path.as_ref().as_bytes().to_owned(), |
934a79697c36
rust-dirs-multiset: improve temporary error message
Raphaël Gomès <rgomes@octobus.net>
parents:
44267
diff
changeset
|
94 second_slash_index, |
934a79697c36
rust-dirs-multiset: improve temporary error message
Raphaël Gomès <rgomes@octobus.net>
parents:
44267
diff
changeset
|
95 }, |
934a79697c36
rust-dirs-multiset: improve temporary error message
Raphaël Gomès <rgomes@octobus.net>
parents:
44267
diff
changeset
|
96 )); |
43788
1fe2e574616e
rust-dirs: address failing tests for `dirs` impl with a temporary fix
Raphaël Gomès <rgomes@octobus.net>
parents:
42957
diff
changeset
|
97 } |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
98 if let Some(val) = self.inner.get_mut(subpath) { |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
99 *val += 1; |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
100 break; |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
101 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
102 self.inner.insert(subpath.to_owned(), 1); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
103 } |
43788
1fe2e574616e
rust-dirs: address failing tests for `dirs` impl with a temporary fix
Raphaël Gomès <rgomes@octobus.net>
parents:
42957
diff
changeset
|
104 Ok(()) |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
105 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
106 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
107 /// Decreases the count of deepest directory contained in the path. |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
108 /// |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
109 /// If it is the only reference, decreases all parents until one is |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
110 /// removed. |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
111 /// If the directory is not in the map, something horrible has happened. |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
112 pub fn delete_path( |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
113 &mut self, |
43831
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
114 path: impl AsRef<HgPath>, |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
115 ) -> Result<(), DirstateMapError> { |
43831
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
116 for subpath in files::find_dirs(path.as_ref()) { |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
117 match self.inner.entry(subpath.to_owned()) { |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
118 Entry::Occupied(mut entry) => { |
44973
26114bd6ec60
rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents:
44283
diff
changeset
|
119 let val = *entry.get(); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
120 if val > 1 { |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
121 entry.insert(val - 1); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
122 break; |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
123 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
124 entry.remove(); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
125 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
126 Entry::Vacant(_) => { |
42557
d26e4a434fe5
rust: run rfmt on all hg-core/hg-cpython code
Raphaël Gomès <rgomes@octobus.net>
parents:
42536
diff
changeset
|
127 return Err(DirstateMapError::PathNotFound( |
43831
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
128 path.as_ref().to_owned(), |
42557
d26e4a434fe5
rust: run rfmt on all hg-core/hg-cpython code
Raphaël Gomès <rgomes@octobus.net>
parents:
42536
diff
changeset
|
129 )) |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
130 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
131 }; |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
132 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
133 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
134 Ok(()) |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
135 } |
42559
a80464e85ddd
rust: remove Deref in favor of explicit methods
Raphaël Gomès <rgomes@octobus.net>
parents:
42557
diff
changeset
|
136 |
43831
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
137 pub fn contains(&self, key: impl AsRef<HgPath>) -> bool { |
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
138 self.inner.contains_key(key.as_ref()) |
42559
a80464e85ddd
rust: remove Deref in favor of explicit methods
Raphaël Gomès <rgomes@octobus.net>
parents:
42557
diff
changeset
|
139 } |
a80464e85ddd
rust: remove Deref in favor of explicit methods
Raphaël Gomès <rgomes@octobus.net>
parents:
42557
diff
changeset
|
140 |
42885
a03a29462c0a
rust-dirstate: specify concrete return type of DirsMultiset::iter()
Yuya Nishihara <yuya@tcha.org>
parents:
42841
diff
changeset
|
141 pub fn iter(&self) -> DirsMultisetIter { |
42750
849e744b925d
rust-dirstate: improve API of `DirsMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
42749
diff
changeset
|
142 self.inner.keys() |
42559
a80464e85ddd
rust: remove Deref in favor of explicit methods
Raphaël Gomès <rgomes@octobus.net>
parents:
42557
diff
changeset
|
143 } |
a80464e85ddd
rust: remove Deref in favor of explicit methods
Raphaël Gomès <rgomes@octobus.net>
parents:
42557
diff
changeset
|
144 |
a80464e85ddd
rust: remove Deref in favor of explicit methods
Raphaël Gomès <rgomes@octobus.net>
parents:
42557
diff
changeset
|
145 pub fn len(&self) -> usize { |
a80464e85ddd
rust: remove Deref in favor of explicit methods
Raphaël Gomès <rgomes@octobus.net>
parents:
42557
diff
changeset
|
146 self.inner.len() |
a80464e85ddd
rust: remove Deref in favor of explicit methods
Raphaël Gomès <rgomes@octobus.net>
parents:
42557
diff
changeset
|
147 } |
44973
26114bd6ec60
rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents:
44283
diff
changeset
|
148 |
26114bd6ec60
rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents:
44283
diff
changeset
|
149 pub fn is_empty(&self) -> bool { |
26114bd6ec60
rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents:
44283
diff
changeset
|
150 self.len() == 0 |
26114bd6ec60
rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents:
44283
diff
changeset
|
151 } |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
152 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
153 |
44267
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
154 /// This is basically a reimplementation of `DirsMultiset` that stores the |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
155 /// children instead of just a count of them, plus a small optional |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
156 /// optimization to avoid some directories we don't need. |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
157 #[derive(PartialEq, Debug)] |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
158 pub struct DirsChildrenMultiset<'a> { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
159 inner: FastHashMap<&'a HgPath, HashSet<&'a HgPath>>, |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
160 only_include: Option<HashSet<&'a HgPath>>, |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
161 } |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
162 |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
163 impl<'a> DirsChildrenMultiset<'a> { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
164 pub fn new( |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
165 paths: impl Iterator<Item = &'a HgPathBuf>, |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
166 only_include: Option<&'a HashSet<impl AsRef<HgPath> + 'a>>, |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
167 ) -> Self { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
168 let mut new = Self { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
169 inner: HashMap::default(), |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
170 only_include: only_include |
44973
26114bd6ec60
rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents:
44283
diff
changeset
|
171 .map(|s| s.iter().map(AsRef::as_ref).collect()), |
44267
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
172 }; |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
173 |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
174 for path in paths { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
175 new.add_path(path) |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
176 } |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
177 |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
178 new |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
179 } |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
180 fn add_path(&mut self, path: &'a (impl AsRef<HgPath> + 'a)) { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
181 if path.as_ref().is_empty() { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
182 return; |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
183 } |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
184 for (directory, basename) in files::find_dirs_with_base(path.as_ref()) |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
185 { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
186 if !self.is_dir_included(directory) { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
187 continue; |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
188 } |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
189 self.inner |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
190 .entry(directory) |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
191 .and_modify(|e| { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
192 e.insert(basename); |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
193 }) |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
194 .or_insert_with(|| { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
195 let mut set = HashSet::new(); |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
196 set.insert(basename); |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
197 set |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
198 }); |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
199 } |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
200 } |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
201 fn is_dir_included(&self, dir: impl AsRef<HgPath>) -> bool { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
202 match &self.only_include { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
203 None => false, |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
204 Some(i) => i.contains(dir.as_ref()), |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
205 } |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
206 } |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
207 |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
208 pub fn get( |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
209 &self, |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
210 path: impl AsRef<HgPath>, |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
211 ) -> Option<&HashSet<&'a HgPath>> { |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
212 self.inner.get(path.as_ref()) |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
213 } |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
214 } |
0e9ac3968b56
rust-dirs-multiset: add `DirsChildrenMultiset`
Raphaël Gomès <rgomes@octobus.net>
parents:
43890
diff
changeset
|
215 |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
216 #[cfg(test)] |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
217 mod tests { |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
218 use super::*; |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
219 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
220 #[test] |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
221 fn test_delete_path_path_not_found() { |
43831
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
222 let manifest: Vec<HgPathBuf> = vec![]; |
43863
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
223 let mut map = DirsMultiset::from_manifest(&manifest).unwrap(); |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
224 let path = HgPathBuf::from_bytes(b"doesnotexist/"); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
225 assert_eq!( |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
226 Err(DirstateMapError::PathNotFound(path.to_owned())), |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
227 map.delete_path(&path) |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
228 ); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
229 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
230 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
231 #[test] |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
232 fn test_delete_path_empty_path() { |
43863
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
233 let mut map = |
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
234 DirsMultiset::from_manifest(&vec![HgPathBuf::new()]).unwrap(); |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
235 let path = HgPath::new(b""); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
236 assert_eq!(Ok(()), map.delete_path(path)); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
237 assert_eq!( |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
238 Err(DirstateMapError::PathNotFound(path.to_owned())), |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
239 map.delete_path(path) |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
240 ); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
241 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
242 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
243 #[test] |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
244 fn test_delete_path_successful() { |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
245 let mut map = DirsMultiset { |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
246 inner: [("", 5), ("a", 3), ("a/b", 2), ("a/c", 1)] |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
247 .iter() |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
248 .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v)) |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
249 .collect(), |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
250 }; |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
251 |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
252 assert_eq!(Ok(()), map.delete_path(HgPath::new(b"a/b/"))); |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
253 eprintln!("{:?}", map); |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
254 assert_eq!(Ok(()), map.delete_path(HgPath::new(b"a/b/"))); |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
255 eprintln!("{:?}", map); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
256 assert_eq!( |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
257 Err(DirstateMapError::PathNotFound(HgPathBuf::from_bytes( |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
258 b"a/b/" |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
259 ))), |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
260 map.delete_path(HgPath::new(b"a/b/")) |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
261 ); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
262 |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
263 assert_eq!(2, *map.inner.get(HgPath::new(b"a")).unwrap()); |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
264 assert_eq!(1, *map.inner.get(HgPath::new(b"a/c")).unwrap()); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
265 eprintln!("{:?}", map); |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
266 assert_eq!(Ok(()), map.delete_path(HgPath::new(b"a/"))); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
267 eprintln!("{:?}", map); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
268 |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
269 assert_eq!(Ok(()), map.delete_path(HgPath::new(b"a/c/"))); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
270 assert_eq!( |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
271 Err(DirstateMapError::PathNotFound(HgPathBuf::from_bytes( |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
272 b"a/c/" |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
273 ))), |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
274 map.delete_path(HgPath::new(b"a/c/")) |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
275 ); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
276 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
277 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
278 #[test] |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
279 fn test_add_path_empty_path() { |
43831
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
280 let manifest: Vec<HgPathBuf> = vec![]; |
43863
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
281 let mut map = DirsMultiset::from_manifest(&manifest).unwrap(); |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
282 let path = HgPath::new(b""); |
43890
d8a96cebf75d
rust-warnings: fix warnings in tests
Raphaël Gomès <rgomes@octobus.net>
parents:
43863
diff
changeset
|
283 map.add_path(path).unwrap(); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
284 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
285 assert_eq!(1, map.len()); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
286 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
287 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
288 #[test] |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
289 fn test_add_path_successful() { |
43831
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
290 let manifest: Vec<HgPathBuf> = vec![]; |
43863
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
291 let mut map = DirsMultiset::from_manifest(&manifest).unwrap(); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
292 |
43890
d8a96cebf75d
rust-warnings: fix warnings in tests
Raphaël Gomès <rgomes@octobus.net>
parents:
43863
diff
changeset
|
293 map.add_path(HgPath::new(b"a/")).unwrap(); |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
294 assert_eq!(1, *map.inner.get(HgPath::new(b"a")).unwrap()); |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
295 assert_eq!(1, *map.inner.get(HgPath::new(b"")).unwrap()); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
296 assert_eq!(2, map.len()); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
297 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
298 // Non directory should be ignored |
43890
d8a96cebf75d
rust-warnings: fix warnings in tests
Raphaël Gomès <rgomes@octobus.net>
parents:
43863
diff
changeset
|
299 map.add_path(HgPath::new(b"a")).unwrap(); |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
300 assert_eq!(1, *map.inner.get(HgPath::new(b"a")).unwrap()); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
301 assert_eq!(2, map.len()); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
302 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
303 // Non directory will still add its base |
43890
d8a96cebf75d
rust-warnings: fix warnings in tests
Raphaël Gomès <rgomes@octobus.net>
parents:
43863
diff
changeset
|
304 map.add_path(HgPath::new(b"a/b")).unwrap(); |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
305 assert_eq!(2, *map.inner.get(HgPath::new(b"a")).unwrap()); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
306 assert_eq!(2, map.len()); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
307 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
308 // Duplicate path works |
43890
d8a96cebf75d
rust-warnings: fix warnings in tests
Raphaël Gomès <rgomes@octobus.net>
parents:
43863
diff
changeset
|
309 map.add_path(HgPath::new(b"a/")).unwrap(); |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
310 assert_eq!(3, *map.inner.get(HgPath::new(b"a")).unwrap()); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
311 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
312 // Nested dir adds to its base |
43890
d8a96cebf75d
rust-warnings: fix warnings in tests
Raphaël Gomès <rgomes@octobus.net>
parents:
43863
diff
changeset
|
313 map.add_path(HgPath::new(b"a/b/")).unwrap(); |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
314 assert_eq!(4, *map.inner.get(HgPath::new(b"a")).unwrap()); |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
315 assert_eq!(1, *map.inner.get(HgPath::new(b"a/b")).unwrap()); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
316 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
317 // but not its base's base, because it already existed |
43890
d8a96cebf75d
rust-warnings: fix warnings in tests
Raphaël Gomès <rgomes@octobus.net>
parents:
43863
diff
changeset
|
318 map.add_path(HgPath::new(b"a/b/c/")).unwrap(); |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
319 assert_eq!(4, *map.inner.get(HgPath::new(b"a")).unwrap()); |
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
320 assert_eq!(2, *map.inner.get(HgPath::new(b"a/b")).unwrap()); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
321 |
43890
d8a96cebf75d
rust-warnings: fix warnings in tests
Raphaël Gomès <rgomes@octobus.net>
parents:
43863
diff
changeset
|
322 map.add_path(HgPath::new(b"a/c/")).unwrap(); |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
323 assert_eq!(1, *map.inner.get(HgPath::new(b"a/c")).unwrap()); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
324 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
325 let expected = DirsMultiset { |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
326 inner: [("", 2), ("a", 5), ("a/b", 2), ("a/b/c", 1), ("a/c", 1)] |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
327 .iter() |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
328 .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v)) |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
329 .collect(), |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
330 }; |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
331 assert_eq!(map, expected); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
332 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
333 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
334 #[test] |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
335 fn test_dirsmultiset_new_empty() { |
43831
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
336 let manifest: Vec<HgPathBuf> = vec![]; |
43863
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
337 let new = DirsMultiset::from_manifest(&manifest).unwrap(); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
338 let expected = DirsMultiset { |
43826
5ac243a92e37
rust-performance: introduce FastHashMap type alias for HashMap
Raphaël Gomès <rgomes@octobus.net>
parents:
43788
diff
changeset
|
339 inner: FastHashMap::default(), |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
340 }; |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
341 assert_eq!(expected, new); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
342 |
48068
bf8837e3d7ce
dirstate: Remove the flat Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
343 let new = DirsMultiset::from_dirstate::<_, HgPathBuf>( |
bf8837e3d7ce
dirstate: Remove the flat Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
344 std::iter::empty(), |
47944
e02f9af7aed1
pathutil: replace the `skip` argument of `dirs` with a boolean
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
47335
diff
changeset
|
345 false, |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
346 ) |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
347 .unwrap(); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
348 let expected = DirsMultiset { |
43826
5ac243a92e37
rust-performance: introduce FastHashMap type alias for HashMap
Raphaël Gomès <rgomes@octobus.net>
parents:
43788
diff
changeset
|
349 inner: FastHashMap::default(), |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
350 }; |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
351 assert_eq!(expected, new); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
352 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
353 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
354 #[test] |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
355 fn test_dirsmultiset_new_no_skip() { |
43831
088ba9d94079
rust-dirs-multiset: use `AsRef` instead of concrete types when possible
Raphaël Gomès <rgomes@octobus.net>
parents:
43826
diff
changeset
|
356 let input_vec: Vec<HgPathBuf> = ["a/", "b/", "a/c", "a/d/"] |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
357 .iter() |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
358 .map(|e| HgPathBuf::from_bytes(e.as_bytes())) |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
359 .collect(); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
360 let expected_inner = [("", 2), ("a", 3), ("b", 1), ("a/d", 1)] |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
361 .iter() |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
362 .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v)) |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
363 .collect(); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
364 |
43863
bc7d8f45c3b6
rust-dirs: handle forgotten `Result`s
Raphaël Gomès <rgomes@octobus.net>
parents:
43831
diff
changeset
|
365 let new = DirsMultiset::from_manifest(&input_vec).unwrap(); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
366 let expected = DirsMultiset { |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
367 inner: expected_inner, |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
368 }; |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
369 assert_eq!(expected, new); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
370 |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
371 let input_map = ["b/x", "a/c", "a/d/x"].iter().map(|f| { |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
372 Ok(( |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
373 HgPathBuf::from_bytes(f.as_bytes()), |
48022
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
47944
diff
changeset
|
374 DirstateEntry::from_v1_data(EntryState::Normal, 0, 0, 0), |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
375 )) |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
376 }); |
45610
496537c9c1b4
rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents:
44973
diff
changeset
|
377 let expected_inner = [("", 2), ("a", 2), ("b", 1), ("a/d", 1)] |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
378 .iter() |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
379 .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v)) |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
380 .collect(); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
381 |
47944
e02f9af7aed1
pathutil: replace the `skip` argument of `dirs` with a boolean
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
47335
diff
changeset
|
382 let new = DirsMultiset::from_dirstate(input_map, false).unwrap(); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
383 let expected = DirsMultiset { |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
384 inner: expected_inner, |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
385 }; |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
386 assert_eq!(expected, new); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
387 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
388 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
389 #[test] |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
390 fn test_dirsmultiset_new_skip() { |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
391 let input_map = [ |
42749
7ceded4419a3
rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents:
42748
diff
changeset
|
392 ("a/", EntryState::Normal), |
45610
496537c9c1b4
rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents:
44973
diff
changeset
|
393 ("a/b", EntryState::Normal), |
42749
7ceded4419a3
rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents:
42748
diff
changeset
|
394 ("a/c", EntryState::Removed), |
45610
496537c9c1b4
rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents:
44973
diff
changeset
|
395 ("a/d", EntryState::Merged), |
42749
7ceded4419a3
rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents:
42748
diff
changeset
|
396 ] |
7ceded4419a3
rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents:
42748
diff
changeset
|
397 .iter() |
7ceded4419a3
rust-dirstate: use EntryState enum instead of literals
Raphaël Gomès <rgomes@octobus.net>
parents:
42748
diff
changeset
|
398 .map(|(f, state)| { |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
399 Ok(( |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
400 HgPathBuf::from_bytes(f.as_bytes()), |
48022
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
47944
diff
changeset
|
401 DirstateEntry::from_v1_data(*state, 0, 0, 0), |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
402 )) |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47332
diff
changeset
|
403 }); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
404 |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
405 // "a" incremented with "a/c" and "a/d/" |
47944
e02f9af7aed1
pathutil: replace the `skip` argument of `dirs` with a boolean
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
47335
diff
changeset
|
406 let expected_inner = [("", 1), ("a", 3)] |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
407 .iter() |
42957
7a01778bc7b7
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Raphaël Gomès <rgomes@octobus.net>
parents:
42885
diff
changeset
|
408 .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v)) |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
409 .collect(); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
410 |
47944
e02f9af7aed1
pathutil: replace the `skip` argument of `dirs` with a boolean
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
47335
diff
changeset
|
411 let new = DirsMultiset::from_dirstate(input_map, true).unwrap(); |
42536
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
412 let expected = DirsMultiset { |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
413 inner: expected_inner, |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
414 }; |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
415 assert_eq!(expected, new); |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
416 } |
2dcee6497b0b
rust-dirstate: add "dirs" Rust implementation
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
417 } |