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