aboutsummaryrefslogtreecommitdiffstats
path: root/log_db/src/row.rs
blob: d8140d29756a304acdbc2b6ff08db0e0e2c2226c (plain)
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
use super::*;

#[derive(Debug, Clone)]
pub struct Row {
    pub values: Vec<Value>,
    pub tombstone: bool,
}

impl Row {
    pub fn serialize(&self) -> Vec<u8> {
        let mut bytes = Vec::new();

        if self.tombstone {
            bytes.extend(&[B_TOMBSTONE]);
        } else {
            bytes.extend(&[B_LIVE]);
        }

        for value in &self.values {
            bytes.extend(value.serialize());
        }
        bytes
    }

    pub fn deserialize(bytes: &[u8]) -> Row {
        assert!(bytes.len() > 0);

        let mut values = Vec::new();

        let tombstone = bytes[0] == B_TOMBSTONE;

        let mut start = 1;
        while start < bytes.len() {
            let (rv, consumed) = Value::deserialize(&bytes[start..]);
            values.push(rv);
            start += consumed;
        }
        Row { values, tombstone }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_record_serialize_deserialize() {
        let record = Row {
            values: vec![
                Value::Int(1),
                Value::String("hello".to_string()),
                Value::Bytes(vec![0, 1, 2, 3]),
            ],
            tombstone: true,
        };

        let serialized = record.serialize();
        let deserialized = Row::deserialize(&serialized);
        let reserialized = deserialized.serialize();

        assert_eq!(serialized.len(), reserialized.len());
        assert_eq!(record.values, deserialized.values);
    }
}

#[derive(Clone, Debug)]
pub enum TxEntry {
    Upsert { row: Row },
    Delete { row: Row },
}