Mercurial > public > mercurial-scm > hg-stable
view 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 |
line wrap: on
line source
// Copyright 2019-2020 Georges Racinet <georges.racinet@octobus.net> // // This software may be used and distributed according to the terms of the // GNU General Public License version 2 or any later version. //! Minimal `RevlogIndex`, readable from standard Mercurial file format use hg::*; use memmap2::*; use std::fs::File; use std::ops::Deref; use std::path::Path; use std::slice; pub struct Index { data: Box<dyn Deref<Target = [IndexEntry]> + Send>, } /// A fixed sized index entry. All numbers are big endian #[repr(C)] pub struct IndexEntry { not_used_yet: [u8; 24], p1: Revision, p2: Revision, node: Node, unused_node: [u8; 12], } pub const INDEX_ENTRY_SIZE: usize = 64; impl IndexEntry { fn parents(&self) -> [Revision; 2] { [Revision::from_be(self.p1), Revision::from_be(self.p1)] } } impl RevlogIndex for Index { fn len(&self) -> usize { self.data.len() } fn node(&self, rev: Revision) -> Option<&Node> { if rev == NULL_REVISION { return None; } let i = rev as usize; if i >= self.len() { None } else { Some(&self.data[i].node) } } } impl Graph for &Index { fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { let [p1, p2] = (*self).data[rev as usize].parents(); let len = (*self).len(); if p1 < NULL_REVISION || p2 < NULL_REVISION || p1 as usize >= len || p2 as usize >= len { return Err(GraphError::ParentOutOfRange(rev)); } Ok([p1, p2]) } } struct IndexMmap(Mmap); impl Deref for IndexMmap { type Target = [IndexEntry]; fn deref(&self) -> &[IndexEntry] { let ptr = self.0.as_ptr() as *const IndexEntry; // Any misaligned data will be ignored. debug_assert_eq!( self.0.len() % std::mem::align_of::<IndexEntry>(), 0, "Misaligned data in mmap" ); unsafe { slice::from_raw_parts(ptr, self.0.len() / INDEX_ENTRY_SIZE) } } } impl Index { pub fn load_mmap(path: impl AsRef<Path>) -> Self { let file = File::open(path).unwrap(); let msg = "Index file is missing, or missing permission"; let mmap = unsafe { MmapOptions::new().map(&file) }.expect(msg); Self { data: Box::new(IndexMmap(mmap)), } } }