Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/examples/nodemap/index.rs @ 47964:796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
When `rhg status` cannot determine whether a file is clean based on mtime and
size alone, it needs to compare its contents with those found in the parent
commit. Previously, rhg would find the (same) manifest of that commit again
for every such file. This is lifted out of the loop and reused.
Differential Revision: https://phab.mercurial-scm.org/D11411
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 13 Sep 2021 18:09:10 +0200 |
parents | e834b79def74 |
children | 4c5f6e95df84 |
rev | line source |
---|---|
44386
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
1 // Copyright 2019-2020 Georges Racinet <georges.racinet@octobus.net> |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
2 // |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
3 // This software may be used and distributed according to the terms of the |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
4 // GNU General Public License version 2 or any later version. |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
5 |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
6 //! Minimal `RevlogIndex`, readable from standard Mercurial file format |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
7 use hg::*; |
47955
e834b79def74
rust: Switch to the memmap2-rs crate
Simon Sapin <simon.sapin@octobus.net>
parents:
44386
diff
changeset
|
8 use memmap2::*; |
44386
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
9 use std::fs::File; |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
10 use std::ops::Deref; |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
11 use std::path::Path; |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
12 use std::slice; |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
13 |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
14 pub struct Index { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
15 data: Box<dyn Deref<Target = [IndexEntry]> + Send>, |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
16 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
17 |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
18 /// A fixed sized index entry. All numbers are big endian |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
19 #[repr(C)] |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
20 pub struct IndexEntry { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
21 not_used_yet: [u8; 24], |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
22 p1: Revision, |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
23 p2: Revision, |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
24 node: Node, |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
25 unused_node: [u8; 12], |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
26 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
27 |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
28 pub const INDEX_ENTRY_SIZE: usize = 64; |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
29 |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
30 impl IndexEntry { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
31 fn parents(&self) -> [Revision; 2] { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
32 [Revision::from_be(self.p1), Revision::from_be(self.p1)] |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
33 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
34 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
35 |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
36 impl RevlogIndex for Index { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
37 fn len(&self) -> usize { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
38 self.data.len() |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
39 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
40 |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
41 fn node(&self, rev: Revision) -> Option<&Node> { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
42 if rev == NULL_REVISION { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
43 return None; |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
44 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
45 let i = rev as usize; |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
46 if i >= self.len() { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
47 None |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
48 } else { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
49 Some(&self.data[i].node) |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
50 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
51 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
52 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
53 |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
54 impl Graph for &Index { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
55 fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
56 let [p1, p2] = (*self).data[rev as usize].parents(); |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
57 let len = (*self).len(); |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
58 if p1 < NULL_REVISION |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
59 || p2 < NULL_REVISION |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
60 || p1 as usize >= len |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
61 || p2 as usize >= len |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
62 { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
63 return Err(GraphError::ParentOutOfRange(rev)); |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
64 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
65 Ok([p1, p2]) |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
66 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
67 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
68 |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
69 struct IndexMmap(Mmap); |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
70 |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
71 impl Deref for IndexMmap { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
72 type Target = [IndexEntry]; |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
73 |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
74 fn deref(&self) -> &[IndexEntry] { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
75 let ptr = self.0.as_ptr() as *const IndexEntry; |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
76 // Any misaligned data will be ignored. |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
77 debug_assert_eq!( |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
78 self.0.len() % std::mem::align_of::<IndexEntry>(), |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
79 0, |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
80 "Misaligned data in mmap" |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
81 ); |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
82 unsafe { slice::from_raw_parts(ptr, self.0.len() / INDEX_ENTRY_SIZE) } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
83 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
84 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
85 |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
86 impl Index { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
87 pub fn load_mmap(path: impl AsRef<Path>) -> Self { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
88 let file = File::open(path).unwrap(); |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
89 let msg = "Index file is missing, or missing permission"; |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
90 let mmap = unsafe { MmapOptions::new().map(&file) }.expect(msg); |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
91 Self { |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
92 data: Box::new(IndexMmap(mmap)), |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
93 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
94 } |
8f7c6656ac79
rust-nodemap: pure Rust example
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
95 } |