reifydb_core/util/encoding/keycode/
varint.rs1pub fn encode_u64_varint(v: u64, output: &mut Vec<u8>) {
5 if v < (1 << 7) {
6 output.push(v as u8);
7 } else if v < (1 << 14) {
8 output.push(0x80 | (v >> 8) as u8);
9 output.push(v as u8);
10 } else if v < (1 << 21) {
11 output.push(0xc0 | (v >> 16) as u8);
12 output.push((v >> 8) as u8);
13 output.push(v as u8);
14 } else if v < (1 << 28) {
15 output.push(0xe0 | (v >> 24) as u8);
16 output.push((v >> 16) as u8);
17 output.push((v >> 8) as u8);
18 output.push(v as u8);
19 } else if v < (1 << 35) {
20 output.push(0xf0 | (v >> 32) as u8);
21 output.push((v >> 24) as u8);
22 output.push((v >> 16) as u8);
23 output.push((v >> 8) as u8);
24 output.push(v as u8);
25 } else if v < (1 << 42) {
26 output.push(0xf8 | (v >> 40) as u8);
27 output.push((v >> 32) as u8);
28 output.push((v >> 24) as u8);
29 output.push((v >> 16) as u8);
30 output.push((v >> 8) as u8);
31 output.push(v as u8);
32 } else if v < (1 << 49) {
33 output.push(0xfc | (v >> 48) as u8);
34 output.push((v >> 40) as u8);
35 output.push((v >> 32) as u8);
36 output.push((v >> 24) as u8);
37 output.push((v >> 16) as u8);
38 output.push((v >> 8) as u8);
39 output.push(v as u8);
40 } else if v < (1 << 56) {
41 output.push(0xfe | (v >> 56) as u8);
42 output.push((v >> 48) as u8);
43 output.push((v >> 40) as u8);
44 output.push((v >> 32) as u8);
45 output.push((v >> 24) as u8);
46 output.push((v >> 16) as u8);
47 output.push((v >> 8) as u8);
48 output.push(v as u8);
49 } else {
50 output.push(0xff);
51 output.extend_from_slice(&v.to_be_bytes());
52 }
53}
54
55pub fn decode_u64_varint(input: &mut &[u8]) -> Option<u64> {
56 if input.is_empty() {
57 return None;
58 }
59 let first = input[0];
60 let prefix = first.leading_ones() as usize;
61 if prefix == 0 {
62 *input = &input[1..];
63 Some(first as u64)
64 } else if prefix < 8 {
65 if input.len() <= prefix {
66 return None;
67 }
68 let mut v = if prefix == 7 {
69 0
70 } else {
71 (first & (0xff >> (prefix + 1))) as u64
72 };
73 for i in 1..=prefix {
74 v = (v << 8) | input[i] as u64;
75 }
76 *input = &input[prefix + 1..];
77 Some(v)
78 } else {
79 if input.len() < 9 {
80 return None;
81 }
82 let mut bytes = [0u8; 8];
83 bytes.copy_from_slice(&input[1..9]);
84 *input = &input[9..];
85 Some(u64::from_be_bytes(bytes))
86 }
87}
88
89pub fn encode_i64_varint(v: i64, output: &mut Vec<u8>) {
90 if v >= 0 {
91 if v < 64 {
92 output.push(0x80 | v as u8);
93 } else if v < 8192 + 64 {
94 let v = (v - 64) as u16;
95 output.push(0xc0 | (v >> 8) as u8);
96 output.push(v as u8);
97 } else {
98 output.push(0xfe);
99 output.extend_from_slice(&v.to_be_bytes());
100 }
101 } else if v >= -64 {
102 output.push(0x40 | (v + 64) as u8);
103 } else if v >= -8192 - 64 {
104 let v = (v + 64 + 8192) as u16;
105 output.push(0x20 | (v >> 8) as u8);
106 output.push(v as u8);
107 } else {
108 output.push(0x01);
109 output.extend_from_slice(&v.to_be_bytes());
110 }
111}
112
113pub fn decode_i64_varint(input: &mut &[u8]) -> Option<i64> {
114 if input.is_empty() {
115 return None;
116 }
117 let first = input[0];
118 if first >= 0x80 {
119 if first < 0xc0 {
120 *input = &input[1..];
121 Some((first & 0x3f) as i64)
122 } else if first < 0xfe {
123 if input.len() < 2 {
124 return None;
125 }
126 let v = ((first & 0x1f) as u16) << 8 | input[1] as u16;
127 *input = &input[2..];
128 Some(v as i64 + 64)
129 } else {
130 if input.len() < 9 {
131 return None;
132 }
133 let mut bytes = [0u8; 8];
134 bytes.copy_from_slice(&input[1..9]);
135 *input = &input[9..];
136 Some(i64::from_be_bytes(bytes))
137 }
138 } else if first >= 0x40 {
139 *input = &input[1..];
140 Some((first & 0x3f) as i64 - 64)
141 } else if first >= 0x20 {
142 if input.len() < 2 {
143 return None;
144 }
145 let v = ((first & 0x1f) as u16) << 8 | input[1] as u16;
146 *input = &input[2..];
147 Some(v as i64 - 64 - 8192)
148 } else {
149 if input.len() < 9 {
150 return None;
151 }
152 let mut bytes = [0u8; 8];
153 bytes.copy_from_slice(&input[1..9]);
154 *input = &input[9..];
155 Some(i64::from_be_bytes(bytes))
156 }
157}
158
159#[cfg(test)]
160mod tests {
161 use super::*;
162
163 #[test]
164 fn test_u64_varint_ordering() {
165 let values = vec![
166 0,
167 1,
168 127,
169 128,
170 16383,
171 16384,
172 1000000,
173 2000000,
174 u32::MAX as u64,
175 u32::MAX as u64 + 1,
176 u64::MAX - 1,
177 u64::MAX,
178 ];
179 let mut encoded = Vec::new();
180 for &v in &values {
181 let mut buf = Vec::new();
182 encode_u64_varint(v, &mut buf);
183 encoded.push(buf);
184 }
185
186 for i in 0..values.len() - 1 {
187 assert!(values[i] < values[i + 1]);
188 assert!(encoded[i] < encoded[i + 1], "failed for {} vs {}", values[i], values[i + 1]);
189 }
190 }
191
192 #[test]
193 fn test_i64_varint_ordering() {
194 let values = vec![
195 i64::MIN,
196 i64::MIN + 1,
197 -1000000,
198 -8257,
199 -8256,
200 -65,
201 -64,
202 -1,
203 0,
204 1,
205 63,
206 64,
207 8255,
208 8256,
209 1000000,
210 i64::MAX - 1,
211 i64::MAX,
212 ];
213 let mut encoded = Vec::new();
214 for &v in &values {
215 let mut buf = Vec::new();
216 encode_i64_varint(v, &mut buf);
217 encoded.push(buf);
218 }
219
220 for i in 0..values.len() - 1 {
221 assert!(values[i] < values[i + 1], "values not sorted: {} vs {}", values[i], values[i + 1]);
222 assert!(
223 encoded[i] < encoded[i + 1],
224 "encoded not sorted: {} ({:x?}) vs {} ({:x?})",
225 values[i],
226 encoded[i],
227 values[i + 1],
228 encoded[i + 1]
229 );
230 }
231 }
232
233 #[test]
234 fn test_i64_varint_roundtrip() {
235 let values = vec![i64::MIN, -1000000, -65, -64, -1, 0, 1, 63, 64, 1000000, i64::MAX];
236 for v in values {
237 let mut buf = Vec::new();
238 encode_i64_varint(v, &mut buf);
239 let mut slice = &buf[..];
240 assert_eq!(decode_i64_varint(&mut slice), Some(v), "failed for {}", v);
241 assert!(slice.is_empty());
242 }
243 }
244}