Mercurial > hg
view rust/hg-core/examples/nodemap/index.rs @ 51222:fc05dd74e907
rust-index: add support for `reachableroots2`
Exposition in `hg-cpython` done in regular impl block, again
for rustfmt support etc.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Mon, 30 Oct 2023 11:57:36 +0100 |
parents | 4c5f6e95df84 |
children | bd8081e9fd62 |
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] { [self.p1, self.p2] } } impl RevlogIndex for Index { fn len(&self) -> usize { self.data.len() } fn node(&self, rev: Revision) -> Option<&Node> { if rev == NULL_REVISION { return None; } Some(&self.data[rev.0 as usize].node) } } impl Graph for &Index { fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { let [p1, p2] = self.data[rev.0 as usize].parents(); let len = (*self).len(); if p1 < NULL_REVISION || p2 < NULL_REVISION || p1.0 as usize >= len || p2.0 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)), } } }