pub mod prefix;
pub mod raw;
use smallvec::SmallVec;
pub const SCRATCH_CAP: usize = 256;
pub type ScratchBuf = SmallVec<[u8; SCRATCH_CAP]>;
#[derive(Debug, thiserror::Error)]
#[allow(dead_code)]
pub enum KeyFmtError {
#[error("truncated")]
Truncated,
#[error("corrupt: {0}")]
Corrupt(&'static str),
}
pub trait KeyBlockFormat: Send + Sync + 'static {
fn format_id(&self) -> u8;
fn seek(&self, block: &[u8], needle: &[u8], scratch: &mut ScratchBuf) -> Result<usize, usize>;
fn seek_with_cmp(
&self,
block: &[u8],
needle: &[u8],
scratch: &mut ScratchBuf,
cmp: fn(&[u8], &[u8]) -> core::cmp::Ordering,
) -> Result<usize, usize>;
fn decode_at<'s>(&self, blk: &'s [u8], i: usize, _scratch: &mut ScratchBuf) -> &'s [u8];
fn entry_range(&self, block: &[u8], idx: usize) -> std::ops::Range<usize>;
fn count(&self, p: &[u8]) -> usize;
fn get_insert_delta(
&self,
block: &[u8],
idx: usize,
new_key: &[u8],
scratch: &mut ScratchBuf,
) -> isize;
fn get_delete_delta(&self, block: &[u8], idx: usize, scratch: &mut ScratchBuf) -> isize;
fn encode_all(&self, keys: &[&[u8]], out: &mut Vec<u8>);
fn insert_plan(
&self,
block: &[u8],
idx: usize,
new_key: &[u8],
scratch: &mut ScratchBuf,
) -> (std::ops::Range<usize>, Vec<u8>);
fn delete_plan(
&self,
block: &[u8],
idx: usize,
scratch: &mut ScratchBuf,
) -> (std::ops::Range<usize>, Vec<u8>);
fn replace_plan(
&self,
block: &[u8],
idx: usize,
new_key: &[u8],
scratch: &mut ScratchBuf,
) -> (std::ops::Range<usize>, Vec<u8>);
fn adjust_after_splice(
&self,
block_final: &mut [u8],
splice_at: usize,
delta: isize,
idx: usize,
);
fn split_into(&self, block: &[u8], idx: usize, left_out: &mut Vec<u8>, right_out: &mut Vec<u8>);
}
#[repr(u8)]
#[derive(Debug, Clone, Copy)]
pub enum KeyFormat {
Raw(raw::RawFormat) = 0,
}
impl KeyFormat {
pub fn as_dyn(&self) -> &dyn KeyBlockFormat {
match self {
KeyFormat::Raw(f) => f,
}
}
pub fn id(&self) -> u8 {
self.as_dyn().format_id()
}
pub fn from_id(id: u8) -> Option<Self> {
match id {
0 => Some(Self::Raw(raw::RawFormat)),
_ => None,
}
}
}
pub static RAW_FORMAT: raw::RawFormat = raw::RawFormat;
pub fn resolve_key_format(id: u8) -> Option<&'static dyn KeyBlockFormat> {
match id {
0 => Some(&RAW_FORMAT),
_ => None,
}
}
#[allow(dead_code)]
pub fn key_format_to_u8(fmt: &dyn KeyBlockFormat) -> u8 {
fmt.format_id()
}