use crate::{
Hash,
db::{EMPTY_RECORD, Record},
path::{Path, PathSegment, PathSegmentInner},
};
use bincode::{
Decode, Encode,
de::Decoder,
enc::Encoder,
error::{DecodeError, EncodeError},
impl_borrow_decode,
};
#[derive(Clone, Debug)]
pub struct Node {
pub id: Record,
pub inner: Option<NodeInner>,
pub(crate) hash_cache: Option<Hash>,
}
#[derive(Clone, Debug)]
pub enum NodeInner {
Leaf {
key: Path<Hash>,
value: Vec<u8>,
},
Internal {
prefix: PathSegment<PathSegmentInner>,
left: Box<Node>,
right: Box<Node>,
},
}
impl Node {
#[inline]
pub fn from_internal(
prefix: PathSegment<PathSegmentInner>,
left: Box<Node>,
right: Box<Node>,
) -> Self {
Self {
id: EMPTY_RECORD,
inner: Some(NodeInner::Internal {
prefix,
left,
right,
}),
hash_cache: None,
}
}
#[inline]
pub fn from_leaf(key: Path<Hash>, value: Vec<u8>) -> Self {
Self {
id: EMPTY_RECORD,
inner: Some(NodeInner::Leaf { key, value }),
hash_cache: None,
}
}
#[inline]
pub(crate) fn from_id(id: Record) -> Self {
Self {
id,
inner: None,
hash_cache: None,
}
}
#[inline]
pub fn mem_size(&self) -> usize {
let base_size = std::mem::size_of_val(self);
let inner_size = std::mem::size_of_val(&self.inner)
+ match &self.inner {
Some(NodeInner::Leaf { value, .. }) => value.capacity(),
Some(NodeInner::Internal { left, right, .. }) => left.mem_size() + right.mem_size(),
None => 0,
};
base_size
+ inner_size
+ std::mem::size_of_val(&self.hash_cache)
+ std::mem::size_of_val(&self.id)
- 1
}
}
impl Encode for NodeInner {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
match self {
NodeInner::Leaf { key, value } => {
Encode::encode(&0u8, encoder)?;
Encode::encode(&key.0, encoder)?;
Encode::encode(value, encoder)?;
}
NodeInner::Internal {
prefix,
left,
right,
} => {
Encode::encode(&1u8, encoder)?;
Encode::encode(&prefix.0, encoder)?;
Encode::encode(left, encoder)?;
Encode::encode(right, encoder)?;
}
}
Ok(())
}
}
impl<Context> Decode<Context> for NodeInner {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let tag: u8 = Decode::decode(decoder)?;
match tag {
0 => {
let key = Path(Decode::decode(decoder)?);
let value = Decode::decode(decoder)?;
Ok(NodeInner::Leaf { key, value })
}
1 => {
let seg: [u8; 33] = Decode::decode(decoder)?;
let prefix = PathSegment(seg);
let left: Node = Decode::decode(decoder)?;
let right: Node = Decode::decode(decoder)?;
Ok(NodeInner::Internal {
prefix,
left: Box::new(left),
right: Box::new(right),
})
}
_ => Err(DecodeError::Other("Invalid tag")),
}
}
}
impl Encode for &mut NodeInner {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
match self {
NodeInner::Leaf { key, value } => {
Encode::encode(&0u8, encoder)?;
Encode::encode(&key.0, encoder)?;
Encode::encode(value, encoder)?;
}
NodeInner::Internal {
prefix,
left,
right,
} => {
Encode::encode(&1u8, encoder)?;
Encode::encode(&prefix.0, encoder)?;
Encode::encode(left, encoder)?;
Encode::encode(right, encoder)?;
}
}
Ok(())
}
}
impl Encode for Node {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
if self.id == EMPTY_RECORD {
return Err(EncodeError::Other("Node id is zero"));
}
Encode::encode(&self.id, encoder)
}
}
impl<Context> Decode<Context> for Node {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
let id = Decode::decode(decoder)?;
Ok(Node::from_id(id))
}
}
impl_borrow_decode!(Node);
impl_borrow_decode!(NodeInner);