author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
Fri, 26 Apr 2024 19:10:35 +0100 | |
changeset 51626 | 865efc020c33 |
parent 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; |
50682
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 |
|
50682
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 |
|
50682
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(( |
50682
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 |
|
50682
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 { |
50682
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 { |
50682
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] { |
50682
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 |
} |