plugmem_arena/key.rs
1//! Big-endian key encoding helpers.
2//!
3//! Every sorted structure in this crate compares keys **byte-wise**
4//! (`[u8]::cmp`). For that comparison to match the numeric order of the
5//! encoded values, integers must be stored **big-endian**: the most
6//! significant byte comes first, so lexicographic byte order equals numeric
7//! order. (Little-endian encodings are only usable for equality lookups —
8//! this is a classic pitfall.)
9//!
10//! Composite keys are built by concatenation: encode the most significant
11//! component first. For example a temporal index key `(timestamp, id)` is
12//! `write_u64(&mut buf[..8], ts)` followed by `write_u32(&mut buf[8..], id)`
13//! — byte order then sorts by timestamp first, id second.
14
15/// Encodes `v` big-endian into the first 4 bytes of `out`.
16///
17/// # Panics
18///
19/// Panics if `out.len() < 4`.
20#[inline]
21pub fn write_u32(out: &mut [u8], v: u32) {
22 out[..4].copy_from_slice(&v.to_be_bytes());
23}
24
25/// Decodes a big-endian `u32` from the first 4 bytes of `bytes`.
26///
27/// # Panics
28///
29/// Panics if `bytes.len() < 4`.
30#[inline]
31pub fn read_u32(bytes: &[u8]) -> u32 {
32 let mut b = [0u8; 4];
33 b.copy_from_slice(&bytes[..4]);
34 u32::from_be_bytes(b)
35}
36
37/// Encodes `v` big-endian into the first 8 bytes of `out`.
38///
39/// # Panics
40///
41/// Panics if `out.len() < 8`.
42#[inline]
43pub fn write_u64(out: &mut [u8], v: u64) {
44 out[..8].copy_from_slice(&v.to_be_bytes());
45}
46
47/// Decodes a big-endian `u64` from the first 8 bytes of `bytes`.
48///
49/// # Panics
50///
51/// Panics if `bytes.len() < 8`.
52#[inline]
53pub fn read_u64(bytes: &[u8]) -> u64 {
54 let mut b = [0u8; 8];
55 b.copy_from_slice(&bytes[..8]);
56 u64::from_be_bytes(b)
57}
58
59/// Encodes the composite key `(hi, lo)` big-endian into the first 12 bytes
60/// of `out` (`hi` first — it is the more significant component).
61///
62/// This is the layout of e.g. the temporal index key
63/// `[recorded_at: u64 | fact_id: u32]`.
64///
65/// # Panics
66///
67/// Panics if `out.len() < 12`.
68#[inline]
69pub fn write_pair(out: &mut [u8], hi: u64, lo: u32) {
70 write_u64(out, hi);
71 write_u32(&mut out[8..], lo);
72}
73
74/// Decodes a composite key previously encoded with [`write_pair`].
75///
76/// # Panics
77///
78/// Panics if `bytes.len() < 12`.
79#[inline]
80pub fn read_pair(bytes: &[u8]) -> (u64, u32) {
81 (read_u64(bytes), read_u32(&bytes[8..]))
82}