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
17const MAX_VALUE_INFO_SIZE: usize = mem::size_of::<u8>() * 2 + mem::size_of::<u64>();
19
20#[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, 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 #[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 #[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 #[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 #[inline]
108 pub const fn set_meta(mut self, meta: u8) -> Self {
109 self.meta = meta;
110 self
111 }
112
113 #[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 #[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 #[inline]
129 pub const fn set_version(mut self, version: u64) -> Self {
130 self.version = version;
131 self
132 }
133
134 #[inline]
136 pub fn set_data(mut self, value: Bytes) -> Self {
137 self.value = value;
138 self
139 }
140
141 #[inline]
143 pub const fn get_version(&self) -> u64 {
144 self.version
145 }
146
147 #[inline]
149 pub fn len(&self) -> usize {
150 self.value.len()
151 }
152
153 #[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
240pub trait ValueExt {
242 #[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 fn parse_value(&self) -> &[u8];
258
259 fn parse_value_to_bytes(&self) -> Bytes;
263
264 fn get_meta(&self) -> u8;
266
267 fn get_user_meta(&self) -> u8;
269
270 fn get_expires_at(&self) -> u64;
272
273 #[inline]
275 fn encoded_size(&self) -> u32 {
276 let sz = self.parse_value().len() + 2; let enc = size_variant(self.get_expires_at());
278 (sz + enc) as u32
279 }
280
281 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 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 #[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 #[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 #[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 #[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#[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, pub(crate) val: &'a [u8],
394}
395
396impl<'a> ValueRef<'a> {
397 #[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 #[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 #[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 #[inline]
441 pub fn to_lossy_string(&self) -> Cow<'_, str> {
442 String::from_utf8_lossy(self.val)
443 }
444
445 #[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 #[inline]
459 pub fn get_version(&self) -> u64 {
460 self.version
461 }
462
463 #[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}