wedb_embed 0.1.1

Embedded database engine providing Redis-like APIs, built on fjall / 嵌入式数据库引擎,提供类似 Redis 的接口,底层基于 fjall 开发
Documentation
use std::borrow::Borrow;
use std::ops::Deref;

/// 栈上定长 128 字节快速键类型(对齐常见 Redis 键长度,零堆内存分配)
#[derive(Clone, Debug)]
pub enum SmallKey {
    Inline { buf: [u8; 128], len: usize },
    Heap(Vec<u8>),
}

impl Default for SmallKey {
    #[inline(always)]
    fn default() -> Self {
        Self::Inline {
            buf: [0u8; 128],
            len: 0,
        }
    }
}

impl SmallKey {
    #[inline(always)]
    pub fn new() -> Self {
        Self::default()
    }

    #[inline]
    pub fn push(&mut self, b: u8) {
        match self {
            Self::Inline { buf, len } => {
                if *len < 128 {
                    buf[*len] = b;
                    *len += 1;
                } else {
                    let mut v = Vec::with_capacity(129);
                    v.extend_from_slice(buf);
                    v.push(b);
                    *self = Self::Heap(v);
                }
            }
            Self::Heap(v) => v.push(b),
        }
    }

    #[inline]
    pub fn extend_from_slice(&mut self, s: &[u8]) {
        match self {
            Self::Inline { buf, len } => {
                if *len + s.len() <= 128 {
                    buf[*len..*len + s.len()].copy_from_slice(s);
                    *len += s.len();
                } else {
                    let mut v = Vec::with_capacity(*len + s.len() + 16);
                    v.extend_from_slice(&buf[..*len]);
                    v.extend_from_slice(s);
                    *self = Self::Heap(v);
                }
            }
            Self::Heap(v) => v.extend_from_slice(s),
        }
    }

    #[inline(always)]
    pub fn as_bytes(&self) -> &[u8] {
        match self {
            Self::Inline { buf, len } => &buf[..*len],
            Self::Heap(v) => v.as_slice(),
        }
    }

    #[inline(always)]
    pub fn to_vec(&self) -> Vec<u8> {
        self.as_bytes().to_vec()
    }
}

impl Deref for SmallKey {
    type Target = [u8];
    #[inline(always)]
    fn deref(&self) -> &[u8] {
        self.as_bytes()
    }
}

impl AsRef<[u8]> for SmallKey {
    #[inline(always)]
    fn as_ref(&self) -> &[u8] {
        self.as_bytes()
    }
}

impl Borrow<[u8]> for SmallKey {
    #[inline(always)]
    fn borrow(&self) -> &[u8] {
        self.as_bytes()
    }
}

impl PartialEq for SmallKey {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.as_bytes() == other.as_bytes()
    }
}

impl Eq for SmallKey {}

impl From<&SmallKey> for fjall::Slice {
    #[inline(always)]
    fn from(k: &SmallKey) -> Self {
        fjall::Slice::from(k.as_bytes())
    }
}

impl From<SmallKey> for fjall::Slice {
    #[inline(always)]
    fn from(k: SmallKey) -> Self {
        match k {
            SmallKey::Inline { buf, len } => fjall::Slice::from(&buf[..len]),
            SmallKey::Heap(v) => fjall::Slice::from(v),
        }
    }
}