wedb_embed 0.1.2

Embedded database engine providing Redis-like APIs, built on fjall / 嵌入式数据库引擎,提供类似 Redis 的接口,底层基于 fjall 开发
Documentation
use crate::error::{Error, Result};
/// 64 位无符号整数原生大端序定长字节数(8 字节)
pub const BE_LEN: usize = 8;

/// 错误常量定义(对标 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))
}