use super::*;
use crate::mem::phys_mem::{page_cache::PageCache, PhysicalMemoryView};
#[derive(Clone)]
pub struct CachedView<'a, T, Q>
where
T: MemoryView,
Q: CacheValidator,
{
mem: PhysicalMemoryView<CachedPhysicalMemory<'a, PhysicalMemoryOnView<T>, Q>>,
}
impl<'a, T, Q> MemoryView for CachedView<'a, T, Q>
where
T: MemoryView,
Q: CacheValidator,
{
#[inline]
fn read_raw_iter(&mut self, data: ReadRawMemOps) -> Result<()> {
self.mem.read_raw_iter(data)
}
#[inline]
fn write_raw_iter(&mut self, data: WriteRawMemOps) -> Result<()> {
self.mem.write_raw_iter(data)
}
#[inline]
fn metadata(&self) -> MemoryViewMetadata {
self.mem.metadata()
}
}
impl<'a, T: MemoryView> CachedView<'a, T, DefaultCacheValidator> {
#[inline]
pub fn builder(mem: T) -> CachedViewBuilder<T, DefaultCacheValidator> {
CachedViewBuilder::new(mem)
}
}
pub struct CachedViewBuilder<T, Q> {
mem: T,
validator: Q,
page_size: Option<usize>,
cache_size: usize,
}
impl<T: MemoryView> CachedViewBuilder<T, DefaultCacheValidator> {
pub fn new(mem: T) -> Self {
Self {
mem,
validator: DefaultCacheValidator::default(),
page_size: None,
cache_size: size::mb(2),
}
}
}
impl<T: MemoryView, Q: CacheValidator> CachedViewBuilder<T, Q> {
pub fn build<'a>(self) -> Result<CachedView<'a, T, Q>> {
let phys_mem = self.mem.into_phys_mem();
let cache = CachedPhysicalMemory::new(
phys_mem,
PageCache::with_page_size(
self.page_size.ok_or_else(|| {
Error(ErrorOrigin::Cache, ErrorKind::Uninitialized)
.log_error("page_size must be initialized")
})?,
self.cache_size,
PageType::all(),
self.validator,
),
);
Ok(CachedView {
mem: cache.into_mem_view(),
})
}
pub fn validator<QN: CacheValidator>(self, validator: QN) -> CachedViewBuilder<T, QN> {
CachedViewBuilder {
mem: self.mem,
validator,
page_size: self.page_size,
cache_size: self.cache_size,
}
}
pub fn page_size(mut self, page_size: usize) -> Self {
self.page_size = Some(page_size);
self
}
pub fn arch(mut self, arch: impl Into<ArchitectureObj>) -> Self {
self.page_size = Some(arch.into().page_size());
self
}
pub fn cache_size(mut self, cache_size: usize) -> Self {
self.cache_size = cache_size;
self
}
}