author | Pierre-Yves David <pierre-yves.david@octobus.net> |
Thu, 02 Mar 2023 19:02:52 +0100 | |
changeset 50252 | a6b8b1ab9116 |
parent 49930 | e98fd81bb151 |
parent 50245 | dbe09fb038fc |
child 50682 | 2cc5de261d76 |
permissions | -rw-r--r-- |
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; |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
4 |
use std::ops::Deref; |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
5 |
|
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
6 |
use ouroboros::self_referencing; |
48999
cfd270d83169
rust: explain why the current `OwningDirstateMap` is unsound
Raphaël Gomès <rgomes@octobus.net>
parents:
48567
diff
changeset
|
7 |
|
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
8 |
/// Keep a `DirstateMap<'on_disk>` next to the `on_disk` buffer that it |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
9 |
/// borrows. |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
10 |
#[self_referencing] |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
11 |
pub struct OwningDirstateMap { |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
12 |
on_disk: Box<dyn Deref<Target = [u8]> + Send>, |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
13 |
#[borrows(on_disk)] |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
14 |
#[covariant] |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
15 |
map: DirstateMap<'this>, |
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 |
|
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
18 |
impl OwningDirstateMap { |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
19 |
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
|
20 |
where |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
21 |
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
|
22 |
{ |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
23 |
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
|
24 |
|
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
25 |
OwningDirstateMapBuilder { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
26 |
on_disk, |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents:
49000
diff
changeset
|
27 |
map_builder: |bytes| DirstateMap::empty(bytes), |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
28 |
} |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
29 |
.build() |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
30 |
} |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
31 |
|
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
32 |
pub fn new_v1<OnDisk>( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
33 |
on_disk: OnDisk, |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Raphaël Gomès <rgomes@octobus.net>
parents:
50243
diff
changeset
|
34 |
identity: Option<u64>, |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
35 |
) -> Result<(Self, DirstateParents), DirstateError> |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
36 |
where |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
37 |
OnDisk: Deref<Target = [u8]> + Send + 'static, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
38 |
{ |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
39 |
let on_disk = Box::new(on_disk); |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
40 |
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
|
41 |
|
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
42 |
Ok(( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
43 |
OwningDirstateMapTryBuilder { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
44 |
on_disk, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
45 |
map_builder: |bytes| { |
50252
a6b8b1ab9116
branching: merge stable into default
Pierre-Yves David <pierre-yves.david@octobus.net>
diff
changeset
|
46 |
DirstateMap::new_v1(bytes, identity).map(|(dmap, p)| { |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
47 |
parents = p.unwrap_or(DirstateParents::NULL); |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
48 |
dmap |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
49 |
}) |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
50 |
}, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
51 |
} |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
52 |
.try_build()?, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
53 |
parents, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
54 |
)) |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
55 |
} |
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
56 |
|
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
57 |
pub fn new_v2<OnDisk>( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
58 |
on_disk: OnDisk, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
59 |
data_size: usize, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
60 |
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
|
61 |
uuid: Vec<u8>, |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Raphaël Gomès <rgomes@octobus.net>
parents:
50243
diff
changeset
|
62 |
identity: Option<u64>, |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
63 |
) -> Result<Self, DirstateError> |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
64 |
where |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
65 |
OnDisk: Deref<Target = [u8]> + Send + 'static, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
66 |
{ |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
67 |
let on_disk = Box::new(on_disk); |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
68 |
|
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
69 |
OwningDirstateMapTryBuilder { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
70 |
on_disk, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
71 |
map_builder: |bytes| { |
50252
a6b8b1ab9116
branching: merge stable into default
Pierre-Yves David <pierre-yves.david@octobus.net>
diff
changeset
|
72 |
DirstateMap::new_v2(bytes, data_size, metadata, uuid, identity) |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
73 |
}, |
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 |
.try_build() |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
76 |
} |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
77 |
|
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
78 |
pub fn with_dmap_mut<R>( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
79 |
&mut self, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
80 |
f: impl FnOnce(&mut DirstateMap) -> R, |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
81 |
) -> R { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
82 |
self.with_map_mut(f) |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
83 |
} |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
84 |
|
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
85 |
pub fn get_map(&self) -> &DirstateMap { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
86 |
self.borrow_map() |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
87 |
} |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
88 |
|
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
89 |
pub fn on_disk(&self) -> &[u8] { |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48999
diff
changeset
|
90 |
self.borrow_on_disk() |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
91 |
} |
50243
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Raphaël Gomès <rgomes@octobus.net>
parents:
49000
diff
changeset
|
92 |
|
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Raphaël Gomès <rgomes@octobus.net>
parents:
49000
diff
changeset
|
93 |
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
|
94 |
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
|
95 |
} |
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Raphaël Gomès <rgomes@octobus.net>
parents:
49000
diff
changeset
|
96 |
|
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Raphaël Gomès <rgomes@octobus.net>
parents:
50243
diff
changeset
|
97 |
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
|
98 |
self.get_map().identity |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Raphaël Gomès <rgomes@octobus.net>
parents:
50243
diff
changeset
|
99 |
} |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Raphaël Gomès <rgomes@octobus.net>
parents:
50243
diff
changeset
|
100 |
|
50243
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Raphaël Gomès <rgomes@octobus.net>
parents:
49000
diff
changeset
|
101 |
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
|
102 |
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
|
103 |
} |
47123
d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
104 |
} |