Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/dirstate_tree/owning.rs @ 50861:76387f79befe
rust-status: only visit parts of the tree requested by the matcher
This is an optimization that the matcher is designed to support, but
we weren't doing it until now. This is primarily relevant for
supporting "hg status [FILES]", where this optimization is crucial for
getting good performance (without this optimization, that command will
still scan the entire tree, and just filter it down after the fact).
When this optimization fires we have to return false from
traverse_fs_directory_and_dirstate, representing that that part of the
tree *might* have new files which we didn't see because we skipped
parts of it. This only affects the cached result of the status, and
is necessary to make future status operations (which might use a
different matcher) work properly.
author | Spencer Baugh <sbaugh@janestreet.com> |
---|---|
date | Wed, 02 Aug 2023 10:33:11 -0400 |
parents | 2cc5de261d76 |
children | 88aa21d654e5 |
rev | line source |
---|---|
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
1 use crate::{DirstateError, DirstateParents}; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
2 |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
3 use super::dirstate_map::DirstateMap; |
50679
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
4 use self_cell::self_cell; |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
5 use std::ops::Deref; |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
6 |
50679
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
7 self_cell!( |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
8 /// Keep a `DirstateMap<'owner>` next to the `owner` buffer that it |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
9 /// borrows. |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
10 pub struct OwningDirstateMap { |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
11 owner: Box<dyn Deref<Target = [u8]> + Send>, |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
12 #[covariant] |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
13 dependent: DirstateMap, |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
14 } |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
15 ); |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
16 |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
17 impl OwningDirstateMap { |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
18 pub fn new_empty<OnDisk>(on_disk: OnDisk) -> Self |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
19 where |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
20 OnDisk: Deref<Target = [u8]> + Send + 'static, |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
21 { |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
22 let on_disk = Box::new(on_disk); |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
23 |
50679
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
24 OwningDirstateMap::new(on_disk, |bytes| DirstateMap::empty(bytes)) |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
25 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
26 |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
27 pub fn new_v1<OnDisk>( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
28 on_disk: OnDisk, |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
29 identity: Option<u64>, |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
30 ) -> Result<(Self, DirstateParents), DirstateError> |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
31 where |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
32 OnDisk: Deref<Target = [u8]> + Send + 'static, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
33 { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
34 let on_disk = Box::new(on_disk); |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
35 let mut parents = DirstateParents::NULL; |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
36 |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
37 Ok(( |
50679
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
38 OwningDirstateMap::try_new(on_disk, |bytes| { |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
39 DirstateMap::new_v1(bytes, identity).map(|(dmap, p)| { |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
40 parents = p.unwrap_or(DirstateParents::NULL); |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
41 dmap |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
42 }) |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
43 })?, |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
44 parents, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
45 )) |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
46 } |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
47 |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
48 pub fn new_v2<OnDisk>( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
49 on_disk: OnDisk, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
50 data_size: usize, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
51 metadata: &[u8], |
50243
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49000
diff
changeset
|
52 uuid: Vec<u8>, |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
53 identity: Option<u64>, |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
54 ) -> Result<Self, DirstateError> |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
55 where |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
56 OnDisk: Deref<Target = [u8]> + Send + 'static, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
57 { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
58 let on_disk = Box::new(on_disk); |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
59 |
50679
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
60 OwningDirstateMap::try_new(on_disk, |bytes| { |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
61 DirstateMap::new_v2(bytes, data_size, metadata, uuid, identity) |
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
62 }) |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
63 } |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
64 |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
65 pub fn with_dmap_mut<R>( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
66 &mut self, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
67 f: impl FnOnce(&mut DirstateMap) -> R, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
68 ) -> R { |
50679
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
69 self.with_dependent_mut(|_owner, dmap| f(dmap)) |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
70 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
71 |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
72 pub fn get_map(&self) -> &DirstateMap { |
50679
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
73 self.borrow_dependent() |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
74 } |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
75 |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48999
diff
changeset
|
76 pub fn on_disk(&self) -> &[u8] { |
50679
2cc5de261d76
rust-hg-core: move from `ouroboros` to `self_cell`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
77 self.borrow_owner() |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
78 } |
50243
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49000
diff
changeset
|
79 |
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49000
diff
changeset
|
80 pub fn old_uuid(&self) -> Option<&[u8]> { |
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49000
diff
changeset
|
81 self.get_map().old_uuid.as_deref() |
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49000
diff
changeset
|
82 } |
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49000
diff
changeset
|
83 |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
84 pub fn old_identity(&self) -> Option<u64> { |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
85 self.get_map().identity |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
86 } |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
87 |
50243
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49000
diff
changeset
|
88 pub fn old_data_size(&self) -> usize { |
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49000
diff
changeset
|
89 self.get_map().old_data_size |
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49000
diff
changeset
|
90 } |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
91 } |