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
12use reifydb_value::value::datetime::DateTime;
13
14pub mod buf;
15pub mod deserializer;
16pub mod encoded;
17#[cfg(test)]
18mod ordering;
19pub mod serializer;
20pub mod sort;
21pub(crate) mod varint;
22
23use std::{f32, f64};
24
25use reifydb_value::{
26	Result,
27	error::{Error, TypeError},
28};
29
30use crate::key::buf::KeyBuf;
31
32pub trait ByteSink {
33	fn push(&mut self, byte: u8);
34	fn extend_from_slice(&mut self, slice: &[u8]);
35}
36
37impl ByteSink for Vec<u8> {
38	fn push(&mut self, byte: u8) {
39		Vec::push(self, byte);
40	}
41	fn extend_from_slice(&mut self, slice: &[u8]) {
42		Vec::extend_from_slice(self, slice);
43	}
44}
45
46impl ByteSink for KeyBuf {
47	fn push(&mut self, byte: u8) {
48		KeyBuf::push(self, byte);
49	}
50	fn extend_from_slice(&mut self, slice: &[u8]) {
51		KeyBuf::extend_from_slice(self, slice);
52	}
53}
54
55pub fn encode_bool(value: bool) -> u8 {
56	if value {
57		0x00
58	} else {
59		0x01
60	}
61}
62
63pub fn decode_bool(byte: u8) -> Result<bool> {
64	match byte {
65		0x00 => Ok(true),
66		0x01 => Ok(false),
67		b => Err(Error::from(TypeError::SerdeKeycode {
68			message: format!("invalid boolean value {b}"),
69		})),
70	}
71}
72
73pub fn encode_f32(value: f32) -> [u8; 4] {
74	let bits = value.to_bits();
75	if value.is_sign_negative() {
76		bits.to_be_bytes()
77	} else {
78		(!(bits ^ 0x80000000)).to_be_bytes()
79	}
80}
81
82pub fn decode_f32(bytes: [u8; 4]) -> f32 {
83	let encoded = u32::from_be_bytes(bytes);
84	if encoded & 0x80000000 != 0 {
85		f32::from_bits(encoded)
86	} else {
87		f32::from_bits(!encoded ^ 0x80000000)
88	}
89}
90
91pub fn encode_f64(value: f64) -> [u8; 8] {
92	let bits = value.to_bits();
93	if value.is_sign_negative() {
94		bits.to_be_bytes()
95	} else {
96		(!(bits ^ 0x8000000000000000)).to_be_bytes()
97	}
98}
99
100pub fn decode_f64(bytes: [u8; 8]) -> f64 {
101	let encoded = u64::from_be_bytes(bytes);
102	if encoded & 0x8000000000000000 != 0 {
103		f64::from_bits(encoded)
104	} else {
105		f64::from_bits(!encoded ^ 0x8000000000000000)
106	}
107}
108
109pub fn encode_i8(value: i8) -> [u8; 1] {
110	(!(value as u8 ^ 0x80)).to_be_bytes()
111}
112
113pub fn decode_i8(bytes: [u8; 1]) -> i8 {
114	(!u8::from_be_bytes(bytes) ^ 0x80) as i8
115}
116
117pub fn encode_i16(value: i16) -> [u8; 2] {
118	(!(value as u16 ^ 0x8000)).to_be_bytes()
119}
120
121pub fn decode_i16(bytes: [u8; 2]) -> i16 {
122	(!u16::from_be_bytes(bytes) ^ 0x8000) as i16
123}
124
125pub fn encode_i32(value: i32) -> [u8; 4] {
126	(!(value as u32 ^ 0x80000000)).to_be_bytes()
127}
128
129pub fn decode_i32(bytes: [u8; 4]) -> i32 {
130	(!u32::from_be_bytes(bytes) ^ 0x80000000) as i32
131}
132
133pub fn encode_i64(value: i64) -> [u8; 8] {
134	(!(value as u64 ^ 0x8000000000000000)).to_be_bytes()
135}
136
137pub fn decode_i64(bytes: [u8; 8]) -> i64 {
138	(!u64::from_be_bytes(bytes) ^ 0x8000000000000000) as i64
139}
140
141pub fn encode_i128(value: i128) -> [u8; 16] {
142	(!(value as u128 ^ 0x80000000000000000000000000000000)).to_be_bytes()
143}
144
145pub fn decode_i128(bytes: [u8; 16]) -> i128 {
146	(!u128::from_be_bytes(bytes) ^ 0x80000000000000000000000000000000) as i128
147}
148
149pub fn encode_u8(value: u8) -> u8 {
150	!value
151}
152
153pub fn decode_u8(byte: u8) -> u8 {
154	!byte
155}
156
157pub fn encode_u16(value: u16) -> [u8; 2] {
158	(!value).to_be_bytes()
159}
160
161pub fn decode_u16(bytes: [u8; 2]) -> u16 {
162	!u16::from_be_bytes(bytes)
163}
164
165pub fn encode_u32(value: u32) -> [u8; 4] {
166	(!value).to_be_bytes()
167}
168
169pub fn decode_u32(bytes: [u8; 4]) -> u32 {
170	!u32::from_be_bytes(bytes)
171}
172
173pub fn encode_u64(value: u64) -> [u8; 8] {
174	(!value).to_be_bytes()
175}
176
177pub fn decode_u64(bytes: [u8; 8]) -> u64 {
178	!u64::from_be_bytes(bytes)
179}
180
181pub fn decode_u64_from(input: &mut &[u8]) -> Result<u64> {
182	if input.len() < 8 {
183		return Err(Error::from(TypeError::SerdeKeycode {
184			message: "unexpected end of key while decoding u64".to_string(),
185		}));
186	}
187	let value = decode_u64(input[..8].try_into()?);
188	*input = &input[8..];
189	Ok(value)
190}
191
192pub fn encode_u64_asc(value: u64) -> [u8; 8] {
193	value.to_be_bytes()
194}
195
196pub fn decode_u64_asc(bytes: [u8; 8]) -> u64 {
197	u64::from_be_bytes(bytes)
198}
199
200pub fn encode_datetime_asc(value: DateTime) -> [u8; 8] {
201	encode_u64_asc(value.to_bits())
202}
203
204pub fn decode_datetime_asc(bytes: [u8; 8]) -> DateTime {
205	DateTime::from_bits(decode_u64_asc(bytes))
206}
207
208pub fn encode_u128_asc(value: u128) -> [u8; 16] {
209	value.to_be_bytes()
210}
211
212pub fn decode_u128_asc(bytes: [u8; 16]) -> u128 {
213	u128::from_be_bytes(bytes)
214}
215
216fn encode_u64_varint<B: ByteSink>(value: u64, output: &mut B) {
217	debug_assert!(
218		value < (1 << 56),
219		"encode_u64_varint is a private helper for encode_u128_varint, which only calls it below 2^56"
220	);
221	if value < (1 << 7) {
222		output.push(!(value as u8));
223	} else if value < (1 << 14) {
224		output.push(!(0x80 | (value >> 8) as u8));
225		output.push(!(value as u8));
226	} else if value < (1 << 21) {
227		output.push(!(0xc0 | (value >> 16) as u8));
228		output.push(!((value >> 8) as u8));
229		output.push(!(value as u8));
230	} else if value < (1 << 28) {
231		output.push(!(0xe0 | (value >> 24) as u8));
232		output.push(!((value >> 16) as u8));
233		output.push(!((value >> 8) as u8));
234		output.push(!(value as u8));
235	} else if value < (1 << 35) {
236		output.push(!(0xf0 | (value >> 32) as u8));
237		output.push(!((value >> 24) as u8));
238		output.push(!((value >> 16) as u8));
239		output.push(!((value >> 8) as u8));
240		output.push(!(value as u8));
241	} else if value < (1 << 42) {
242		output.push(!(0xf8 | (value >> 40) as u8));
243		output.push(!((value >> 32) as u8));
244		output.push(!((value >> 24) as u8));
245		output.push(!((value >> 16) as u8));
246		output.push(!((value >> 8) as u8));
247		output.push(!(value as u8));
248	} else if value < (1 << 49) {
249		output.push(!(0xfc | (value >> 48) as u8));
250		output.push(!((value >> 40) as u8));
251		output.push(!((value >> 32) as u8));
252		output.push(!((value >> 24) as u8));
253		output.push(!((value >> 16) as u8));
254		output.push(!((value >> 8) as u8));
255		output.push(!(value as u8));
256	} else {
257		output.push(!0xfe);
258		output.push(!((value >> 48) as u8));
259		output.push(!((value >> 40) as u8));
260		output.push(!((value >> 32) as u8));
261		output.push(!((value >> 24) as u8));
262		output.push(!((value >> 16) as u8));
263		output.push(!((value >> 8) as u8));
264		output.push(!(value as u8));
265	}
266}
267
268pub fn encode_u128(value: u128) -> [u8; 16] {
269	(!value).to_be_bytes()
270}
271
272pub fn decode_u128(bytes: [u8; 16]) -> u128 {
273	!u128::from_be_bytes(bytes)
274}
275
276pub fn encode_fixed<const N: usize>(value: [u8; N]) -> [u8; N] {
277	let mut encoded = value;
278	for byte in encoded.iter_mut() {
279		*byte = !*byte;
280	}
281	encoded
282}
283
284pub fn decode_fixed<const N: usize>(bytes: [u8; N]) -> [u8; N] {
285	encode_fixed(bytes)
286}
287
288pub fn encode_u128_varint<B: ByteSink>(value: u128, output: &mut B) {
289	if value < (1 << 56) {
290		encode_u64_varint(value as u64, output);
291	} else {
292		output.push(!0xff);
293		let bytes = value.to_be_bytes();
294		let start = bytes.iter().position(|&b| b != 0).unwrap_or(bytes.len() - 1);
295		let sig = &bytes[start..];
296		output.push(!(sig.len() as u8));
297		for &b in sig {
298			output.push(!b);
299		}
300	}
301}
302
303pub fn decode_u128_varint(input: &mut &[u8]) -> Result<u128> {
304	if input.is_empty() {
305		return Err(Error::from(TypeError::SerdeKeycode {
306			message: "unexpected end of key while decoding u128 varint".to_string(),
307		}));
308	}
309	let first = !input[0];
310	let prefix = first.leading_ones() as usize;
311	if prefix < 8 {
312		let len = prefix + 1;
313		if input.len() < len {
314			return Err(Error::from(TypeError::SerdeKeycode {
315				message: "unexpected end of key while decoding u128 varint".to_string(),
316			}));
317		}
318		let mut buf = [0u8; 9];
319		for (dst, &src) in buf[..len].iter_mut().zip(&input[..len]) {
320			*dst = !src;
321		}
322		let mut slice = &buf[..len];
323		let v = varint::decode_u64_varint(&mut slice).ok_or_else(|| {
324			Error::from(TypeError::SerdeKeycode {
325				message: "failed to decode u128 varint".to_string(),
326			})
327		})?;
328		*input = &input[len..];
329		Ok(v as u128)
330	} else {
331		if input.len() < 2 {
332			return Err(Error::from(TypeError::SerdeKeycode {
333				message: "unexpected end of key while decoding u128 varint length".to_string(),
334			}));
335		}
336		let len = (!input[1]) as usize;
337		if len == 0 || len > 16 || input.len() < 2 + len {
338			return Err(Error::from(TypeError::SerdeKeycode {
339				message: "invalid u128 varint length".to_string(),
340			}));
341		}
342		let mut bytes = [0u8; 16];
343		for (i, &src) in input[2..2 + len].iter().enumerate() {
344			bytes[16 - len + i] = !src;
345		}
346		*input = &input[2 + len..];
347		Ok(u128::from_be_bytes(bytes))
348	}
349}
350
351pub const CONTAINER_END: u8 = 0xff;
352
353pub fn encode_bytes<B: ByteSink>(bytes: &[u8], output: &mut B) {
354	for &byte in bytes {
355		if byte == 0x00 {
356			output.push(0xff);
357			output.push(0x00);
358		} else {
359			output.push(!byte);
360		}
361	}
362	output.extend_from_slice(&[0xff, 0xff]);
363}
364
365#[macro_export]
366macro_rules! key_prefix {
367    ($($arg:tt)*) => {
368        &EncodedKey::new((&format!($($arg)*)).as_bytes())
369    };
370}