use memmap2::MmapMut;
use parking_lot::RwLockReadGuard;
use crate::{Database, Region};
#[must_use = "Reader holds locks and should be used for reading"]
pub struct Reader {
mmap: RwLockReadGuard<'static, MmapMut>,
start: usize,
len: usize,
_region: Region,
_db: Database,
}
impl Reader {
#[inline]
pub(crate) fn new(region: &Region) -> Self {
let db = region.db();
let region = region.clone();
let meta = region.meta();
let start = meta.start();
let len = meta.len();
drop(meta);
let mmap: RwLockReadGuard<'static, MmapMut> = unsafe { std::mem::transmute(db.mmap()) };
Self {
_db: db,
_region: region,
start,
len,
mmap,
}
}
#[inline(always)]
pub fn unchecked_read(&self, offset: usize, len: usize) -> &[u8] {
let start = self.start() + offset;
let end = start + len;
&self.mmap[start..end]
}
#[inline(always)]
pub fn read(&self, offset: usize, len: usize) -> &[u8] {
assert!(offset + len <= self.len());
self.unchecked_read(offset, len)
}
#[inline(always)]
fn start(&self) -> usize {
self.start
}
#[inline(always)]
pub fn len(&self) -> usize {
self.len
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline(always)]
pub fn read_all(&self) -> &[u8] {
self.read(0, self.len())
}
#[inline(always)]
pub fn prefixed(&self, offset: usize) -> &[u8] {
assert!(offset <= self.len());
let start = self.start() + offset;
&self.mmap[start..]
}
}