wedb_embed 0.1.1

Embedded database engine providing Redis-like APIs, built on fjall / 嵌入式数据库引擎,提供类似 Redis 的接口,底层基于 fjall 开发
Documentation
use crate::error::{Error, Result};
pub use crate::meta::{HEX_CHARS, decode_hex_u64, u64_to_hex_16 as encode_hex_u64};

/// 64 位无符号整数十六进制定长字节数(16 字符)
pub const HEX_LEN: usize = 16;

/// 错误常量定义(对标 Apache Kvrocks 错误字符串,避免运行时动态堆分配)
pub const ERR_MIN_NOT_INT: &str = "ERR the min isn't integer";
pub const ERR_MAX_NOT_INT: &str = "ERR the max isn't integer";
pub const ERR_MIN_GT_MAX: &str = "ERR min > max";
pub use crate::error::ERR_WRONG_TYPE;

/// 64 位有序整型集合范围查询规则(对标 Apache Kvrocks SortedintRangeSpec)
#[derive(Debug, Clone, PartialEq, Eq, bitcode::Encode, bitcode::Decode)]
pub struct SortedintRangeSpec {
    pub min: u64,
    pub max: u64,
    pub minex: bool,
    pub maxex: bool,
    pub offset: usize,
    pub count: Option<usize>,
    pub reversed: bool,
}

impl Default for SortedintRangeSpec {
    #[inline]
    fn default() -> Self {
        Self {
            min: u64::MIN,
            max: u64::MAX,
            minex: false,
            maxex: false,
            offset: 0,
            count: None,
            reversed: false,
        }
    }
}

impl SortedintRangeSpec {
    /// 创建全区间范围规则 [0, u64::MAX]
    #[inline]
    pub const fn all() -> Self {
        Self {
            min: u64::MIN,
            max: u64::MAX,
            minex: false,
            maxex: false,
            offset: 0,
            count: None,
            reversed: false,
        }
    }

    /// 设置分页偏移量
    #[inline]
    pub const fn with_offset(mut self, offset: usize) -> Self {
        self.offset = offset;
        self
    }

    /// 设置最大返回数量
    #[inline]
    pub const fn with_count(mut self, count: usize) -> Self {
        self.count = Some(count);
        self
    }

    /// 设置是否逆序
    #[inline]
    pub const fn with_reversed(mut self, reversed: bool) -> Self {
        self.reversed = reversed;
        self
    }

    /// 设置下界及开闭区间
    #[inline]
    pub const fn with_min(mut self, min: u64, minex: bool) -> Self {
        self.min = min;
        self.minex = minex;
        self
    }

    /// 设置上界及开闭区间
    #[inline]
    pub const fn with_max(mut self, max: u64, maxex: bool) -> Self {
        self.max = max;
        self.maxex = maxex;
        self
    }

    /// 检查范围区间是否为空(如 min > max,或 min == max 且存在开区间)
    #[inline]
    pub const fn is_empty_range(&self) -> bool {
        if self.min > self.max {
            return true;
        }
        if self.min == self.max && (self.minex || self.maxex) {
            return true;
        }
        if self.minex && self.min == u64::MAX {
            return true;
        }
        if self.maxex && self.max == 0 {
            return true;
        }
        false
    }

    /// 判断指定值是否落在该范围区间内
    #[inline]
    pub const fn contains(&self, val: u64) -> bool {
        if self.minex {
            if val <= self.min {
                return false;
            }
        } else if val < self.min {
            return false;
        }

        if self.maxex {
            if val >= self.max {
                return false;
            }
        } else if val > self.max {
            return false;
        }

        true
    }
}

/// 解析单侧边界值(支持 '(' 开区间、'[' 闭区间、'+' 号前缀及无前缀数字)
#[inline]
fn parse_bound(s: &str, is_min: bool) -> Result<(u64, bool)> {
    let (num_str, ex) = if let Some(stripped) = s.strip_prefix('(') {
        (stripped, true)
    } else if let Some(stripped) = s.strip_prefix('[') {
        (stripped, false)
    } else {
        (s, false)
    };
    let num_str = num_str.strip_prefix('+').unwrap_or(num_str);
    let val = num_str.parse::<u64>().map_err(|_| {
        if is_min {
            Error::redis(ERR_MIN_NOT_INT)
        } else {
            Error::redis(ERR_MAX_NOT_INT)
        }
    })?;
    Ok((val, ex))
}

/// 解析 64 位无符号整型范围规则(对标 Apache Kvrocks Sortedint::ParseRangeSpec)
/// 支持 -inf, +inf, (val, [val, val
pub fn parse_range_spec(min_str: &str, max_str: &str) -> Result<SortedintRangeSpec> {
    let min_str = min_str.trim();
    let max_str = max_str.trim();

    if min_str == "+inf" || max_str == "-inf" {
        return Err(Error::redis(ERR_MIN_GT_MAX));
    }

    let (min, minex) = if min_str == "-inf" {
        (u64::MIN, false)
    } else {
        parse_bound(min_str, true)?
    };

    let (max, maxex) = if max_str == "+inf" {
        (u64::MAX, false)
    } else {
        parse_bound(max_str, false)?
    };

    Ok(SortedintRangeSpec {
        min,
        max,
        minex,
        maxex,
        offset: 0,
        count: None,
        reversed: false,
    })
}

/// 64 位无符号整数编码为 8 字节大端序原生二进制数组
#[inline(always)]
pub const fn encode_be_u64(val: u64) -> [u8; 8] {
    val.to_be_bytes()
}

/// 8 字节大端序原生二进制解码为 64 位无符号整数
#[inline(always)]
pub const fn decode_be_u64(bytes: &[u8]) -> Option<u64> {
    if bytes.len() < 8 {
        return None;
    }
    let buf = [
        bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
    ];
    Some(u64::from_be_bytes(buf))
}