-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deserialize branch #374
Deserialize branch #374
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -4,13 +4,13 @@ | |||||
use super::{Data, Encoded, Node}; | ||||||
use crate::{ | ||||||
merkle::{PartialPath, TRIE_HASH_LEN}, | ||||||
shale::ShaleStore, | ||||||
shale::{DiskAddress, Storable}, | ||||||
shale::{ShaleError, ShaleStore}, | ||||||
}; | ||||||
use bincode::{Error, Options}; | ||||||
use std::{ | ||||||
fmt::{Debug, Error as FmtError, Formatter}, | ||||||
io::{Cursor, Write}, | ||||||
io::{Cursor, Read, Write}, | ||||||
mem::size_of, | ||||||
ops::Deref, | ||||||
}; | ||||||
|
@@ -232,13 +232,98 @@ impl Storable for BranchNode { | |||||
} | ||||||
|
||||||
fn deserialize<T: crate::shale::CachedStore>( | ||||||
_addr: usize, | ||||||
_mem: &T, | ||||||
) -> Result<Self, crate::shale::ShaleError> | ||||||
where | ||||||
Self: Sized, | ||||||
{ | ||||||
todo!() | ||||||
mut addr: usize, | ||||||
mem: &T, | ||||||
) -> Result<Self, crate::shale::ShaleError> { | ||||||
const DATA_LEN_SIZE: usize = size_of::<DataLen>(); | ||||||
const BRANCH_HEADER_SIZE: u64 = | ||||||
BranchNode::MAX_CHILDREN as u64 * DiskAddress::MSIZE + DATA_LEN_SIZE as u64; | ||||||
|
||||||
let node_raw = | ||||||
mem.get_view(addr, BRANCH_HEADER_SIZE) | ||||||
.ok_or(ShaleError::InvalidCacheView { | ||||||
offset: addr, | ||||||
size: BRANCH_HEADER_SIZE, | ||||||
})?; | ||||||
|
||||||
addr += BRANCH_HEADER_SIZE as usize; | ||||||
|
||||||
let mut cursor = Cursor::new(node_raw.as_deref()); | ||||||
let mut children = [None; BranchNode::MAX_CHILDREN]; | ||||||
let mut buf = [0u8; DiskAddress::MSIZE as usize]; | ||||||
|
||||||
for child in &mut children { | ||||||
cursor.read_exact(&mut buf)?; | ||||||
*child = Some(usize::from_le_bytes(buf)) | ||||||
.filter(|addr| *addr != 0) | ||||||
.map(DiskAddress::from); | ||||||
} | ||||||
|
||||||
let raw_len = { | ||||||
let mut buf = [0; DATA_LEN_SIZE]; | ||||||
cursor.read_exact(&mut buf)?; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit (DRY): identical code could be refactored into a macro, maybe: macro_rules! read_data {
($cursor:expr, $type:ty) => {{
let mut buf = [0u8; std::mem::size_of::<$type>()];
$cursor.read_exact(&mut buf)?;
<$type>::from_le_bytes(buf)
}};
} Then, at the callsite, you can do all the manipulation: *child = Some(read_data!(cursor, usize))
.filter(|addr| *addr != 0)
.map(DiskAddress::from); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
Some(DataLen::from_le_bytes(buf)) | ||||||
.filter(|len| *len != DataLen::MAX) | ||||||
.map(|len| len as u64) | ||||||
}; | ||||||
|
||||||
let value = match raw_len { | ||||||
Some(len) => { | ||||||
let data = mem | ||||||
.get_view(addr, len) | ||||||
.ok_or(ShaleError::InvalidCacheView { | ||||||
offset: addr, | ||||||
size: len, | ||||||
})?; | ||||||
|
||||||
addr += len as usize; | ||||||
|
||||||
Some(Data(data.as_deref())) | ||||||
} | ||||||
None => None, | ||||||
}; | ||||||
|
||||||
let mut children_encoded: [Option<Vec<u8>>; BranchNode::MAX_CHILDREN] = Default::default(); | ||||||
|
||||||
for child in &mut children_encoded { | ||||||
const ENCODED_CHILD_LEN_SIZE: u64 = size_of::<EncodedChildLen>() as u64; | ||||||
|
||||||
let len = mem | ||||||
.get_view(addr, ENCODED_CHILD_LEN_SIZE) | ||||||
.ok_or(ShaleError::InvalidCacheView { | ||||||
offset: addr, | ||||||
size: ENCODED_CHILD_LEN_SIZE, | ||||||
})? | ||||||
.as_deref()[0] as u64; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: this will get a clippy exception due to unhandled panic once we add the clippy rules. Maybe:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤔 this could also be solved with a macro. We should be casting to an array and using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
|
||||||
addr += ENCODED_CHILD_LEN_SIZE as usize; | ||||||
|
||||||
if len == 0 { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: clearer if this and the prior statement were reversed. Perhaps increase addr before setting and testing len. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To go along with your comment about the macro, every time we get a view, we should automatically advance the address. I created #396 to address this |
||||||
continue; | ||||||
} | ||||||
|
||||||
let encoded = mem | ||||||
.get_view(addr, len) | ||||||
.ok_or(ShaleError::InvalidCacheView { | ||||||
offset: addr, | ||||||
size: len, | ||||||
})? | ||||||
.as_deref(); | ||||||
|
||||||
addr += len as usize; | ||||||
|
||||||
*child = Some(encoded); | ||||||
} | ||||||
|
||||||
let node = BranchNode { | ||||||
// TODO: add path | ||||||
// path: Vec::new().into(), | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Is this comment wrong? This assumes that all branch nodes have no data. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will go away shortly There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: this line can be removed with the TODO above? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will go away shortly |
||||||
children, | ||||||
value, | ||||||
children_encoded, | ||||||
}; | ||||||
|
||||||
Ok(node) | ||||||
} | ||||||
} | ||||||
|
||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This TODO seems relevant still, but it was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will go away shortly