use crate::codec::KeyCodec;
use crate::keyfmt::{KeyFormat, ScratchBuf};
use crate::page::{InternalPage, LeafPage, PageError};
use std::fmt;
use thiserror::Error;
pub type NodeId = u64;
#[derive(Error, Debug)]
pub enum NodeViewError {
#[error("wrong node kind for this operation")]
WrongKind,
#[error(transparent)]
Page(#[from] PageError),
#[error("unknown key format id: {0}")]
UnknownKeyFormat(u8),
}
#[derive(Clone, Copy)]
pub enum NodeView {
Internal {
page: InternalPage,
page_id: Option<NodeId>,
},
Leaf {
page: LeafPage,
page_id: Option<NodeId>,
},
}
impl NodeView {
#[inline]
pub fn new_internal(format_id: KeyFormat) -> Self {
NodeView::Internal {
page: InternalPage::new(format_id),
page_id: None,
}
}
#[inline]
pub fn new_leaf(format_id: KeyFormat) -> Self {
NodeView::Leaf {
page: LeafPage::new(format_id),
page_id: None,
}
}
#[inline]
pub fn page_id(&self) -> Option<NodeId> {
match self {
NodeView::Internal { page_id, .. } | NodeView::Leaf { page_id, .. } => *page_id,
}
}
#[inline]
pub fn set_page_id(&mut self, id: NodeId) {
match self {
NodeView::Internal { page_id, .. } | NodeView::Leaf { page_id, .. } => {
*page_id = Some(id);
}
}
}
#[inline]
pub fn is_internal(&self) -> bool {
matches!(self, NodeView::Internal { .. })
}
#[inline]
pub fn is_leaf(&self) -> bool {
matches!(self, NodeView::Leaf { .. })
}
pub fn as_leaf(&self) -> Option<&LeafPage> {
match self {
NodeView::Leaf { page, .. } => Some(page),
_ => None,
}
}
pub fn as_leaf_mut(&mut self) -> Option<&mut LeafPage> {
match self {
NodeView::Leaf { page, .. } => Some(page),
_ => None,
}
}
pub fn as_internal(&self) -> Option<&InternalPage> {
match self {
NodeView::Internal { page, .. } => Some(page),
_ => None,
}
}
pub fn as_internal_mut(&mut self) -> Option<&mut InternalPage> {
match self {
NodeView::Internal { page, .. } => Some(page),
_ => None,
}
}
#[inline]
pub fn keys_len(&self) -> usize {
match self {
NodeView::Internal { page, .. } => page.key_count() as usize,
NodeView::Leaf { page, .. } => page.key_count() as usize,
}
}
pub fn value_bytes_at(&self, i: usize) -> Result<&[u8], NodeViewError> {
match self {
NodeView::Internal { .. } => Err(NodeViewError::WrongKind),
NodeView::Leaf { page, .. } => Ok(page.read_value_at(i)?),
}
}
#[inline]
pub fn child_ptr_at(&self, idx: usize) -> Result<u64, NodeViewError> {
match self {
NodeView::Internal { page, .. } => Ok(page.read_child_at(idx)?),
NodeView::Leaf { .. } => Err(NodeViewError::WrongKind),
}
}
#[inline]
pub fn value_at(&self, i: usize) -> Result<Vec<u8>, NodeViewError> {
match self {
NodeView::Internal { .. } => Err(NodeViewError::WrongKind),
NodeView::Leaf { page, .. } => Ok(page.read_value_at(i)?.to_vec()),
}
}
#[inline]
pub fn key_at(&self, i: usize) -> Result<Vec<u8>, NodeViewError> {
let mut scratch = ScratchBuf::new();
match self {
NodeView::Internal { page, .. } => Ok(page.get_key_at(i, &mut scratch)?.to_vec()),
NodeView::Leaf { page, .. } => Ok(page.get_key_at(i, &mut scratch)?.to_vec()),
}
}
#[inline]
pub fn key_bytes_at(&self, i: usize) -> Result<&[u8], NodeViewError> {
let mut scratch = ScratchBuf::new();
match self {
NodeView::Internal { page, .. } => Ok(page.get_key_at(i, &mut scratch)?),
NodeView::Leaf { page, .. } => Ok(page.get_key_at(i, &mut scratch)?),
}
}
#[inline]
pub fn first_key(&self) -> Result<Vec<u8>, NodeViewError> {
self.key_at(0)
}
pub fn lower_bound(&self, probe: &[u8]) -> Result<usize, usize> {
match self {
NodeView::Internal { page, .. } => {
let mut scratch = ScratchBuf::new();
page.lower_bound(probe, &mut scratch)
}
NodeView::Leaf { page, .. } => {
let mut scratch = ScratchBuf::new();
page.lower_bound(probe, &mut scratch)
}
}
}
pub fn lower_bound_cmp(
&self,
probe: &[u8],
cmp: fn(&[u8], &[u8]) -> core::cmp::Ordering,
) -> Result<usize, usize> {
match self {
NodeView::Internal { page, .. } => {
let mut scratch = ScratchBuf::new();
page.lower_bound_cmp(probe, &mut scratch, cmp)
}
NodeView::Leaf { page, .. } => {
let mut scratch = ScratchBuf::new();
page.lower_bound_cmp(probe, &mut scratch, cmp)
}
}
}
pub fn insert(
&mut self,
key: &[u8],
value: Option<&[u8]>,
child_ptr: Option<u64>,
) -> Result<(), NodeViewError> {
match self {
NodeView::Internal { page, .. } => match child_ptr {
Some(ptr) => Ok(page.insert_encoded(key, ptr)?),
None => Err(NodeViewError::WrongKind),
},
NodeView::Leaf { page, .. } => match value {
Some(val) => Ok(page.insert_encoded(key, val)?),
None => Err(NodeViewError::WrongKind),
},
}
}
#[inline]
pub fn insert_at(&mut self, idx: usize, key: &[u8], value: &[u8]) -> Result<(), NodeViewError> {
match self {
NodeView::Internal { .. } => Err(NodeViewError::WrongKind),
NodeView::Leaf { page, .. } => Ok(page.insert_at(idx, key, value)?),
}
}
#[inline]
pub fn insert_separator_at(
&mut self,
idx: usize,
key: &[u8],
child_ptr: u64,
) -> Result<(), NodeViewError> {
match self {
NodeView::Leaf { .. } => Err(NodeViewError::WrongKind),
NodeView::Internal { page, .. } => Ok(page.insert_separator(idx, key, child_ptr)?),
}
}
#[inline]
pub fn replace_at(&mut self, idx: usize, value: &[u8]) -> Result<(), NodeViewError> {
match self {
NodeView::Internal { .. } => Err(NodeViewError::WrongKind),
NodeView::Leaf { page, .. } => Ok(page.overwrite_value_at(idx, value)?),
}
}
#[inline]
pub fn delete_at(&mut self, idx: usize) -> Result<(), NodeViewError> {
match self {
NodeView::Internal { page, .. } => Ok(page.delete_separator(idx)?),
NodeView::Leaf { page, .. } => Ok(page.delete_at(idx)?),
}
}
#[inline]
pub fn entry_count(&self) -> usize {
match self {
NodeView::Internal { page, .. } => page.key_count() as usize,
NodeView::Leaf { page, .. } => page.key_count() as usize,
}
}
#[inline]
pub fn used_bytes(&self) -> usize {
match self {
NodeView::Internal { page, .. } => page.used_bytes(),
NodeView::Leaf { page, .. } => page.used_bytes(),
}
}
#[inline]
pub fn can_merge_physically(&self, other: &NodeView) -> bool {
let buffer_cap = match self {
NodeView::Internal { .. } => crate::page::internal::BUFFER_SIZE,
NodeView::Leaf { .. } => crate::page::leaf::BUFFER_SIZE,
};
self.used_bytes() + other.used_bytes() <= buffer_cap
}
pub fn split_off(&mut self, idx: usize) -> Result<NodeView, NodeViewError> {
match self {
NodeView::Internal { page, .. } => {
let keyfmt_id = KeyFormat::from_id(page.keyfmt_id())
.ok_or(NodeViewError::UnknownKeyFormat(page.keyfmt_id()))?;
let mut new_page = InternalPage::new(keyfmt_id);
page.split_off_into(idx, &mut new_page)?;
Ok(NodeView::Internal {
page: new_page,
page_id: None,
})
}
NodeView::Leaf { page, .. } => {
let keyfmt_id = KeyFormat::from_id(page.keyfmt_id())
.ok_or(NodeViewError::UnknownKeyFormat(page.keyfmt_id()))?;
let mut new_page = LeafPage::new(keyfmt_id);
page.split_off_into(idx, &mut new_page)?;
Ok(NodeView::Leaf {
page: new_page,
page_id: None,
})
}
}
}
pub fn replace_child_at(&mut self, idx: usize, child_ptr: u64) -> Result<(), NodeViewError> {
match self {
NodeView::Internal { page, .. } => Ok(page.replace_child_at(idx, child_ptr)?),
NodeView::Leaf { .. } => Err(NodeViewError::WrongKind),
}
}
pub fn pop_key(&mut self) -> Result<Option<Vec<u8>>, NodeViewError> {
match self {
NodeView::Internal { page, .. } => {
if page.key_count() == 0 {
return Ok(None);
}
let mut scratch = ScratchBuf::new();
Ok(Some(page.pop_last_key(&mut scratch)?))
}
NodeView::Leaf { .. } => Err(NodeViewError::WrongKind),
}
}
pub fn replace_key_at(&mut self, idx: usize, new_key: &[u8]) -> Result<(), NodeViewError> {
match self {
NodeView::Internal { page, .. } => Ok(page.replace_key_at(idx, new_key)?),
NodeView::Leaf { page, .. } => Ok(page.replace_key_at(idx, new_key)?),
}
}
pub fn write_leftmost_child(&mut self, ptr: u64) -> Result<(), NodeViewError> {
match self {
NodeView::Internal { page, .. } => Ok(page.write_leftmost_child(ptr)?),
NodeView::Leaf { .. } => Err(NodeViewError::WrongKind),
}
}
pub fn children_len(&self) -> Result<usize, NodeViewError> {
match self {
NodeView::Internal { page, .. } => Ok(page.key_count() as usize + 1),
NodeView::Leaf { .. } => Err(NodeViewError::WrongKind),
}
}
pub fn push_front(&mut self, key: &[u8], child_ptr: u64) -> Result<(), NodeViewError> {
match self {
NodeView::Internal { page, .. } => Ok(page.push_front(key, child_ptr)?),
NodeView::Leaf { .. } => Err(NodeViewError::WrongKind),
}
}
pub fn delete_key_at(&mut self, idx: usize) -> Result<Vec<u8>, NodeViewError> {
let mut scratch = ScratchBuf::new();
match self {
NodeView::Internal { page, .. } => Ok(page.delete_key_at(idx, &mut scratch)?),
NodeView::Leaf { page, .. } => Ok(page.delete_key_at(idx, &mut scratch)?),
}
}
pub fn insert_key_at(&mut self, idx: usize, key: &[u8]) -> Result<(), NodeViewError> {
match self {
NodeView::Internal { page, .. } => Ok(page.insert_key_at(idx, key)?),
NodeView::Leaf { page, .. } => Ok(page.insert_key_at(idx, key)?),
}
}
pub fn delete_child_at(&mut self, idx: usize) -> Result<(), NodeViewError> {
match self {
NodeView::Internal { page, .. } => Ok(page.delete_child_at(idx)?),
NodeView::Leaf { .. } => Err(NodeViewError::WrongKind),
}
}
pub fn merge_into(&mut self, other: &mut NodeView) -> Result<(), NodeViewError> {
match (self, other) {
(
NodeView::Internal {
page: self_page, ..
},
NodeView::Internal {
page: other_page, ..
},
) => {
let other_key_count = other_page.key_count();
let mut scratch = ScratchBuf::new();
for i in 0..other_key_count {
let key = other_page.get_key_at(i as usize, &mut scratch)?;
let child_ptr = other_page.read_child_at(i as usize + 1)?;
self_page.append(key, child_ptr)?;
}
Ok(())
}
(
NodeView::Leaf {
page: self_page, ..
},
NodeView::Leaf {
page: other_page, ..
},
) => {
let other_key_count = other_page.key_count();
let mut scratch = ScratchBuf::new();
for i in 0..other_key_count {
let (k, v) = other_page.get_kv_at(i as usize, &mut scratch)?;
self_page.append(k, v)?;
}
Ok(())
}
_ => Err(NodeViewError::WrongKind),
}
}
pub fn view_content<KC, K>(&self) -> Result<(), NodeViewError>
where
K: std::fmt::Debug,
KC: KeyCodec<K>,
{
match self {
NodeView::Internal { page, .. } => {
let key_count = page.key_count();
let mut scratch = ScratchBuf::new();
for i in 0..key_count as usize {
let key = page.get_key_at(i, &mut scratch)?;
let key = KC::decode_key(key);
let child_ptr = page.read_child_at(i + 1)?;
println!("Key {}: {:?}, Child Ptr: {}", i, key, child_ptr);
}
Ok(())
}
NodeView::Leaf { page, .. } => {
let key_count = page.key_count();
let mut scratch = ScratchBuf::new();
for i in 0..key_count as usize {
let (k, v) = page.get_kv_at(i, &mut scratch)?;
println!("Key {}: {:?}, Value: {:?}", i, k, v);
}
Ok(())
}
}
}
}
impl fmt::Debug for NodeView {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
NodeView::Leaf { page, .. } => page.fmt(f),
NodeView::Internal { page, .. } => page.fmt(f),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::keyfmt::raw::RawFormat;
#[test]
fn test_node_view_merge() -> Result<(), NodeViewError> {
let mut leaf1 = NodeView::new_leaf(KeyFormat::Raw(RawFormat));
leaf1.insert(b"key1", Some(b"value1"), None)?;
leaf1.insert(b"key2", Some(b"value2"), None)?;
let mut leaf2 = NodeView::new_leaf(KeyFormat::Raw(RawFormat));
leaf2.insert(b"key3", Some(b"value3"), None)?;
leaf2.insert(b"key4", Some(b"value4"), None)?;
leaf1.merge_into(&mut leaf2)?;
assert_eq!(leaf1.entry_count(), 4);
assert_eq!(leaf1.key_at(0)?, b"key1");
assert_eq!(leaf1.value_at(0)?, b"value1".to_vec());
assert_eq!(leaf1.key_at(1)?, b"key2");
assert_eq!(leaf1.value_at(1)?, b"value2".to_vec());
assert_eq!(leaf1.key_at(2)?, b"key3");
assert_eq!(leaf1.value_at(2)?, b"value3".to_vec());
assert_eq!(leaf1.key_at(3)?, b"key4");
assert_eq!(leaf1.value_at(3)?, b"value4".to_vec());
let mut internal1 = NodeView::new_internal(KeyFormat::Raw(RawFormat));
internal1.write_leftmost_child(0)?; internal1.insert(b"key2", None, Some(1))?;
internal1.insert(b"key4", None, Some(2))?;
let mut internal2 = NodeView::new_internal(KeyFormat::Raw(RawFormat));
internal2.write_leftmost_child(3)?; internal2.insert(b"key6", None, Some(3))?;
internal2.insert(b"key8", None, Some(4))?;
internal1.merge_into(&mut internal2)?;
assert_eq!(internal1.entry_count(), 4);
assert_eq!(internal1.key_at(0)?, b"key2");
assert_eq!(internal1.child_ptr_at(0)?, 0); assert_eq!(internal1.key_at(1)?, b"key4");
assert_eq!(internal1.child_ptr_at(1)?, 1);
assert_eq!(internal1.key_at(2)?, b"key6");
assert_eq!(internal1.child_ptr_at(2)?, 2);
assert_eq!(internal1.key_at(3)?, b"key8");
assert_eq!(internal1.child_ptr_at(3)?, 3);
assert_eq!(internal1.child_ptr_at(4)?, 4);
Ok(())
}
}