Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/dirstate_tree/owning.rs @ 51616:b08c5fbe0e70 stable
rust: blanket implementation of Graph for Graph references
The need comes from the fact that `AncestorsIterator` and many
Graph-related algorithms take ownership of the `Graph` they work with.
This, in turn is due to them needing to accept the `Index` instances
that are provided by the Python layers (that neither rhg nor `RHGitaly`
use, of course): the fact that nowadays the Python layer holds an object
that is itself implemented in Rust does not change the core problem that
they cannot be tracked by the borrow checker.
Even though it looks like cloning `Changelog` would be cheap, it seems
hard to guarantee that on the long run. The object is already too rich
for us to be comfortable with it, when using references is the most
natural and guaranteed way of proceeding.
The added test seems a bit superfleous, but it will act as a reminder
that this feature is really useful until something in the Mercurial code
base actually uses it.
author | Georges Racinet <georges.racinet@octobus.net> |
---|---|
date | Mon, 22 Apr 2024 19:47:08 +0200 |
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 } |