Mercurial > public > mercurial-scm > hg-stable
annotate rust/hg-core/examples/nodemap/index.rs @ 49210:34decbaf4da3
node: manually implement Debug
I got too irritated today with the default Debug implementation of
hg::revlog::Node while playing with a new parser. This isn't quite
what I wanted, but it wasn't much code and it at least gives you
output that's easy to visually compare to a node.hex()ed identifier
from the Python side of things.
Sadly, this doesn't influence the output in lldb or the VSCode
debugger extension that uses lldb under the covers, but it at least
means debug prints are a little more useful.
Differential Revision: https://phab.mercurial-scm.org/D12608
author | Augie Fackler <augie@google.com> |
---|---|
date | Thu, 05 May 2022 14:47:26 -0400 |
parents | e834b79def74 |
children | 4c5f6e95df84 |
rev | line source |
---|---|
44417
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::*; |
47983
e834b79def74
rust: Switch to the memmap2-rs crate
Simon Sapin <simon.sapin@octobus.net>
parents:
44417
diff
changeset
|
8 use memmap2::*; |
44417
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 } |