tempest-kv 0.0.2

Key-Value storage layer for TempestDB
Documentation
use bytes::{Bytes, BytesMut};
use tempest_io::{Io, IoBuf};
use tempest_rt::read_exact;

use crate::{
    base::{Comparer, InternalKey, KeyKind},
    sst::{SstHandle, SstReadError, block::BlockReader},
};

impl<I: Io, C: Comparer> SstHandle<I, C> {
    pub(crate) async fn get(
        &self,
        search_key: &InternalKey<C>,
    ) -> Result<Option<(KeyKind, Bytes)>, SstReadError> {
        let (prefix, _) = search_key.split_up();
        if !self.bloom_filter.maybe_contains(prefix) {
            return Ok(None);
        }

        let Some((_, block_offset, block_size)) = self.block_index.get_block_for(search_key) else {
            return Ok(None);
        };

        let block_size = block_size as usize;
        let block_buf = BytesMut::with_capacity(block_size);
        let (result, s) =
            read_exact::<_, I>(self.fd, block_buf.slice(..block_size), block_offset).await;
        result?;
        let block_raw = s.into_inner().freeze();
        // TODO: validate checksum
        assert_eq!(block_raw.len(), block_size);

        // TODO: for performance, we should cache the blocks on the SstHandle so that they can be
        // reused like the bloom filter and block index without reading from I/O again
        let block_reader = BlockReader::<C>::new(block_raw);

        Ok(block_reader.get(&search_key.slice_key()))
    }
}