Mercurial > hg
view rust/hg-core/examples/nodemap/index.rs @ 46538:2f99dedf96b1
test-copies: improve description of the G+F case
This will make its role clearer.
Differential Revision: https://phab.mercurial-scm.org/D10042
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 16 Feb 2021 05:46:32 +0100 |
parents | 8f7c6656ac79 |
children | e834b79def74 |
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 memmap::*; 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)), } } }