Skip to main content

wedb_embed/api/string/
opt.rs

1/// Domain operation (aligned with Apache Kvrocks StringPair).
2/// 键值对引用结构(对标 Apache Kvrocks StringPair)
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub struct StringPair<'a> {
5  pub key: &'a [u8],
6  pub value: &'a [u8],
7}
8
9impl<'a> StringPair<'a> {
10  #[inline]
11  pub const fn new(key: &'a [u8], value: &'a [u8]) -> Self {
12    Self { key, value }
13  }
14
15  #[inline]
16  pub const fn key(&self) -> &'a [u8] {
17    self.key
18  }
19
20  #[inline]
21  pub const fn value(&self) -> &'a [u8] {
22    self.value
23  }
24}
25
26/// Domain operation (aligned with Apache Kvrocks StringSetType).
27/// String SET 条件类型(对标 Apache Kvrocks StringSetType)
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
29pub enum StringSetType {
30  #[default]
31  None,
32  Nx,
33  Xx,
34  IfEq,
35  IfNe,
36  IfDeq,
37  IfDne,
38}
39
40/// Domain operation (aligned with Apache Kvrocks StringSet).
41/// String SET 参数结构体(对标 Apache Kvrocks StringSet)
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
43pub struct StringSet<'a> {
44  pub expire: u64,
45  pub set_type: StringSetType,
46  pub get: bool,
47  pub keep_ttl: bool,
48  pub cmp_value: Option<&'a [u8]>,
49}
50
51impl<'a> StringSet<'a> {
52  /// Operation definition.
53  /// 判断是否满足常规极速直写通道条件(无复合条件、无需旧值、无 TTL 继承、无摘要对比)
54  #[inline]
55  pub const fn is_fast_path(&self) -> bool {
56    matches!(self.set_type, StringSetType::None)
57      && !self.get
58      && !self.keep_ttl
59      && self.cmp_value.is_none()
60  }
61}
62
63/// Command options enumeration.
64/// String SET 选项枚举(统一 *Opt 后缀)
65#[derive(Debug, Clone, PartialEq, Eq)]
66pub enum Set<'a> {
67  Ex(u64),
68  Px(u64),
69  ExAt(u64),
70  PxAt(u64),
71  KeepTtl,
72  Nx,
73  Xx,
74  IfEq(&'a [u8]),
75  IfNe(&'a [u8]),
76  IfDeq(&'a [u8]),
77  IfDne(&'a [u8]),
78  Get,
79}
80
81impl<'a> Set<'a> {
82  /// Parses parameter or binary slice.
83  /// 从选项列表解析为完整的 StringSet
84  pub fn parse_options(options: impl IntoIterator<Item = Set<'a>>, now_ms: u64) -> StringSet<'a> {
85    let mut set_type = StringSetType::None;
86    let mut get = false;
87    let mut keep_ttl = false;
88    let mut expire = 0u64;
89    let mut cmp_value: Option<&'a [u8]> = None;
90
91    for opt in options {
92      match opt {
93        Set::Ex(sec) => {
94          expire = now_ms.saturating_add(sec.saturating_mul(1000));
95          keep_ttl = false;
96        }
97        Set::Px(ms) => {
98          expire = now_ms.saturating_add(ms);
99          keep_ttl = false;
100        }
101        Set::ExAt(sec) => {
102          expire = sec.saturating_mul(1000);
103          keep_ttl = false;
104        }
105        Set::PxAt(ms) => {
106          expire = ms;
107          keep_ttl = false;
108        }
109        Set::KeepTtl => {
110          keep_ttl = true;
111          expire = 0;
112        }
113        Set::Nx => {
114          set_type = StringSetType::Nx;
115          cmp_value = None;
116        }
117        Set::Xx => {
118          set_type = StringSetType::Xx;
119          cmp_value = None;
120        }
121        Set::IfEq(expected) => {
122          set_type = StringSetType::IfEq;
123          cmp_value = Some(expected);
124        }
125        Set::IfNe(expected) => {
126          set_type = StringSetType::IfNe;
127          cmp_value = Some(expected);
128        }
129        Set::IfDeq(expected) => {
130          set_type = StringSetType::IfDeq;
131          cmp_value = Some(expected);
132        }
133        Set::IfDne(expected) => {
134          set_type = StringSetType::IfDne;
135          cmp_value = Some(expected);
136        }
137        Set::Get => get = true,
138      }
139    }
140
141    StringSet {
142      expire,
143      set_type,
144      get,
145      keep_ttl,
146      cmp_value,
147    }
148  }
149}
150
151/// GETEX command options enumeration.
152/// GETEX 选项枚举(统一 *Opt 后缀)
153#[derive(Debug, Clone, Copy, PartialEq, Eq)]
154pub enum GetEx {
155  Ex(u64),
156  Px(u64),
157  ExAt(u64),
158  PxAt(u64),
159  Persist,
160}
161
162impl GetEx {
163  /// Returns or computes calculated value.
164  /// 计算新的绝对过期时间戳(毫秒)
165  #[inline]
166  pub const fn compute_expire(&self, now_ms: u64) -> u64 {
167    match *self {
168      Self::Persist => 0,
169      Self::Ex(sec) => now_ms.saturating_add(sec.saturating_mul(1000)),
170      Self::Px(ms) => now_ms.saturating_add(ms),
171      Self::ExAt(sec) => sec.saturating_mul(1000),
172      Self::PxAt(ms) => ms,
173    }
174  }
175}
176
177/// DELEX command options enumeration.
178/// DELEX 选项枚举(统一 *Opt 后缀)
179#[derive(Debug, Clone, PartialEq, Eq, Default)]
180pub enum DelEx<'a> {
181  #[default]
182  None,
183  IfEq(&'a [u8]),
184  IfNe(&'a [u8]),
185  IfDeq(&'a [u8]),
186  IfDne(&'a [u8]),
187}
188
189/// Domain operation (aligned with Apache Kvrocks StringMSet).
190/// String MSET 参数结构体(对标 Apache Kvrocks StringMSet)
191#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
192pub struct StringMSet {
193  pub expire: u64,
194  pub set_type: StringSetType,
195  pub keep_ttl: bool,
196}
197
198/// Domain operation (aligned with Apache Kvrocks StringLCSType).
199/// LCS 选项类型(对标 Apache Kvrocks StringLCSType)
200#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
201pub enum StringLCSType {
202  #[default]
203  None,
204  Len,
205  Idx,
206}
207
208/// Domain operation (aligned with Apache Kvrocks StringLCSOpt).
209/// LCS 参数结构体(对标 Apache Kvrocks StringLCSOpt)
210#[derive(Debug, Clone, Copy, PartialEq, Eq)]
211pub struct StringLCS {
212  pub lcs_type: StringLCSType,
213  pub min_match_len: i64,
214}
215
216impl Default for StringLCS {
217  fn default() -> Self {
218    Self {
219      lcs_type: StringLCSType::None,
220      min_match_len: 0,
221    }
222  }
223}
224
225/// LCS command options enumeration.
226/// LCS 选项枚举(统一 *Opt 后缀)
227#[derive(Debug, Clone, Copy, PartialEq, Eq)]
228pub enum Lcs {
229  Len,
230  Idx,
231  WithMatchLen,
232  MinMatchLen(i64),
233}
234
235impl Lcs {
236  pub fn parse_options(options: impl IntoIterator<Item = Lcs>) -> StringLCS {
237    let mut lcs_type = StringLCSType::None;
238    let mut min_match_len = 0;
239    for opt in options {
240      match opt {
241        Lcs::Len => lcs_type = StringLCSType::Len,
242        Lcs::Idx | Lcs::WithMatchLen => lcs_type = StringLCSType::Idx,
243        Lcs::MinMatchLen(len) => {
244          lcs_type = StringLCSType::Idx;
245          min_match_len = len;
246        }
247      }
248    }
249    StringLCS {
250      lcs_type,
251      min_match_len,
252    }
253  }
254}
255
256impl From<&[Lcs]> for StringLCS {
257  fn from(options: &[Lcs]) -> Self {
258    Lcs::parse_options(options.iter().copied())
259  }
260}
261
262/// Domain operation (aligned with Apache Kvrocks StringLCSRange).
263/// LCS 字符串子区间(对标 Apache Kvrocks StringLCSRange)
264#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
265pub struct StringLCSRange {
266  pub start: u32,
267  pub end: u32,
268}
269
270/// Domain operation (aligned with Apache Kvrocks StringLCSMatchedRange).
271/// LCS 匹配区间(对标 Apache Kvrocks StringLCSMatchedRange)
272#[derive(Debug, Clone, Copy, PartialEq, Eq)]
273pub struct StringLCSMatchedRange {
274  pub a: StringLCSRange,
275  pub b: StringLCSRange,
276  pub match_len: u32,
277}
278
279impl StringLCSMatchedRange {
280  #[inline]
281  pub const fn new(a_start: u32, a_end: u32, b_start: u32, b_end: u32, match_len: u32) -> Self {
282    Self {
283      a: StringLCSRange {
284        start: a_start,
285        end: a_end,
286      },
287      b: StringLCSRange {
288        start: b_start,
289        end: b_end,
290      },
291      match_len,
292    }
293  }
294
295  #[inline]
296  pub const fn a_start(&self) -> u32 {
297    self.a.start
298  }
299
300  #[inline]
301  pub const fn a_end(&self) -> u32 {
302    self.a.end
303  }
304
305  #[inline]
306  pub const fn b_start(&self) -> u32 {
307    self.b.start
308  }
309
310  #[inline]
311  pub const fn b_end(&self) -> u32 {
312    self.b.end
313  }
314}
315
316/// Domain operation (aligned with Apache Kvrocks StringLCSIdxResult).
317/// LCS 索引结果(对标 Apache Kvrocks StringLCSIdxResult)
318#[derive(Debug, Clone, PartialEq, Eq, Default)]
319pub struct StringLCSIdxResult {
320  pub matches: Vec<StringLCSMatchedRange>,
321  pub len: u32,
322}
323
324/// Domain operation (aligned with Apache Kvrocks StringLCSResult).
325/// LCS 综合结果(对标 Apache Kvrocks StringLCSResult)
326#[derive(Debug, Clone, PartialEq, Eq)]
327pub enum StringLCSResult {
328  Str(String),
329  Len(u32),
330  Idx(StringLCSIdxResult),
331}