kvstructs/
value.rs

1use crate::raw_value_pointer::RawValuePointer;
2use crate::value_enc::EncodedValue;
3use crate::{
4    binary_uvarint, binary_uvarint_allocate, put_binary_uvariant_to_vec, EXPIRATION_OFFSET,
5    META_OFFSET, USER_META_OFFSET,
6};
7use alloc::borrow::Cow;
8use alloc::boxed::Box;
9use alloc::rc::Rc;
10use alloc::string::{String, ToString};
11use alloc::sync::Arc;
12use alloc::vec::Vec;
13use bytes::{Buf, BufMut, Bytes, BytesMut};
14use core::mem;
15use core::slice::from_raw_parts;
16
17/// Max size of a value information. 1 for meta, 1 for user meta, 8 for expires_at
18const MAX_VALUE_INFO_SIZE: usize = mem::size_of::<u8>() * 2 + mem::size_of::<u64>();
19
20/// Value represents the value info that can be associated with a key, but also the internal
21/// Meta field. The data in the Value is not mutable.
22///
23/// # Design for Value
24///
25/// **Note:**
26/// 1. `version` field will not be encoded, it is a helper field.
27/// 2. `expiration` field will be encoded as uvarient, which means after encoded, the size of
28/// this field is less or equal to 8 bytes.
29///
30/// ```text
31/// +----------+-----------------+--------------------+--------------------+--------------------+
32/// |   meta   |    user meta    |     expiration     |      version       |        data        |
33/// +----------+-----------------+--------------------+--------------------+--------------------+
34/// |  1 byte  |      1 byte     |      8 bytes       |      8 bytes       |       n bytes      |
35/// +----------+-----------------+--------------------+--------------------+--------------------+
36/// ```
37#[derive(Default, Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Hash)]
38#[repr(C)]
39pub struct Value {
40    pub(crate) meta: u8,
41    pub(crate) user_meta: u8,
42    pub(crate) expires_at: u64,
43    pub(crate) version: u64, // This field is not serialized. Only for internal usage.
44    pub(crate) value: Bytes,
45}
46
47impl From<Value> for Bytes {
48    fn from(v: Value) -> Self {
49        let mut b = BytesMut::with_capacity(MAX_VALUE_INFO_SIZE + v.value.len());
50        b.put_u8(v.meta);
51        b.put_u8(v.user_meta);
52        b.put_u64(v.expires_at);
53        b.extend(v.value);
54        b.freeze()
55    }
56}
57
58impl Value {
59    /// Returns an empty value
60    #[inline]
61    pub const fn new() -> Self {
62        Self {
63            meta: 0,
64            user_meta: 0,
65            expires_at: 0,
66            version: 0,
67            value: Bytes::new(),
68        }
69    }
70
71    /// Returns a value with the given meta, user meta, expires_at, version and data.
72    #[inline]
73    pub const fn with_all_fields(
74        meta: u8,
75        user_meta: u8,
76        expires_at: u64,
77        version: u64,
78        data: Bytes,
79    ) -> Self {
80        Self {
81            meta,
82            user_meta,
83            expires_at,
84            version,
85            value: data,
86        }
87    }
88
89    /// Decodes value from bytes
90    #[inline]
91    pub fn decode_bytes(src: Bytes) -> Self {
92        let meta = src[META_OFFSET];
93        let user_meta = src[USER_META_OFFSET];
94        let (expires_at, sz) = binary_uvarint(&src[EXPIRATION_OFFSET..]);
95        let value = src.slice(EXPIRATION_OFFSET + sz..);
96
97        Self {
98            meta,
99            user_meta,
100            expires_at,
101            version: 0,
102            value,
103        }
104    }
105
106    /// Set the meta for the value
107    #[inline]
108    pub const fn set_meta(mut self, meta: u8) -> Self {
109        self.meta = meta;
110        self
111    }
112
113    /// Set the user meta for the value
114    #[inline]
115    pub const fn set_user_meta(mut self, user_meta: u8) -> Self {
116        self.user_meta = user_meta;
117        self
118    }
119
120    /// Set the expires_at for the value
121    #[inline]
122    pub const fn set_expires_at(mut self, expires_at: u64) -> Self {
123        self.expires_at = expires_at;
124        self
125    }
126
127    /// Set the version for the value
128    #[inline]
129    pub const fn set_version(mut self, version: u64) -> Self {
130        self.version = version;
131        self
132    }
133
134    /// Set the data for the value
135    #[inline]
136    pub fn set_data(mut self, value: Bytes) -> Self {
137        self.value = value;
138        self
139    }
140
141    /// Returns the version for this value
142    #[inline]
143    pub const fn get_version(&self) -> u64 {
144        self.version
145    }
146
147    /// Returns the number of bytes contained in the value data.
148    #[inline]
149    pub fn len(&self) -> usize {
150        self.value.len()
151    }
152
153    /// Returns true if the value data has a length of 0.
154    #[inline]
155    pub fn is_empty(&self) -> bool {
156        self.value.is_empty()
157    }
158}
159
160impl ValueExt for Value {
161    #[inline]
162    fn as_value_ref(&self) -> ValueRef {
163        ValueRef {
164            meta: self.meta,
165            user_meta: self.user_meta,
166            expires_at: self.expires_at,
167            version: self.version,
168            val: self.parse_value(),
169        }
170    }
171
172    #[inline]
173    fn parse_value(&self) -> &[u8] {
174        self.value.as_ref()
175    }
176
177    #[inline]
178    fn parse_value_to_bytes(&self) -> Bytes {
179        self.value.clone()
180    }
181
182    #[inline]
183    fn get_meta(&self) -> u8 {
184        self.meta
185    }
186
187    #[inline]
188    fn get_user_meta(&self) -> u8 {
189        self.user_meta
190    }
191
192    #[inline]
193    fn get_expires_at(&self) -> u64 {
194        self.expires_at
195    }
196
197    impl_psfix_suites!(ValueExt::parse_value, u8, "u8");
198}
199
200fn size_variant(mut x: u64) -> usize {
201    let mut n = 0;
202    loop {
203        n += 1;
204        x >>= 7;
205        if x == 0 {
206            break;
207        }
208    }
209    n
210}
211
212macro_rules! impl_from_for_value {
213    ($($ty: ty), +$(,)?) => {
214        $(
215        impl From<$ty> for Value {
216            fn from(val: $ty) -> Self {
217                Self {
218                    meta: 0,
219                    user_meta: 0,
220                    expires_at: 0,
221                    value: Bytes::from(val),
222                    version: 0,
223                }
224            }
225        }
226        )*
227    };
228}
229
230impl_from_for_value! {
231    String,
232    &'static str,
233    &'static [u8],
234    Vec<u8>,
235    Box<[u8]>,
236    Bytes,
237    BytesMut,
238}
239
240/// Extensions for `Value`
241pub trait ValueExt {
242    /// Returns a [`ValueRef`]
243    ///
244    /// [`ValueRef`]: struct.ValueRef.html
245    #[inline]
246    fn as_value_ref(&self) -> ValueRef {
247        ValueRef {
248            meta: self.get_meta(),
249            user_meta: self.get_user_meta(),
250            expires_at: self.get_expires_at(),
251            version: 0,
252            val: self.parse_value(),
253        }
254    }
255
256    /// Returns the value data
257    fn parse_value(&self) -> &[u8];
258
259    /// Returns the value data (do shallow copy, except [`RawValuePointer`][`RawValuePointer`])
260    ///
261    /// [`RawValuePointer`]: struct.RawValuePointer.html
262    fn parse_value_to_bytes(&self) -> Bytes;
263
264    /// Get the meta of the value
265    fn get_meta(&self) -> u8;
266
267    /// Get the user meta
268    fn get_user_meta(&self) -> u8;
269
270    /// Returns the expiration time (unix timestamp) for this value
271    fn get_expires_at(&self) -> u64;
272
273    /// Returns the size of the Value when encoded
274    #[inline]
275    fn encoded_size(&self) -> u32 {
276        let sz = self.parse_value().len() + 2; // meta, user meta.
277        let enc = size_variant(self.get_expires_at());
278        (sz + enc) as u32
279    }
280
281    /// Encode to a mutable slice. This function will copy the value.
282    /// Use [`to_encoded`], if you want a shallow copy when encoded.
283    ///
284    /// # Panics
285    /// This function panics if the remaining capacity of slice is less than encoded size.
286    ///
287    /// [`to_encoded`]: #method.to_encoded
288    fn encode(&self, mut buf: &mut [u8]) {
289        buf.put_u8(self.get_meta());
290        buf.put_u8(self.get_user_meta());
291        buf.put_slice(binary_uvarint_allocate(self.get_expires_at()).as_slice());
292        buf.put_slice(self.parse_value());
293    }
294
295    /// Encode to a mutable buf. This function will copy the value.
296    /// Use [`to_encoded`], if you want a shallow copy when encoded.
297    ///
298    /// # Panics
299    /// This function panics if the remaining capacity of slice is less than encoded size.
300    ///
301    /// [`to_encoded`]: #method.to_encoded_to_buf
302    fn encode_to_buf(&self, mut buf: impl BufMut) {
303        buf.put_u8(self.get_meta());
304        buf.put_u8(self.get_user_meta());
305        buf.put_slice(binary_uvarint_allocate(self.get_expires_at()).as_slice());
306        buf.put_slice(self.parse_value());
307    }
308
309    /// Encode to [`EncodedValue`].
310    ///
311    /// This function may be optimized by the underlying type to avoid actual copies.
312    /// For example, [`Value`] implementation will do a shallow copy (ref-count increment)
313    ///
314    /// [`EncodedValue`]: struct.EncodedValue.html
315    /// [`Value`]: struct.Value.html
316    #[inline]
317    fn to_encoded(&self) -> EncodedValue {
318        let mut data = Vec::with_capacity(MAX_VALUE_INFO_SIZE);
319        data.push(self.get_meta());
320        data.push(self.get_user_meta());
321        put_binary_uvariant_to_vec(data.as_mut(), self.get_expires_at());
322
323        let expires_sz = data.len() - 2;
324        let meta = Bytes::from(data);
325        let val = self.parse_value_to_bytes();
326        let enc_len = meta.len() + val.len();
327
328        EncodedValue {
329            data: meta.chain(val).copy_to_bytes(enc_len),
330            expires_sz: expires_sz as u8,
331        }
332    }
333
334    /// Decodes byte slice to value ref.
335    #[inline]
336    fn decode_value_ref(src: &[u8]) -> ValueRef {
337        let meta = src[META_OFFSET];
338        let user_meta = src[USER_META_OFFSET];
339        let (expires_at, sz) = binary_uvarint(&src[EXPIRATION_OFFSET..]);
340        ValueRef {
341            meta,
342            user_meta,
343            expires_at,
344            version: 0,
345            val: &src[EXPIRATION_OFFSET + sz..],
346        }
347    }
348
349    /// Decodes byte slice to value.
350    #[inline]
351    fn decode_value(src: &[u8]) -> Value {
352        let meta = src[META_OFFSET];
353        let user_meta = src[USER_META_OFFSET];
354        let (expires_at, sz) = binary_uvarint(&src[EXPIRATION_OFFSET..]);
355        let value = src[EXPIRATION_OFFSET + sz..].to_vec().into();
356
357        Value {
358            meta,
359            user_meta,
360            expires_at,
361            version: 0,
362            value,
363        }
364    }
365
366    /// Decode bytes to value. (Shallow copy)
367    #[inline]
368    fn decode_bytes(src: Bytes) -> Value {
369        let meta = src[META_OFFSET];
370        let user_meta = src[USER_META_OFFSET];
371        let (expires_at, sz) = binary_uvarint(&src[EXPIRATION_OFFSET..]);
372        let value = src.slice(EXPIRATION_OFFSET + sz..);
373
374        Value {
375            meta,
376            user_meta,
377            expires_at,
378            version: 0,
379            value,
380        }
381    }
382
383    impl_psfix_suites!(ValueExt::parse_value, u8, "u8");
384}
385
386/// ValueRef contains a `&'a Value`
387#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
388pub struct ValueRef<'a> {
389    pub(crate) meta: u8,
390    pub(crate) user_meta: u8,
391    pub(crate) expires_at: u64,
392    pub(crate) version: u64, // This field is not serialized. Only for internal usage.
393    pub(crate) val: &'a [u8],
394}
395
396impl<'a> ValueRef<'a> {
397    /// Returns a ValueRef from byte slice
398    #[inline]
399    pub const fn new(
400        meta: u8,
401        user_meta: u8,
402        expires_at: u64,
403        version: u64,
404        data: &'a [u8],
405    ) -> Self {
406        Self {
407            meta,
408            user_meta,
409            expires_at,
410            version,
411            val: data,
412        }
413    }
414
415    /// Returns a ValueRef from [`RawKeyPointer`]
416    ///
417    /// # Safety
418    /// The inner raw pointer of [`RawKeyPointer`] must be valid.
419    ///
420    /// [`RawKeyPointer`]: struct.RawKeyPointer.html
421    #[inline]
422    pub unsafe fn from_raw_value_pointer(rp: RawValuePointer) -> ValueRef<'a> {
423        ValueRef {
424            meta: rp.meta,
425            user_meta: rp.user_meta,
426            expires_at: rp.expires_at,
427            version: rp.version,
428            val: from_raw_parts(rp.ptr, rp.l as usize),
429        }
430    }
431
432    /// Converts a slice of bytes to a string, including invalid characters.
433    #[inline]
434    #[allow(clippy::inherent_to_string)]
435    pub fn to_string(&self) -> String {
436        String::from_utf8_lossy(self.val).to_string()
437    }
438
439    /// Converts a slice of bytes to a string, including invalid characters.
440    #[inline]
441    pub fn to_lossy_string(&self) -> Cow<'_, str> {
442        String::from_utf8_lossy(self.val)
443    }
444
445    /// Copy the data to a new value
446    #[inline]
447    pub fn to_value(&self) -> Value {
448        Value {
449            meta: self.meta,
450            user_meta: self.user_meta,
451            expires_at: self.expires_at,
452            version: self.version,
453            value: Bytes::copy_from_slice(self.val),
454        }
455    }
456
457    /// Get the value version
458    #[inline]
459    pub fn get_version(&self) -> u64 {
460        self.version
461    }
462
463    /// Set the value version for this value ref
464    #[inline]
465    pub fn set_version(&mut self, version: u64) {
466        self.version = version
467    }
468}
469
470impl<'a> ValueExt for ValueRef<'a> {
471    #[inline]
472    fn as_value_ref(&self) -> ValueRef {
473        *self
474    }
475
476    #[inline]
477    fn parse_value(&self) -> &[u8] {
478        self.val
479    }
480
481    #[inline]
482    fn parse_value_to_bytes(&self) -> Bytes {
483        Bytes::copy_from_slice(self.val)
484    }
485
486    #[inline]
487    fn get_meta(&self) -> u8 {
488        self.meta
489    }
490
491    #[inline]
492    fn get_user_meta(&self) -> u8 {
493        self.user_meta
494    }
495
496    #[inline]
497    fn get_expires_at(&self) -> u64 {
498        self.expires_at
499    }
500}
501
502impl<const N: usize> ValueExt for [u8; N] {
503    fn parse_value(&self) -> &[u8] {
504        self
505    }
506
507    fn parse_value_to_bytes(&self) -> Bytes {
508        Bytes::copy_from_slice(self)
509    }
510
511    fn get_meta(&self) -> u8 {
512        self[META_OFFSET]
513    }
514
515    fn get_user_meta(&self) -> u8 {
516        self[USER_META_OFFSET]
517    }
518
519    fn get_expires_at(&self) -> u64 {
520        let (expires_at, _) = binary_uvarint(&self[EXPIRATION_OFFSET..]);
521        expires_at
522    }
523}
524
525impl<'a> ValueExt for &'a [u8] {
526    fn parse_value(&self) -> &[u8] {
527        self
528    }
529
530    fn parse_value_to_bytes(&self) -> Bytes {
531        Bytes::copy_from_slice(self)
532    }
533
534    fn get_meta(&self) -> u8 {
535        self[META_OFFSET]
536    }
537
538    fn get_user_meta(&self) -> u8 {
539        self[USER_META_OFFSET]
540    }
541
542    fn get_expires_at(&self) -> u64 {
543        let (expires_at, _) = binary_uvarint(&self[EXPIRATION_OFFSET..]);
544        expires_at
545    }
546}
547
548impl ValueExt for Box<[u8]> {
549    fn parse_value(&self) -> &[u8] {
550        self
551    }
552
553    fn parse_value_to_bytes(&self) -> Bytes {
554        Bytes::copy_from_slice(self)
555    }
556
557    fn get_meta(&self) -> u8 {
558        self[META_OFFSET]
559    }
560
561    fn get_user_meta(&self) -> u8 {
562        self[USER_META_OFFSET]
563    }
564
565    fn get_expires_at(&self) -> u64 {
566        let (expires_at, _) = binary_uvarint(&self[EXPIRATION_OFFSET..]);
567        expires_at
568    }
569}
570
571impl ValueExt for Arc<[u8]> {
572    fn parse_value(&self) -> &[u8] {
573        self
574    }
575
576    fn parse_value_to_bytes(&self) -> Bytes {
577        Bytes::copy_from_slice(self)
578    }
579
580    fn get_meta(&self) -> u8 {
581        self[META_OFFSET]
582    }
583
584    fn get_user_meta(&self) -> u8 {
585        self[USER_META_OFFSET]
586    }
587
588    fn get_expires_at(&self) -> u64 {
589        let (expires_at, _) = binary_uvarint(&self[EXPIRATION_OFFSET..]);
590        expires_at
591    }
592}
593
594impl ValueExt for Rc<[u8]> {
595    fn parse_value(&self) -> &[u8] {
596        self
597    }
598
599    fn parse_value_to_bytes(&self) -> Bytes {
600        Bytes::copy_from_slice(self)
601    }
602
603    fn get_meta(&self) -> u8 {
604        self[META_OFFSET]
605    }
606
607    fn get_user_meta(&self) -> u8 {
608        self[USER_META_OFFSET]
609    }
610
611    fn get_expires_at(&self) -> u64 {
612        let (expires_at, _) = binary_uvarint(&self[EXPIRATION_OFFSET..]);
613        expires_at
614    }
615}