segcache 0.2.0

Segment-structured cache storage engine with eager TTL expiration
Documentation
// Copyright 2021 Twitter, Inc.
// Copyright 2023 Pelikan Cache contributors
// Licensed under the MIT and Apache-2.0 licenses

//! Items are the base unit of data stored within the cache.

mod reserved;

#[cfg(any(feature = "magic", feature = "debug"))]
pub(crate) use keyvalue::ITEM_MAGIC_SIZE;

use crate::SegcacheError;
use keyvalue::{RawItem, Value};

pub(crate) use reserved::ReservedItem;

/// Items are the base unit of data stored within the cache.
pub struct Item {
    cas: u32,
    raw: RawItem,
}

impl Item {
    /// Creates a new `Item` from its parts
    pub(crate) fn new(raw: RawItem, cas: u32) -> Self {
        Item { cas, raw }
    }

    /// If the `magic` or `debug` features are enabled, this allows for checking
    /// that the magic bytes at the start of an item match the expected value.
    ///
    /// # Panics
    ///
    /// Panics if the magic bytes are incorrect, indicating that the data has
    /// become corrupted or the item was loaded from the wrong offset.
    pub(crate) fn check_magic(&self) {
        self.raw.check_magic()
    }

    /// Borrow the item key
    pub fn key(&self) -> &[u8] {
        self.raw.key()
    }

    /// Borrow the item value
    pub fn value(&self) -> Value<'_> {
        self.raw.value()
    }

    /// CAS value for the item
    pub fn cas(&self) -> u32 {
        self.cas
    }

    /// Borrow the optional data
    pub fn optional(&self) -> Option<&[u8]> {
        self.raw.optional()
    }

    /// Perform a wrapping addition on the value. Returns an error if the item
    /// is not a numeric type.
    pub fn wrapping_add(&mut self, rhs: u64) -> Result<(), SegcacheError> {
        self.raw
            .wrapping_add(rhs)
            .map_err(|_| SegcacheError::NotNumeric)
    }

    /// Perform a saturating subtraction on the value. Returns an error if the
    /// item is not a numeric type.
    pub fn saturating_sub(&mut self, rhs: u64) -> Result<(), SegcacheError> {
        self.raw
            .saturating_sub(rhs)
            .map_err(|_| SegcacheError::NotNumeric)
    }
}

impl std::fmt::Debug for Item {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        f.debug_struct("Item")
            .field("cas", &self.cas())
            .field("raw", &self.raw)
            .finish()
    }
}