simd-r-drive 0.8.0-alpha

SIMD-optimized append-only schema-less storage engine. Key-based binary storage in a single-file storage container.
Documentation
use crate::storage_engine::EntryMetadata;
use std::io::Result;

pub trait DataStoreReader {
    type EntryHandleType;

    /// Retrieves the most recent value associated with a given key.
    ///
    /// This method **efficiently looks up a key** using a fast in-memory index,
    /// and returns the latest corresponding value if found.
    ///
    /// # Parameters:
    /// - `key`: The **binary key** whose latest value is to be retrieved.
    ///
    /// # Returns:
    /// - `Ok(Some(EntryHandle))`: Handle to the entry if found.
    /// - `Ok(None)`: If the key does not exist or is deleted.
    /// - `Err(std::io::Error)`: On I/O failure.
    ///
    /// # Notes:
    /// - The returned `EntryHandle` provides zero-copy access to the stored data.
    fn read(&self, key: &[u8]) -> Result<Option<Self::EntryHandleType>>;

    /// Retrieves the last entry written to the file.
    ///
    /// # Returns:
    /// - `Ok(Some(EntryHandle))`: Handle to the last entry, if any.
    /// - `Ok(None)`: If the file is empty.
    /// - `Err(std::io::Error)`: On I/O failure.
    fn read_last_entry(&self) -> Result<Option<Self::EntryHandleType>>;

    /// Reads many keys in one shot.
    ///
    /// This is the **vectorized** counterpart to [`crate::DataStore::read`].  
    /// It takes a slice of raw-byte keys and returns a `Vec` whose *i-th* element
    /// is the result of looking up the *i-th* key.
    ///
    /// *   **Zero-copy** – each `Some(EntryHandle)` points directly into the
    ///     shared `Arc<Mmap>`; no payload is copied.
    /// *   **Constant-time per key** – the in-memory [`crate::storage_engine::KeyIndexer`] map is used
    ///     for each lookup, so the complexity is *O(n)* where *n* is
    ///     `keys.len()`.
    /// *   **Thread-safe** – a read lock on the index is taken once for the whole
    ///     batch, so concurrent writers are still blocked only for the same short
    ///     critical section that a single `read` would need.
    ///
    /// # Returns:
    /// - `Ok(results)`: `Vec<Option<EntryHandle>>` in key order.
    /// - `Err(std::io::Error)`: On I/O failure.
    fn batch_read(&self, keys: &[&[u8]]) -> Result<Vec<Option<Self::EntryHandleType>>>;

    /// Retrieves metadata for a given key.
    ///
    /// This method looks up a key in the storage and returns its associated metadata.
    ///
    /// # Parameters:
    /// - `key`: The **binary key** whose metadata is to be retrieved.
    ///
    /// # Returns:
    /// - `Ok(Some(metadata))`: Metadata if the key exists.
    /// - `Ok(None)`: If the key is absent.
    /// - `Err(std::io::Error)`: On I/O failure.
    fn read_metadata(&self, key: &[u8]) -> Result<Option<EntryMetadata>>;

    /// Counts **active** (non-deleted) key-value pairs in the storage.
    ///
    /// # Returns:
    /// - `Ok(active_count)`: Total active entries.
    /// - `Err(std::io::Error)`: On I/O failure.
    fn count(&self) -> Result<usize>;

    /// Returns the current file size on disk (including those of deleted entries).
    ///
    /// # Returns:
    /// - `Ok(bytes)`: File size in bytes.
    /// - `Err(std::io::Error)`: On I/O failure.
    fn get_storage_size(&self) -> Result<u64>;
}

#[async_trait::async_trait]
pub trait AsyncDataStoreReader {
    type EntryHandleType;

    /// Retrieves the most recent value associated with a given key.
    ///
    /// This method **efficiently looks up a key** using a fast in-memory index,
    /// and returns the latest corresponding value if found.
    ///
    /// # Parameters:
    /// - `key`: The **binary key** whose latest value is to be retrieved.
    ///
    /// # Returns:
    /// - `Ok(Some(EntryHandle))`: Handle to the entry if found.
    /// - `Ok(None)`: If the key does not exist or is deleted.
    /// - `Err(std::io::Error)`: On I/O failure.
    ///
    /// # Notes:
    /// - The returned `EntryHandle` provides zero-copy access to the stored data.
    async fn read(&self, key: &[u8]) -> Result<Option<Self::EntryHandleType>>;

    /// Retrieves the last entry written to the file.
    ///
    /// # Returns:
    /// - `Ok(Some(EntryHandle))`: Handle to the last entry, if any.
    /// - `Ok(None)`: If the file is empty.
    /// - `Err(std::io::Error)`: On I/O failure.
    async fn read_last_entry(&self) -> Result<Option<Self::EntryHandleType>>;

    /// Reads many keys in one shot.
    ///
    /// This is the **vectorized** counterpart to [`crate::DataStore::read`].  
    /// It takes a slice of raw-byte keys and returns a `Vec` whose *i-th* element
    /// is the result of looking up the *i-th* key.
    ///
    /// *   **Zero-copy** – each `Some(EntryHandle)` points directly into the
    ///     shared `Arc<Mmap>`; no payload is copied.
    /// *   **Constant-time per key** – the in-memory [`crate::storage_engine::KeyIndexer`] map is used
    ///     for each lookup, so the complexity is *O(n)* where *n* is
    ///     `keys.len()`.
    /// *   **Thread-safe** – a read lock on the index is taken once for the whole
    ///     batch, so concurrent writers are still blocked only for the same short
    ///     critical section that a single `read` would need.
    ///
    /// # Returns:
    /// - `Ok(results)`: `Vec<Option<EntryHandle>>` in key order.
    /// - `Err(std::io::Error)`: On I/O failure.
    async fn batch_read(&self, keys: &[&[u8]]) -> Result<Vec<Option<Self::EntryHandleType>>>;

    /// Retrieves metadata for a given key.
    ///
    /// This method looks up a key in the storage and returns its associated metadata.
    ///
    /// # Parameters:
    /// - `key`: The **binary key** whose metadata is to be retrieved.
    ///
    /// # Returns:
    /// - `Ok(Some(metadata))`: Metadata if the key exists.
    /// - `Ok(None)`: If the key is absent.
    /// - `Err(std::io::Error)`: On I/O failure.
    async fn read_metadata(&self, key: &[u8]) -> Result<Option<EntryMetadata>>;

    /// Counts **active** (non-deleted) key-value pairs in the storage.
    ///
    /// # Returns:
    /// - `Ok(active_count)`: Total active entries.
    /// - `Err(std::io::Error)`: On I/O failure.
    async fn count(&self) -> Result<usize>;

    /// Returns the current file size on disk (including those of deleted entries).
    ///
    /// # Returns:
    /// - `Ok(bytes)`: File size in bytes.
    /// - `Err(std::io::Error)`: On I/O failure.
    async fn get_storage_size(&self) -> Result<u64>;
}