use crate::comparator::SharedComparator;
use crate::table::block::{BlockType, Decoder, DecoderMeta, ParsedItem};
use crate::table::block_index::{BlockIndexIter, iter::OwnedIndexBlockIter};
use crate::table::index_block::{IndexBlockParsedItem, Iter as BorrowedIndexIter};
use crate::table::{IndexBlock, KeyedBlockHandle};
use crate::{SeqNo, Slice};
pub struct FullBlockIndex {
block: IndexBlock,
comparator: SharedComparator,
meta: DecoderMeta,
}
impl FullBlockIndex {
pub fn new(block: IndexBlock, comparator: SharedComparator) -> crate::Result<Self> {
if block.inner.header.block_type != BlockType::Index {
return Err(crate::Error::InvalidTag((
"BlockType",
block.inner.header.block_type.into(),
)));
}
let meta = Decoder::<KeyedBlockHandle, IndexBlockParsedItem>::try_new(&block.inner)?.meta();
Ok(Self {
block,
comparator,
meta,
})
}
pub fn inner(&self) -> &IndexBlock {
&self.block
}
pub fn point_read_reader(&self, needle: &[u8], seqno: SeqNo) -> Option<PointReadIter<'_>> {
let mut it = self
.block
.iter_with_meta(self.comparator.clone(), self.meta);
if it.seek(needle, seqno) {
Some(PointReadIter {
iter: it,
data: &self.block.inner.data,
})
} else {
None
}
}
pub fn forward_reader(&self, needle: &[u8], seqno: SeqNo) -> Option<Iter> {
let mut it = self.iter();
if it.seek_lower(needle, seqno) {
Some(it)
} else {
None
}
}
pub fn iter(&self) -> Iter {
Iter(OwnedIndexBlockIter::from_validated_block(
self.block.clone(),
self.comparator.clone(),
))
}
}
pub struct PointReadIter<'a> {
iter: BorrowedIndexIter<'a>,
data: &'a Slice,
}
impl Iterator for PointReadIter<'_> {
type Item = crate::Result<KeyedBlockHandle>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|item| Ok(item.materialize(self.data)))
}
}
pub struct Iter(OwnedIndexBlockIter);
impl BlockIndexIter for Iter {
fn seek_lower(&mut self, key: &[u8], seqno: SeqNo) -> bool {
self.0.seek_lower(key, seqno)
}
fn seek_upper(&mut self, key: &[u8], seqno: SeqNo) -> bool {
self.0.seek_upper(key, seqno)
}
}
impl Iterator for Iter {
type Item = crate::Result<KeyedBlockHandle>;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(Ok)
}
}
impl DoubleEndedIterator for Iter {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(Ok)
}
}