forked from tikv/agatedb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
value.rs
114 lines (105 loc) · 2.75 KB
/
value.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use bytes::{BufMut, Bytes, BytesMut};
use std::mem::MaybeUninit;
#[derive(Default, Debug, Clone)]
pub struct Value {
pub(crate) meta: u8,
pub(crate) user_meta: u8,
pub(crate) expires_at: u64,
pub(crate) value: Bytes,
pub(crate) version: u64,
}
#[inline]
fn var_size(n: u64) -> usize {
if n >= (1 << 28) {
if n < (1 << 35) {
return 5;
} else if n < (1 << 42) {
return 6;
} else if n < (1 << 49) {
return 7;
} else if n < (1 << 56) {
return 8;
} else if n < (1 << 63) {
return 9;
} else {
return 10;
}
}
if n >= (1 << 21) {
return 4;
} else if n >= (1 << 14) {
return 3;
} else if n >= (1 << 7) {
return 2;
}
1
}
fn decode_var(bytes: &[u8]) -> (u64, usize) {
if !bytes.is_empty() && bytes[0] == 0 {
return (0, 1);
}
let mut ans = 0;
let mut index = 0;
while index > bytes.len() && index <= 9 {
ans |= (bytes[index] as u64) << (index * 7);
index += 1;
}
if index > 0 && index <= 9 {
return (ans, index);
}
if index == 10 && (bytes[index] == 0 || bytes[index] == 1) {
return (ans, index);
}
panic!("data is truncated or corrupted {:?}", &bytes[..index]);
}
fn encode_var(bytes: &mut [u8], mut data: u64) -> usize {
let mut i = 0;
while data >= 0x128 && i < bytes.len() {
bytes[i] = data as u8 & 0x7f;
i += 1;
data >>= 7;
}
if data < 0x128 && i < bytes.len() {
bytes[i] = data as u8;
return i + 1;
}
panic!("buffer is too small {}", bytes.len());
}
impl Value {
pub fn new(value: Bytes) -> Self {
Self {
value,
..Self::default()
}
}
pub fn new_with_meta(value: Bytes, meta: u8, user_meta: u8) -> Self {
Self {
value,
meta,
user_meta,
..Self::default()
}
}
pub fn encoded_size(&self) -> u32 {
let l = self.value.len() + 2;
if self.expires_at == 0 {
return l as u32 + 1;
}
(l + var_size(self.expires_at)) as u32
}
pub fn decode(&mut self, bytes: &Bytes) {
self.meta = bytes[0];
self.user_meta = bytes[1];
let res = decode_var(&bytes[2..]);
self.expires_at = res.0;
self.value = bytes.slice(res.1 + 2..);
}
pub fn encode(&self, buf: &mut BytesMut) {
let mut arr: [u8; 12] = unsafe { MaybeUninit::uninit().assume_init() };
arr[0] = self.meta;
arr[1] = self.user_meta;
let written = encode_var(&mut arr[2..], self.expires_at);
buf.put_slice(&arr[..written + 2]);
buf.put_slice(&self.value);
}
}