Add overflow error handling to WritableDataPage. Add IO tests.
This commit is contained in:
parent
53e5bd81af
commit
de6287c6c5
3 changed files with 58 additions and 6 deletions
|
@ -3,7 +3,7 @@ use std::io::{Read, Seek, SeekFrom, Write};
|
|||
pub trait DataPager {
|
||||
fn get_page(&mut self, offset: usize) -> Result<&mut DataPage, String>;
|
||||
|
||||
fn update_page(&mut self, page: WritableDataPage) -> Result<u64, ()>;
|
||||
fn update_page(&mut self, page: DataPage) -> Result<u64, ()>;
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash)]
|
||||
|
@ -67,6 +67,16 @@ impl Seek for DataPage {
|
|||
}
|
||||
}
|
||||
|
||||
impl Clone for DataPage {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
offset: self.offset,
|
||||
pos: self.pos,
|
||||
data: self.data.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DataPage {
|
||||
pub(crate) fn load(offset: usize, data: Vec<u8>) -> Self {
|
||||
DataPage {
|
||||
|
@ -108,6 +118,13 @@ impl Write for WritableDataPage<'_> {
|
|||
return Ok(0);
|
||||
}
|
||||
|
||||
if pos + buf.len() > self.page.len() {
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::OutOfMemory,
|
||||
"A write operation would overflow the block.",
|
||||
));
|
||||
}
|
||||
|
||||
self.page.data[pos..pos + len].copy_from_slice(&buf);
|
||||
|
||||
Ok(len)
|
||||
|
@ -118,6 +135,12 @@ impl Write for WritableDataPage<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Seek for WritableDataPage<'_> {
|
||||
fn seek(&mut self, pos: SeekFrom) -> std::io::Result<u64> {
|
||||
self.page.seek(pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl WritableDataPage<'_> {
|
||||
pub fn data(&self) -> &[u8] {
|
||||
self.page.buffer()
|
||||
|
@ -126,6 +149,10 @@ impl WritableDataPage<'_> {
|
|||
pub fn offset(&self) -> usize {
|
||||
self.page.offset()
|
||||
}
|
||||
|
||||
pub fn finish(&self) -> DataPage {
|
||||
self.page.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{
|
||||
collections::hash_map::DefaultHasher,
|
||||
hash::{Hash, Hasher},
|
||||
io::{Read, Seek, SeekFrom},
|
||||
io::{Read, Seek, SeekFrom, Write},
|
||||
};
|
||||
|
||||
use crate::data::{DataPage, DataPager};
|
||||
|
@ -179,10 +179,12 @@ impl LocalStore {
|
|||
|
||||
node.children.push(entry);
|
||||
|
||||
let mut block = block.mutate();
|
||||
block.seek(SeekFrom::Start(position)).unwrap();
|
||||
node.serialize(&self.meta);
|
||||
block.write(&node.serialize(&self.meta)).unwrap();
|
||||
let page = block.finish();
|
||||
|
||||
//todo serialize
|
||||
self.io.update_page(page).unwrap();
|
||||
|
||||
todo!()
|
||||
}
|
||||
|
|
|
@ -32,9 +32,9 @@ impl DataPager for DataAccessor {
|
|||
Ok(self.cache.get_mut(&offset).unwrap())
|
||||
}
|
||||
|
||||
fn update_page(&mut self, page: crate::data::WritableDataPage) -> Result<u64, ()> {
|
||||
fn update_page(&mut self, page: crate::data::DataPage) -> Result<u64, ()> {
|
||||
self.dirty_pages
|
||||
.push(DataPage::load(page.offset(), page.data().to_vec()));
|
||||
.push(DataPage::load(page.offset(), page.buffer().to_vec()));
|
||||
return Ok(1);
|
||||
}
|
||||
}
|
||||
|
@ -60,3 +60,26 @@ impl DataAccessor {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::io::{Seek, Write};
|
||||
|
||||
use crate::data::DataPage;
|
||||
|
||||
#[test]
|
||||
fn data_page_update() {
|
||||
let data = vec![2, 1, 3, 7, 0, 0, 0];
|
||||
let mut page = DataPage::load(127, data);
|
||||
page.seek(std::io::SeekFrom::Start(2)).unwrap();
|
||||
|
||||
let mut writable = page.mutate();
|
||||
|
||||
writable.write(&[4, 8, 6, 9, 5]).unwrap();
|
||||
let page_mod = writable.finish();
|
||||
|
||||
println!("{:?}", page.buffer());
|
||||
assert!(page.buffer().eq(&[2, 1, 4, 8, 6, 9, 5]));
|
||||
assert!(page_mod.buffer().eq(&[2, 1, 4, 8, 6, 9, 5]));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue