Skip to main content

akar_common/
serialization.rs

1//! Binary serialization/deserialization primitives (LittleEndian).
2//!
3//! Used by the storage engine to persist data to disk.
4
5use std::io::{Read, Write};
6
7/// Serialize a value into a byte buffer (LittleEndian).
8pub trait Serialize {
9    fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()>;
10}
11
12/// Deserialize a value from a byte buffer (LittleEndian).
13pub trait Deserialize: Sized {
14    fn deserialize<R: Read>(reader: &mut R) -> std::io::Result<Self>;
15}
16
17// --- Primitive implementations ---
18
19macro_rules! impl_serialize_le {
20    ($($ty:ty),*) => {
21        $(
22            impl Serialize for $ty {
23                fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
24                    writer.write_all(&self.to_le_bytes())
25                }
26            }
27
28            impl Deserialize for $ty {
29                fn deserialize<R: Read>(reader: &mut R) -> std::io::Result<Self> {
30                    let mut buf = [0u8; std::mem::size_of::<Self>()];
31                    reader.read_exact(&mut buf)?;
32                    Ok(<$ty>::from_le_bytes(buf))
33                }
34            }
35        )*
36    };
37}
38
39impl_serialize_le!(i8, u8, i16, u16, i32, u32, i64, u64, f32, f64);
40
41// --- Serialization for Akar types ---
42
43impl Serialize for crate::types::InternalID {
44    fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
45        self.table_id.serialize(writer)?;
46        self.offset.serialize(writer)
47    }
48}
49
50impl Deserialize for crate::types::InternalID {
51    fn deserialize<R: Read>(reader: &mut R) -> std::io::Result<Self> {
52        let table_id = u64::deserialize(reader)?;
53        let offset = u64::deserialize(reader)?;
54        Ok(crate::types::InternalID { table_id, offset })
55    }
56}
57
58impl Serialize for crate::types::Date {
59    fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
60        self.0.serialize(writer)
61    }
62}
63
64impl Deserialize for crate::types::Date {
65    fn deserialize<R: Read>(reader: &mut R) -> std::io::Result<Self> {
66        Ok(crate::types::Date(i32::deserialize(reader)?))
67    }
68}
69
70impl Serialize for crate::types::Timestamp {
71    fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
72        self.0.serialize(writer)
73    }
74}
75
76impl Deserialize for crate::types::Timestamp {
77    fn deserialize<R: Read>(reader: &mut R) -> std::io::Result<Self> {
78        Ok(crate::types::Timestamp(i64::deserialize(reader)?))
79    }
80}
81
82impl Serialize for crate::types::Interval {
83    fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
84        self.months.serialize(writer)?;
85        self.days.serialize(writer)?;
86        self.micros.serialize(writer)
87    }
88}
89
90impl Deserialize for crate::types::Interval {
91    fn deserialize<R: Read>(reader: &mut R) -> std::io::Result<Self> {
92        let months = i32::deserialize(reader)?;
93        let days = i32::deserialize(reader)?;
94        let micros = i64::deserialize(reader)?;
95        Ok(crate::types::Interval { months, days, micros })
96    }
97}
98
99// --- VarInt encoding helpers for storage ---
100
101/// Encode a u64 using unsigned varint encoding (used for smaller storage).
102pub fn write_varint<W: Write>(writer: &mut W, mut value: u64) -> std::io::Result<()> {
103    loop {
104        if value < 0x80 {
105            writer.write_all(&[value as u8])?;
106            break;
107        } else {
108            writer.write_all(&[(value as u8) | 0x80])?;
109            value >>= 7;
110        }
111    }
112    Ok(())
113}
114
115/// Decode a u64 using unsigned varint encoding.
116pub fn read_varint<R: Read>(reader: &mut R) -> std::io::Result<u64> {
117    let mut result = 0u64;
118    let mut shift = 0;
119    loop {
120        let mut byte = [0u8];
121        reader.read_exact(&mut byte)?;
122        result |= ((byte[0] & 0x7F) as u64) << shift;
123        if byte[0] & 0x80 == 0 {
124            break;
125        }
126        shift += 7;
127    }
128    Ok(result)
129}
130
131#[cfg(test)]
132mod tests {
133    use super::*;
134    use crate::types::{Date, InternalID, Interval, Timestamp};
135
136    #[test]
137    fn test_serialize_primitive_roundtrip() {
138        let mut buf = Vec::new();
139        42i64.serialize(&mut buf).unwrap();
140        let val = i64::deserialize(&mut &buf[..]).unwrap();
141        assert_eq!(val, 42);
142    }
143
144    #[test]
145    fn test_serialize_u32_roundtrip() {
146        let mut buf = Vec::new();
147        12345u32.serialize(&mut buf).unwrap();
148        let val = u32::deserialize(&mut &buf[..]).unwrap();
149        assert_eq!(val, 12345);
150    }
151
152    #[test]
153    fn test_serialize_f64_roundtrip() {
154        let mut buf = Vec::new();
155        std::f64::consts::PI.serialize(&mut buf).unwrap();
156        let val = f64::deserialize(&mut &buf[..]).unwrap();
157        assert!((val - std::f64::consts::PI).abs() < 1e-10);
158    }
159
160    #[test]
161    fn test_serialize_internal_id() {
162        let id = InternalID {
163            table_id: 10,
164            offset: 42,
165        };
166        let mut buf = Vec::new();
167        id.serialize(&mut buf).unwrap();
168        let val = InternalID::deserialize(&mut &buf[..]).unwrap();
169        assert_eq!(val.table_id, 10);
170        assert_eq!(val.offset, 42);
171    }
172
173    #[test]
174    fn test_serialize_date() {
175        let d = Date(365);
176        let mut buf = Vec::new();
177        d.serialize(&mut buf).unwrap();
178        let val = Date::deserialize(&mut &buf[..]).unwrap();
179        assert_eq!(val, d);
180    }
181
182    #[test]
183    fn test_serialize_timestamp() {
184        let ts = Timestamp(1_700_000_000_000_000);
185        let mut buf = Vec::new();
186        ts.serialize(&mut buf).unwrap();
187        let val = Timestamp::deserialize(&mut &buf[..]).unwrap();
188        assert_eq!(val, ts);
189    }
190
191    #[test]
192    fn test_serialize_interval() {
193        let iv = Interval {
194            months: 12,
195            days: 30,
196            micros: 1_000_000,
197        };
198        let mut buf = Vec::new();
199        iv.serialize(&mut buf).unwrap();
200        let val = Interval::deserialize(&mut &buf[..]).unwrap();
201        assert_eq!(val.months, 12);
202        assert_eq!(val.days, 30);
203        assert_eq!(val.micros, 1_000_000);
204    }
205
206    #[test]
207    fn test_varint_roundtrip() {
208        let test_values = [0u64, 1, 127, 128, 255, 16383, 16384, 1_000_000, u64::MAX];
209        for &v in &test_values {
210            let mut buf = Vec::new();
211            write_varint(&mut buf, v).unwrap();
212            let val = read_varint(&mut &buf[..]).unwrap();
213            assert_eq!(val, v, "varint roundtrip failed for {v}");
214        }
215    }
216
217    #[test]
218    fn test_multi_value_serialization() {
219        let mut buf = Vec::new();
220        1i32.serialize(&mut buf).unwrap();
221        2.5f64.serialize(&mut buf).unwrap();
222
223        let mut reader = &buf[..];
224        assert_eq!(i32::deserialize(&mut reader).unwrap(), 1);
225        assert!((f64::deserialize(&mut reader).unwrap() - 2.5).abs() < 1e-10);
226    }
227}