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 {
|
pub trait DataPager {
|
||||||
fn get_page(&mut self, offset: usize) -> Result<&mut DataPage, String>;
|
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)]
|
#[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 {
|
impl DataPage {
|
||||||
pub(crate) fn load(offset: usize, data: Vec<u8>) -> Self {
|
pub(crate) fn load(offset: usize, data: Vec<u8>) -> Self {
|
||||||
DataPage {
|
DataPage {
|
||||||
|
@ -108,6 +118,13 @@ impl Write for WritableDataPage<'_> {
|
||||||
return Ok(0);
|
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);
|
self.page.data[pos..pos + len].copy_from_slice(&buf);
|
||||||
|
|
||||||
Ok(len)
|
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<'_> {
|
impl WritableDataPage<'_> {
|
||||||
pub fn data(&self) -> &[u8] {
|
pub fn data(&self) -> &[u8] {
|
||||||
self.page.buffer()
|
self.page.buffer()
|
||||||
|
@ -126,6 +149,10 @@ impl WritableDataPage<'_> {
|
||||||
pub fn offset(&self) -> usize {
|
pub fn offset(&self) -> usize {
|
||||||
self.page.offset()
|
self.page.offset()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn finish(&self) -> DataPage {
|
||||||
|
self.page.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::hash_map::DefaultHasher,
|
collections::hash_map::DefaultHasher,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
io::{Read, Seek, SeekFrom},
|
io::{Read, Seek, SeekFrom, Write},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::data::{DataPage, DataPager};
|
use crate::data::{DataPage, DataPager};
|
||||||
|
@ -179,10 +179,12 @@ impl LocalStore {
|
||||||
|
|
||||||
node.children.push(entry);
|
node.children.push(entry);
|
||||||
|
|
||||||
|
let mut block = block.mutate();
|
||||||
block.seek(SeekFrom::Start(position)).unwrap();
|
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!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,9 @@ impl DataPager for DataAccessor {
|
||||||
Ok(self.cache.get_mut(&offset).unwrap())
|
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
|
self.dirty_pages
|
||||||
.push(DataPage::load(page.offset(), page.data().to_vec()));
|
.push(DataPage::load(page.offset(), page.buffer().to_vec()));
|
||||||
return Ok(1);
|
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