Skip to main content

reifydb_codec/key/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4// This file includes and modifies code from the toydb project (https://github.com/erikgrinaker/toydb),
5// originally licensed under the Apache License, Version 2.0.
6// Original copyright:
7//   Copyright (c) 2024 Erik Grinaker
8//
9// The original Apache License can be found at:
10//   http://www.apache.org/licenses/LICENSE-2.0
11
12//! Order-determining codec turning typed keys into the bytes that go on disk: a range scan reads
13//! order straight off the bytes with no decode pass. Booleans, numbers and temporals are
14//! bit-inverted and so sort descending; utf8, blobs and uuids are stored plain and sort ascending.
15//! `encode_*_asc` are the uninverted integer forms for keyspaces that need a forward scan.
16
17use reifydb_value::value::datetime::DateTime;
18use serde::{Deserialize, Serialize};
19
20pub mod buf;
21pub mod deserialize;
22pub mod deserializer;
23pub mod encoded;
24pub mod serialize;
25pub mod serializer;
26pub mod sort;
27pub(crate) mod varint;
28
29use std::{f32, f64};
30
31use reifydb_value::{
32	Result,
33	error::{Error, TypeError},
34};
35
36use crate::key::{buf::KeyBuf, deserialize::Deserializer, serialize::Serializer};
37
38pub trait ByteSink {
39	fn push(&mut self, byte: u8);
40	fn extend_from_slice(&mut self, slice: &[u8]);
41}
42
43impl ByteSink for Vec<u8> {
44	fn push(&mut self, byte: u8) {
45		Vec::push(self, byte);
46	}
47	fn extend_from_slice(&mut self, slice: &[u8]) {
48		Vec::extend_from_slice(self, slice);
49	}
50}
51
52impl ByteSink for KeyBuf {
53	fn push(&mut self, byte: u8) {
54		KeyBuf::push(self, byte);
55	}
56	fn extend_from_slice(&mut self, slice: &[u8]) {
57		KeyBuf::extend_from_slice(self, slice);
58	}
59}
60
61pub fn encode_bool(value: bool) -> u8 {
62	if value {
63		0x00
64	} else {
65		0x01
66	}
67}
68
69pub fn encode_f32(value: f32) -> [u8; 4] {
70	let bits = value.to_bits();
71	if value.is_sign_negative() {
72		bits.to_be_bytes()
73	} else {
74		(!(bits ^ 0x80000000)).to_be_bytes()
75	}
76}
77
78pub fn encode_f64(value: f64) -> [u8; 8] {
79	let bits = value.to_bits();
80	if value.is_sign_negative() {
81		bits.to_be_bytes()
82	} else {
83		(!(bits ^ 0x8000000000000000)).to_be_bytes()
84	}
85}
86
87pub fn encode_i8(value: i8) -> [u8; 1] {
88	(!(value as u8 ^ 0x80)).to_be_bytes()
89}
90
91pub fn encode_i16(value: i16) -> [u8; 2] {
92	(!(value as u16 ^ 0x8000)).to_be_bytes()
93}
94
95pub fn encode_i32(value: i32) -> [u8; 4] {
96	(!(value as u32 ^ 0x80000000)).to_be_bytes()
97}
98
99pub fn encode_i64(value: i64) -> [u8; 8] {
100	(!(value as u64 ^ 0x8000000000000000)).to_be_bytes()
101}
102
103pub fn encode_i128(value: i128) -> [u8; 16] {
104	(!(value as u128 ^ 0x80000000000000000000000000000000)).to_be_bytes()
105}
106
107pub fn encode_u8(value: u8) -> u8 {
108	!value
109}
110
111pub fn encode_u16(value: u16) -> [u8; 2] {
112	(!value).to_be_bytes()
113}
114
115pub fn encode_u32(value: u32) -> [u8; 4] {
116	(!value).to_be_bytes()
117}
118
119pub fn encode_u64(value: u64) -> [u8; 8] {
120	(!value).to_be_bytes()
121}
122
123pub fn decode_u64(bytes: [u8; 8]) -> u64 {
124	!u64::from_be_bytes(bytes)
125}
126
127pub fn decode_u64_from(input: &mut &[u8]) -> Result<u64> {
128	if input.len() < 8 {
129		return Err(Error::from(TypeError::SerdeKeycode {
130			message: "unexpected end of key while decoding u64".to_string(),
131		}));
132	}
133	let value = decode_u64(input[..8].try_into()?);
134	*input = &input[8..];
135	Ok(value)
136}
137
138pub fn encode_u64_asc(value: u64) -> [u8; 8] {
139	value.to_be_bytes()
140}
141
142pub fn decode_u64_asc(bytes: [u8; 8]) -> u64 {
143	u64::from_be_bytes(bytes)
144}
145
146pub fn encode_datetime_asc(value: DateTime) -> [u8; 8] {
147	encode_u64_asc(value.to_bits())
148}
149
150pub fn decode_datetime_asc(bytes: [u8; 8]) -> DateTime {
151	DateTime::from_bits(decode_u64_asc(bytes))
152}
153
154pub fn encode_u128_asc(value: u128) -> [u8; 16] {
155	value.to_be_bytes()
156}
157
158pub fn decode_u128_asc(bytes: [u8; 16]) -> u128 {
159	u128::from_be_bytes(bytes)
160}
161
162pub fn encode_u64_varint<B: ByteSink>(value: u64, output: &mut B) {
163	if value < (1 << 7) {
164		output.push(!(value as u8));
165	} else if value < (1 << 14) {
166		output.push(!(0x80 | (value >> 8) as u8));
167		output.push(!(value as u8));
168	} else if value < (1 << 21) {
169		output.push(!(0xc0 | (value >> 16) as u8));
170		output.push(!((value >> 8) as u8));
171		output.push(!(value as u8));
172	} else if value < (1 << 28) {
173		output.push(!(0xe0 | (value >> 24) as u8));
174		output.push(!((value >> 16) as u8));
175		output.push(!((value >> 8) as u8));
176		output.push(!(value as u8));
177	} else if value < (1 << 35) {
178		output.push(!(0xf0 | (value >> 32) as u8));
179		output.push(!((value >> 24) as u8));
180		output.push(!((value >> 16) as u8));
181		output.push(!((value >> 8) as u8));
182		output.push(!(value as u8));
183	} else if value < (1 << 42) {
184		output.push(!(0xf8 | (value >> 40) as u8));
185		output.push(!((value >> 32) as u8));
186		output.push(!((value >> 24) as u8));
187		output.push(!((value >> 16) as u8));
188		output.push(!((value >> 8) as u8));
189		output.push(!(value as u8));
190	} else if value < (1 << 49) {
191		output.push(!(0xfc | (value >> 48) as u8));
192		output.push(!((value >> 40) as u8));
193		output.push(!((value >> 32) as u8));
194		output.push(!((value >> 24) as u8));
195		output.push(!((value >> 16) as u8));
196		output.push(!((value >> 8) as u8));
197		output.push(!(value as u8));
198	} else if value < (1 << 56) {
199		output.push(!(0xfe | (value >> 56) as u8));
200		output.push(!((value >> 48) as u8));
201		output.push(!((value >> 40) as u8));
202		output.push(!((value >> 32) as u8));
203		output.push(!((value >> 24) as u8));
204		output.push(!((value >> 16) as u8));
205		output.push(!((value >> 8) as u8));
206		output.push(!(value as u8));
207	} else {
208		output.push(!0xff);
209		let inv = !value;
210		output.extend_from_slice(&inv.to_be_bytes());
211	}
212}
213
214pub fn encode_u128(value: u128) -> [u8; 16] {
215	(!value).to_be_bytes()
216}
217
218pub fn encode_u128_varint<B: ByteSink>(value: u128, output: &mut B) {
219	if value < (1 << 56) {
220		encode_u64_varint(value as u64, output);
221	} else {
222		output.push(!0xff);
223		let bytes = value.to_be_bytes();
224		let start = bytes.iter().position(|&b| b != 0).unwrap_or(bytes.len() - 1);
225		let sig = &bytes[start..];
226		output.push(!(sig.len() as u8));
227		for &b in sig {
228			output.push(!b);
229		}
230	}
231}
232
233pub fn decode_u128_varint(input: &mut &[u8]) -> Result<u128> {
234	if input.is_empty() {
235		return Err(Error::from(TypeError::SerdeKeycode {
236			message: "unexpected end of key while decoding u128 varint".to_string(),
237		}));
238	}
239	let first = !input[0];
240	let prefix = first.leading_ones() as usize;
241	if prefix < 8 {
242		let len = prefix + 1;
243		if input.len() < len {
244			return Err(Error::from(TypeError::SerdeKeycode {
245				message: "unexpected end of key while decoding u128 varint".to_string(),
246			}));
247		}
248		let mut buf = [0u8; 9];
249		for (dst, &src) in buf[..len].iter_mut().zip(&input[..len]) {
250			*dst = !src;
251		}
252		let mut slice = &buf[..len];
253		let v = varint::decode_u64_varint(&mut slice).ok_or_else(|| {
254			Error::from(TypeError::SerdeKeycode {
255				message: "failed to decode u128 varint".to_string(),
256			})
257		})?;
258		*input = &input[len..];
259		Ok(v as u128)
260	} else {
261		if input.len() < 2 {
262			return Err(Error::from(TypeError::SerdeKeycode {
263				message: "unexpected end of key while decoding u128 varint length".to_string(),
264			}));
265		}
266		let len = (!input[1]) as usize;
267		if len == 0 || len > 16 || input.len() < 2 + len {
268			return Err(Error::from(TypeError::SerdeKeycode {
269				message: "invalid u128 varint length".to_string(),
270			}));
271		}
272		let mut bytes = [0u8; 16];
273		for (i, &src) in input[2..2 + len].iter().enumerate() {
274			bytes[16 - len + i] = !src;
275		}
276		*input = &input[2 + len..];
277		Ok(u128::from_be_bytes(bytes))
278	}
279}
280
281pub const CONTAINER_END: u8 = 0xff;
282
283pub fn encode_bytes<B: ByteSink>(bytes: &[u8], output: &mut B) {
284	let mut start = 0;
285	while let Some(pos) = bytes[start..].iter().position(|&b| b == 0xff) {
286		let end = start + pos;
287		output.extend_from_slice(&bytes[start..end]);
288		output.extend_from_slice(&[0xff, 0x00]);
289		start = end + 1;
290	}
291	output.extend_from_slice(&bytes[start..]);
292	output.extend_from_slice(&[0xff, 0xff]);
293}
294
295#[macro_export]
296macro_rules! key_prefix {
297    ($($arg:tt)*) => {
298        &EncodedKey::new((&format!($($arg)*)).as_bytes())
299    };
300}
301
302pub fn serialize<T: Serialize>(key: &T) -> Vec<u8> {
303	let mut serializer = Serializer {
304		output: Vec::new(),
305	};
306
307	key.serialize(&mut serializer).expect("key must be serializable");
308	serializer.output
309}
310
311pub fn deserialize<'a, T: Deserialize<'a>>(input: &'a [u8]) -> Result<T> {
312	let mut deserializer = Deserializer::from_bytes(input);
313	let t = T::deserialize(&mut deserializer)?;
314	if !deserializer.input.is_empty() {
315		return Err(Error::from(TypeError::SerdeKeycode {
316			message: format!(
317				"unexpected trailing bytes {:x?} at end of key {input:x?}",
318				deserializer.input,
319			),
320		}));
321	}
322	Ok(t)
323}