use memmap::MmapMut;
pub trait StableMemoryBackend {
fn stable_size(&mut self) -> u64;
fn stable_grow(&mut self, new_pages: u64) -> i64;
fn stable_read(&mut self, offset: u64, buf: &mut [u8]);
fn stable_write(&mut self, offset: u64, buf: &[u8]);
}
pub struct FileSystemStableMemory {
_file: MmapMut,
}
impl StableMemoryBackend for FileSystemStableMemory {
fn stable_size(&mut self) -> u64 {
todo!()
}
fn stable_grow(&mut self, _new_pages: u64) -> i64 {
todo!()
}
fn stable_read(&mut self, _offset: u64, _buf: &mut [u8]) {
todo!()
}
fn stable_write(&mut self, _offset: u64, _buf: &[u8]) {
todo!()
}
}
pub struct HeapStableMemory {
pages: Vec<[u8; 1 << 16]>,
max_pages: u64,
}
impl Default for HeapStableMemory {
fn default() -> Self {
Self {
pages: Vec::new(),
max_pages: 128 << 20 >> 16,
}
}
}
impl HeapStableMemory {
pub fn new(max_pages: u64) -> Self {
Self {
pages: Vec::new(),
max_pages,
}
}
}
impl StableMemoryBackend for HeapStableMemory {
fn stable_size(&mut self) -> u64 {
self.pages.len() as u64
}
fn stable_grow(&mut self, new_pages: u64) -> i64 {
let size = self.pages.len() as u64;
if new_pages + size > self.max_pages {
-1
} else {
for _ in 0..new_pages {
self.pages.push([0; 1 << 16]);
}
size as i64
}
}
fn stable_read(&mut self, offset: u64, buf: &mut [u8]) {
for i in 0..buf.len() {
let offset = offset + i as u64;
let page = offset >> 16;
let byte = offset - (page << 16);
buf[i] = self.pages[page as usize][byte as usize];
}
}
fn stable_write(&mut self, offset: u64, buf: &[u8]) {
for i in 0..buf.len() {
let offset = offset + i as u64;
let page = offset >> 16;
let byte = offset - (page << 16);
self.pages[page as usize][byte as usize] = buf[i];
}
}
}