kvstructs/
value_enc.rs

1use crate::bytes::Bytes;
2use crate::{binary_uvarint, Value, ValueExt};
3
4/// The position store meta in a encoded value
5pub const META_OFFSET: usize = 0;
6/// The position store user meta in a encoded value
7pub const USER_META_OFFSET: usize = 1;
8/// The position store expires_at in a encoded value
9pub const EXPIRATION_OFFSET: usize = 2;
10
11/// EncodedValue contains the data need to be stored in Bytes.
12///
13/// **Note**: When [`Value`] is encoded to `EncodedValue`,
14/// the version field will not be encoded.
15/// So, when convert from `EncodedValue` to [`Value`],
16/// version is always be 0.
17#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
18pub struct EncodedValue {
19    pub(crate) data: Bytes,
20    pub(crate) expires_sz: u8,
21}
22
23impl EncodedValue {
24    /// Decode `EncodedValue` to Value (shallow copy).
25    pub fn decode_value(&self) -> Value {
26        let meta = self.data[META_OFFSET];
27        let user_meta = self.data[USER_META_OFFSET];
28        let (expires_at, sz) = binary_uvarint(&self.data[EXPIRATION_OFFSET..]);
29        let value = self.data.slice(EXPIRATION_OFFSET + sz..);
30
31        Value {
32            meta,
33            user_meta,
34            expires_at,
35            version: 0,
36            value,
37        }
38    }
39
40    /// Returns the length of encoded value
41    #[inline]
42    pub fn len(&self) -> usize {
43        self.data.len()
44    }
45
46    /// Returns if the encoded value is empty
47    #[inline]
48    pub fn is_empty(&self) -> bool {
49        self.data.is_empty()
50    }
51
52    /// Returns the encoded data (including meta, user_meta, expires_at, value)
53    #[inline]
54    pub fn leak_data(self) -> Bytes {
55        self.data
56    }
57}
58
59impl ValueExt for EncodedValue {
60    #[inline]
61    fn parse_value(&self) -> &[u8] {
62        &self.data[(EXPIRATION_OFFSET + self.expires_sz as usize)..]
63    }
64
65    #[inline]
66    fn parse_value_to_bytes(&self) -> Bytes {
67        self.data
68            .slice((EXPIRATION_OFFSET + self.expires_sz as usize)..)
69    }
70
71    #[inline]
72    fn get_meta(&self) -> u8 {
73        self.data[META_OFFSET]
74    }
75
76    #[inline]
77    fn get_user_meta(&self) -> u8 {
78        self.data[USER_META_OFFSET]
79    }
80
81    #[inline]
82    fn get_expires_at(&self) -> u64 {
83        let (expires_at, _) = binary_uvarint(&self.data[EXPIRATION_OFFSET..]);
84        expires_at
85    }
86
87    #[inline]
88    fn to_encoded(&self) -> EncodedValue {
89        self.clone()
90    }
91}
92
93macro_rules! impl_value_ext_for_bytes {
94    ($($ty: ty), +$(,)?) => {
95        $(
96        impl ValueExt for $ty {
97            #[inline]
98            fn parse_value(&self) -> &[u8] {
99                let (_, sz) = binary_uvarint(&self.as_ref()[EXPIRATION_OFFSET..]);
100
101                &self[(EXPIRATION_OFFSET + sz)..]
102            }
103
104            #[inline]
105            fn parse_value_to_bytes(&self) -> Bytes {
106                let (_, sz) = binary_uvarint(&self[EXPIRATION_OFFSET..]);
107                self.slice((EXPIRATION_OFFSET + sz)..)
108            }
109
110            #[inline]
111            fn get_meta(&self) -> u8 {
112                self[META_OFFSET]
113            }
114
115            #[inline]
116            fn get_user_meta(&self) -> u8 {
117                self[USER_META_OFFSET]
118            }
119
120            #[inline]
121            fn get_expires_at(&self) -> u64 {
122                let (expires_at, _) = binary_uvarint(&self[EXPIRATION_OFFSET..]);
123                expires_at
124            }
125        }
126        )*
127    };
128}
129
130impl_value_ext_for_bytes! {
131    Bytes,
132}