##// END OF EJS Templates
branching: merge default into stable for 6.8rc0
branching: merge default into stable for 6.8rc0

File last commit:

r51872:4c5f6e95 default
r52541:6454c117 merge 6.8rc0 stable
Show More
index.rs
90 lines | 2.3 KiB | application/rls-services+xml | RustLexer
Georges Racinet
rust-nodemap: pure Rust example...
r44870 // 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::*;
Simon Sapin
rust: Switch to the memmap2-rs crate...
r48767 use memmap2::*;
Georges Racinet
rust-nodemap: pure Rust example...
r44870 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] {
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 [self.p1, self.p2]
Georges Racinet
rust-nodemap: pure Rust example...
r44870 }
}
impl RevlogIndex for Index {
fn len(&self) -> usize {
self.data.len()
}
fn node(&self, rev: Revision) -> Option<&Node> {
if rev == NULL_REVISION {
return None;
}
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 Some(&self.data[rev.0 as usize].node)
Georges Racinet
rust-nodemap: pure Rust example...
r44870 }
}
impl Graph for &Index {
fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> {
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 let [p1, p2] = self.data[rev.0 as usize].parents();
Georges Racinet
rust-nodemap: pure Rust example...
r44870 let len = (*self).len();
if p1 < NULL_REVISION
|| p2 < NULL_REVISION
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 || p1.0 as usize >= len
|| p2.0 as usize >= len
Georges Racinet
rust-nodemap: pure Rust example...
r44870 {
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)),
}
}
}