redb/
complex_types.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use crate::types::{TypeName, Value};

// Encode len as a varint and store it at the end of output
fn encode_varint_len(len: usize, output: &mut Vec<u8>) {
    if len < 254 {
        output.push(len.try_into().unwrap());
    } else if len <= u16::MAX.into() {
        let u16_len: u16 = len.try_into().unwrap();
        output.push(254);
        output.extend_from_slice(&u16_len.to_le_bytes())
    } else {
        assert!(len <= u32::MAX as usize);
        let u32_len: u32 = len.try_into().unwrap();
        output.push(255);
        output.extend_from_slice(&u32_len.to_le_bytes())
    }
}

// Decode a variable length int starting at the beginning of data
// Returns (decoded length, length consumed of `data`)
fn decode_varint_len(data: &[u8]) -> (usize, usize) {
    match data[0] {
        0..=253 => (data[0] as usize, 1),
        254 => (
            u16::from_le_bytes(data[1..3].try_into().unwrap()) as usize,
            3,
        ),
        255 => (
            u32::from_le_bytes(data[1..5].try_into().unwrap()) as usize,
            5,
        ),
    }
}

impl<T: Value> Value for Vec<T> {
    type SelfType<'a> = Vec<T::SelfType<'a>>
    where
        Self: 'a;
    type AsBytes<'a> = Vec<u8>
    where
        Self: 'a;

    fn fixed_width() -> Option<usize> {
        None
    }

    fn from_bytes<'a>(data: &'a [u8]) -> Vec<T::SelfType<'a>>
    where
        Self: 'a,
    {
        let (elements, mut offset) = decode_varint_len(data);
        let mut result = Vec::with_capacity(elements);
        for _ in 0..elements {
            let element_len = if let Some(len) = T::fixed_width() {
                len
            } else {
                let (len, consumed) = decode_varint_len(&data[offset..]);
                offset += consumed;
                len
            };
            result.push(T::from_bytes(&data[offset..(offset + element_len)]));
            offset += element_len;
        }
        assert_eq!(offset, data.len());
        result
    }

    fn as_bytes<'a, 'b: 'a>(value: &'a Vec<T::SelfType<'b>>) -> Vec<u8>
    where
        Self: 'a,
        Self: 'b,
    {
        let mut result = if let Some(width) = T::fixed_width() {
            Vec::with_capacity(value.len() * width + 5)
        } else {
            Vec::with_capacity(value.len() * 2 + 5)
        };
        encode_varint_len(value.len(), &mut result);

        for element in value.iter() {
            let serialized = T::as_bytes(element);
            if T::fixed_width().is_none() {
                encode_varint_len(serialized.as_ref().len(), &mut result);
            }
            result.extend_from_slice(serialized.as_ref());
        }
        result
    }

    fn type_name() -> TypeName {
        TypeName::internal(&format!("Vec<{}>", T::type_name().name()))
    }
}