reifydb_core/value/encoded/
key.rs1use std::{
5 collections::{
6 Bound,
7 Bound::{Excluded, Included, Unbounded},
8 },
9 ops::{Deref, RangeBounds},
10};
11
12use serde::{Deserialize, Serialize};
13
14use crate::util::{
15 CowVec,
16 encoding::{binary::decode_binary, keycode::KeySerializer},
17};
18
19#[derive(Debug, Clone, PartialOrd, Ord, Hash, PartialEq, Eq, Serialize, Deserialize)]
20pub struct EncodedKey(pub CowVec<u8>);
21
22impl Deref for EncodedKey {
23 type Target = CowVec<u8>;
24
25 fn deref(&self) -> &Self::Target {
26 &self.0
27 }
28}
29
30impl EncodedKey {
31 pub fn new(key: impl Into<Vec<u8>>) -> Self {
32 Self(CowVec::new(key.into()))
33 }
34
35 pub fn as_bytes(&self) -> &[u8] {
36 self.0.as_ref()
37 }
38
39 pub fn as_slice(&self) -> &[u8] {
40 self.0.as_ref()
41 }
42}
43
44pub trait IntoEncodedKey {
47 fn into_encoded_key(self) -> EncodedKey;
48}
49
50impl IntoEncodedKey for EncodedKey {
52 fn into_encoded_key(self) -> EncodedKey {
53 self
54 }
55}
56
57impl IntoEncodedKey for &str {
59 fn into_encoded_key(self) -> EncodedKey {
60 let mut serializer = KeySerializer::new();
61 serializer.extend_str(self);
62 serializer.to_encoded_key()
63 }
64}
65
66impl IntoEncodedKey for String {
67 fn into_encoded_key(self) -> EncodedKey {
68 let mut serializer = KeySerializer::new();
69 serializer.extend_str(&self);
70 serializer.to_encoded_key()
71 }
72}
73
74impl IntoEncodedKey for Vec<u8> {
76 fn into_encoded_key(self) -> EncodedKey {
77 let mut serializer = KeySerializer::new();
78 serializer.extend_bytes(&self);
79 serializer.to_encoded_key()
80 }
81}
82
83impl IntoEncodedKey for &[u8] {
84 fn into_encoded_key(self) -> EncodedKey {
85 let mut serializer = KeySerializer::new();
86 serializer.extend_bytes(self);
87 serializer.to_encoded_key()
88 }
89}
90
91impl IntoEncodedKey for u64 {
93 fn into_encoded_key(self) -> EncodedKey {
94 let mut serializer = KeySerializer::with_capacity(8);
95 serializer.extend_u64(self);
96 serializer.to_encoded_key()
97 }
98}
99
100impl IntoEncodedKey for i64 {
101 fn into_encoded_key(self) -> EncodedKey {
102 let mut serializer = KeySerializer::with_capacity(8);
103 serializer.extend_i64(self);
104 serializer.to_encoded_key()
105 }
106}
107
108impl IntoEncodedKey for u32 {
109 fn into_encoded_key(self) -> EncodedKey {
110 let mut serializer = KeySerializer::with_capacity(4);
111 serializer.extend_u32(self);
112 serializer.to_encoded_key()
113 }
114}
115
116impl IntoEncodedKey for i32 {
117 fn into_encoded_key(self) -> EncodedKey {
118 let mut serializer = KeySerializer::with_capacity(4);
119 serializer.extend_i32(self);
120 serializer.to_encoded_key()
121 }
122}
123
124impl IntoEncodedKey for u16 {
125 fn into_encoded_key(self) -> EncodedKey {
126 let mut serializer = KeySerializer::with_capacity(2);
127 serializer.extend_u16(self);
128 serializer.to_encoded_key()
129 }
130}
131
132impl IntoEncodedKey for i16 {
133 fn into_encoded_key(self) -> EncodedKey {
134 let mut serializer = KeySerializer::with_capacity(2);
135 serializer.extend_i16(self);
136 serializer.to_encoded_key()
137 }
138}
139
140impl IntoEncodedKey for u8 {
141 fn into_encoded_key(self) -> EncodedKey {
142 let mut serializer = KeySerializer::with_capacity(1);
143 serializer.extend_u8(self);
144 serializer.to_encoded_key()
145 }
146}
147
148impl IntoEncodedKey for i8 {
149 fn into_encoded_key(self) -> EncodedKey {
150 let mut serializer = KeySerializer::with_capacity(1);
151 serializer.extend_i8(self);
152 serializer.to_encoded_key()
153 }
154}
155
156#[derive(Clone, Debug)]
157pub struct EncodedKeyRange {
158 pub start: Bound<EncodedKey>,
159 pub end: Bound<EncodedKey>,
160}
161
162impl EncodedKeyRange {
163 pub fn new(start: Bound<EncodedKey>, end: Bound<EncodedKey>) -> Self {
164 Self {
165 start,
166 end,
167 }
168 }
169
170 pub fn prefix(prefix: &[u8]) -> Self {
178 let start = Bound::Included(EncodedKey::new(prefix));
179 let end = match prefix.iter().rposition(|&b| b != 0xff) {
180 Some(i) => Bound::Excluded(EncodedKey::new(
181 prefix.iter()
182 .take(i)
183 .copied()
184 .chain(std::iter::once(prefix[i] + 1))
185 .collect::<Vec<_>>(),
186 )),
187 None => Bound::Unbounded,
188 };
189 Self {
190 start,
191 end,
192 }
193 }
194
195 pub fn with_prefix(&self, prefix: EncodedKey) -> Self {
196 let start = match self.start_bound() {
197 Included(key) => {
198 let mut prefixed = Vec::with_capacity(prefix.len() + key.len());
199 prefixed.extend_from_slice(prefix.as_ref());
200 prefixed.extend_from_slice(key.as_ref());
201 Included(EncodedKey::new(prefixed))
202 }
203 Excluded(key) => {
204 let mut prefixed = Vec::with_capacity(prefix.len() + key.len());
205 prefixed.extend_from_slice(prefix.as_ref());
206 prefixed.extend_from_slice(key.as_ref());
207 Excluded(EncodedKey::new(prefixed))
208 }
209 Unbounded => Included(prefix.clone()),
210 };
211
212 let end = match self.end_bound() {
213 Included(key) => {
214 let mut prefixed = Vec::with_capacity(prefix.len() + key.len());
215 prefixed.extend_from_slice(prefix.as_ref());
216 prefixed.extend_from_slice(key.as_ref());
217 Included(EncodedKey::new(prefixed))
218 }
219 Excluded(key) => {
220 let mut prefixed = Vec::with_capacity(prefix.len() + key.len());
221 prefixed.extend_from_slice(prefix.as_ref());
222 prefixed.extend_from_slice(key.as_ref());
223 Excluded(EncodedKey::new(prefixed))
224 }
225 Unbounded => match prefix.as_ref().iter().rposition(|&b| b != 0xff) {
226 Some(i) => {
227 let mut next_prefix = prefix.as_ref()[..=i].to_vec();
228 next_prefix[i] += 1;
229 Excluded(EncodedKey::new(next_prefix))
230 }
231 None => Unbounded,
232 },
233 };
234
235 EncodedKeyRange::new(start, end)
236 }
237
238 pub fn start_end(start: Option<EncodedKey>, end: Option<EncodedKey>) -> Self {
252 let start = match start {
253 Some(s) => Bound::Included(s),
254 None => Bound::Unbounded,
255 };
256
257 let end = match end {
258 Some(e) => Bound::Included(e),
259 None => Bound::Unbounded,
260 };
261
262 Self {
263 start,
264 end,
265 }
266 }
267
268 pub fn all() -> Self {
275 Self {
276 start: Bound::Unbounded,
277 end: Bound::Unbounded,
278 }
279 }
280
281 pub fn parse(str: &str) -> Self {
298 let (mut start, mut end) = (Bound::<EncodedKey>::Unbounded, Bound::<EncodedKey>::Unbounded);
299
300 if let Some(dot_pos) = str.find("..") {
302 let start_part = &str[..dot_pos];
303 let end_part = &str[dot_pos + 2..];
304
305 if !start_part.is_empty() {
307 start = Bound::Included(EncodedKey(decode_binary(start_part)));
308 }
309
310 if let Some(end_str) = end_part.strip_prefix('=') {
312 if !end_str.is_empty() {
314 end = Bound::Included(EncodedKey(decode_binary(end_str)));
315 }
316 } else {
317 if !end_part.is_empty() {
319 end = Bound::Excluded(EncodedKey(decode_binary(end_part)));
320 }
321 }
322
323 Self {
324 start,
325 end,
326 }
327 } else {
328 Self {
330 start: Bound::Included(EncodedKey::new([0xff])),
331 end: Bound::Excluded(EncodedKey::new([0xff])),
332 }
333 }
334 }
335}
336
337impl RangeBounds<EncodedKey> for EncodedKeyRange {
338 fn start_bound(&self) -> Bound<&EncodedKey> {
339 self.start.as_ref()
340 }
341
342 fn end_bound(&self) -> Bound<&EncodedKey> {
343 self.end.as_ref()
344 }
345}
346
347#[cfg(test)]
348mod tests {
349 use std::collections::Bound;
350
351 use super::EncodedKey;
352
353 macro_rules! as_key {
354 ($key:expr) => {{ EncodedKey::new(keycode::serialize(&$key)) }};
355 }
356
357 mod prefix {
358 use std::ops::Bound;
359
360 use crate::value::encoded::key::{
361 EncodedKeyRange,
362 tests::{excluded, included},
363 };
364
365 #[test]
366 fn test_simple() {
367 let range = EncodedKeyRange::prefix(&[0x12, 0x34]);
368 assert_eq!(range.start, included(&[0x12, 0x34]));
369 assert_eq!(range.end, excluded(&[0x12, 0x35]));
370 }
371
372 #[test]
373 fn test_with_trailing_ff() {
374 let range = EncodedKeyRange::prefix(&[0x12, 0xff]);
375 assert_eq!(range.start, included(&[0x12, 0xff]));
376 assert_eq!(range.end, excluded(&[0x13]));
377 }
378
379 #[test]
380 fn test_with_multiple_trailing_ff() {
381 let range = EncodedKeyRange::prefix(&[0x12, 0xff, 0xff]);
382 assert_eq!(range.start, included(&[0x12, 0xff, 0xff]));
383 assert_eq!(range.end, excluded(&[0x13]));
384 }
385
386 #[test]
387 fn test_all_ff() {
388 let range = EncodedKeyRange::prefix(&[0xff, 0xff]);
389 assert_eq!(range.start, included(&[0xff, 0xff]));
390 assert_eq!(range.end, Bound::Unbounded);
391 }
392
393 #[test]
394 fn test_empty() {
395 let range = EncodedKeyRange::prefix(&[]);
396 assert_eq!(range.start, included(&[]));
397 assert_eq!(range.end, Bound::Unbounded);
398 }
399
400 #[test]
401 fn test_mid_increment() {
402 let range = EncodedKeyRange::prefix(&[0x12, 0x00, 0xff]);
403 assert_eq!(range.start, included(&[0x12, 0x00, 0xff]));
404 assert_eq!(range.end, excluded(&[0x12, 0x01]));
405 }
406 }
407
408 mod start_end {
409 use std::ops::Bound;
410
411 use crate::{
412 EncodedKey,
413 util::encoding::keycode,
414 value::encoded::key::{EncodedKeyRange, tests::included},
415 };
416
417 #[test]
418 fn test_start_and_end() {
419 let range = EncodedKeyRange::start_end(Some(as_key!(1)), Some(as_key!(2)));
420 assert_eq!(range.start, included(&as_key!(1)));
421 assert_eq!(range.end, included(&as_key!(2)));
422 }
423
424 #[test]
425 fn test_start_only() {
426 let range = EncodedKeyRange::start_end(Some(as_key!(1)), None);
427 assert_eq!(range.start, included(&as_key!(1)));
428 assert_eq!(range.end, Bound::Unbounded);
429 }
430
431 #[test]
432 fn test_end_only() {
433 let range = EncodedKeyRange::start_end(None, Some(as_key!(2)));
434 assert_eq!(range.start, Bound::Unbounded);
435 assert_eq!(range.end, included(&as_key!(2)));
436 }
437
438 #[test]
439 fn test_unbounded_range() {
440 let range = EncodedKeyRange::start_end(None, None);
441 assert_eq!(range.start, Bound::Unbounded);
442 assert_eq!(range.end, Bound::Unbounded);
443 }
444
445 #[test]
446 fn test_full_byte_range() {
447 let range = EncodedKeyRange::start_end(Some(as_key!(0x00)), Some(as_key!(0xff)));
448 assert_eq!(range.start, included(&as_key!(0x00)));
449 assert_eq!(range.end, included(&as_key!(0xff)));
450 }
451
452 #[test]
453 fn test_identical_bounds() {
454 let range = EncodedKeyRange::start_end(Some(as_key!(0x42)), Some(as_key!(0x42)));
455 assert_eq!(range.start, included(&as_key!(0x42)));
456 assert_eq!(range.end, included(&as_key!(0x42)));
457 }
458 }
459
460 mod all {
461 use std::ops::Bound;
462
463 use crate::value::encoded::key::EncodedKeyRange;
464
465 #[test]
466 fn test_is_unbounded() {
467 let range = EncodedKeyRange::all();
468 assert_eq!(range.start, Bound::Unbounded);
469 assert_eq!(range.end, Bound::Unbounded);
470 }
471 }
472
473 mod parse {
474 use std::ops::Bound;
475
476 use crate::value::encoded::key::{
477 EncodedKey, EncodedKeyRange,
478 tests::{excluded, included},
479 };
480
481 #[test]
482 fn test_full_range() {
483 let r = EncodedKeyRange::parse("a..z");
484 assert_eq!(r.start, included(b"a"));
485 assert_eq!(r.end, excluded(b"z"));
486 }
487
488 #[test]
489 fn test_inclusive_end() {
490 let r = EncodedKeyRange::parse("a..=z");
491 assert_eq!(r.start, included(b"a"));
492 assert_eq!(r.end, included(b"z"));
493 }
494
495 #[test]
496 fn test_unbounded_start() {
497 let r = EncodedKeyRange::parse("..z");
498 assert_eq!(r.start, Bound::Unbounded);
499 assert_eq!(r.end, excluded(b"z"));
500 }
501
502 #[test]
503 fn test_unbounded_end() {
504 let r = EncodedKeyRange::parse("a..");
505 assert_eq!(r.start, included(b"a"));
506 assert_eq!(r.end, Bound::Unbounded);
507 }
508
509 #[test]
510 fn test_inclusive_only() {
511 let r = EncodedKeyRange::parse("..=z");
512 assert_eq!(r.start, Bound::Unbounded);
513 assert_eq!(r.end, included(b"z"));
514 }
515
516 #[test]
517 fn test_invalid_string_returns_degenerate_range() {
518 let r = EncodedKeyRange::parse("not a range");
519 let expected = EncodedKey::new([0xff]);
520 assert_eq!(r.start, Bound::Included(expected.clone()));
521 assert_eq!(r.end, Bound::Excluded(expected));
522 }
523
524 #[test]
525 fn test_empty_string_returns_degenerate_range() {
526 let r = EncodedKeyRange::parse("");
527 let expected = EncodedKey::new([0xff]);
528 assert_eq!(r.start, Bound::Included(expected.clone()));
529 assert_eq!(r.end, Bound::Excluded(expected));
530 }
531
532 #[test]
533 fn test_binary_encoded_values() {
534 let r = EncodedKeyRange::parse("0101..=0aff");
535 assert_eq!(r.start, included(b"0101"));
537 assert_eq!(r.end, included(b"0aff"));
539 }
540 }
541
542 fn included(key: &[u8]) -> Bound<EncodedKey> {
543 Bound::Included(EncodedKey::new(key))
544 }
545
546 fn excluded(key: &[u8]) -> Bound<EncodedKey> {
547 Bound::Excluded(EncodedKey::new(key))
548 }
549}