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