umadb_core/
header_node.rs1use crate::common::Position;
2use crate::common::{PageID, Tsn};
3use byteorder::{ByteOrder, LittleEndian};
4use umadb_dcb::{DCBError, DCBResult};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct HeaderNode {
9 pub tsn: Tsn,
10 pub free_lists_tree_root_id: PageID,
11 pub events_tree_root_id: PageID,
12 pub tags_tree_root_id: PageID,
13 pub next_page_id: PageID,
14 pub next_position: Position,
15}
16
17impl HeaderNode {
18 pub fn default() -> Self {
19 Self {
20 tsn: Tsn(0),
21 free_lists_tree_root_id: PageID(0),
22 events_tree_root_id: PageID(0),
23 tags_tree_root_id: PageID(0),
24 next_page_id: PageID(0),
25 next_position: Position(0),
26 }
27 }
28
29 pub fn serialize_into(&self, buf: &mut [u8]) -> usize {
32 assert!(
33 buf.len() >= 48,
34 "HeaderNode::serialize_into dst must be at least 48 bytes"
35 );
36 buf[0..8].copy_from_slice(&self.tsn.0.to_le_bytes());
38 buf[8..16].copy_from_slice(&self.next_page_id.0.to_le_bytes());
39 buf[16..24].copy_from_slice(&self.free_lists_tree_root_id.0.to_le_bytes());
40 buf[24..32].copy_from_slice(&self.events_tree_root_id.0.to_le_bytes());
41 buf[32..40].copy_from_slice(&self.tags_tree_root_id.0.to_le_bytes());
42 buf[40..48].copy_from_slice(&self.next_position.0.to_le_bytes());
43 48
44 }
45
46 pub fn from_slice(slice: &[u8]) -> DCBResult<Self> {
61 if slice.len() != 48 {
62 return Err(DCBError::DeserializationError(format!(
63 "Expected 48 bytes, got {}",
64 slice.len()
65 )));
66 }
67
68 let tsn = LittleEndian::read_u64(&slice[0..8]);
69 let next_page_id = LittleEndian::read_u64(&slice[8..16]);
70 let freetree_root_id = LittleEndian::read_u64(&slice[16..24]);
71 let position_root_id = LittleEndian::read_u64(&slice[24..32]);
72 let tags_root_id = LittleEndian::read_u64(&slice[32..40]);
73 let next_position = LittleEndian::read_u64(&slice[40..48]);
74
75 Ok(HeaderNode {
76 tsn: Tsn(tsn),
77 next_page_id: PageID(next_page_id),
78 free_lists_tree_root_id: PageID(freetree_root_id),
79 events_tree_root_id: PageID(position_root_id),
80 tags_tree_root_id: PageID(tags_root_id),
81 next_position: Position(next_position),
82 })
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 #[test]
90 fn test_header_serialize() {
91 let header_node = HeaderNode {
93 tsn: Tsn(42),
94 next_page_id: PageID(123),
95 free_lists_tree_root_id: PageID(456),
96 events_tree_root_id: PageID(789),
97 tags_tree_root_id: PageID(321),
98 next_position: Position(9876543210),
99 };
100
101 let mut serialized = [0u8; 48];
103 header_node.serialize_into(&mut serialized);
104
105 assert_eq!(48, serialized.len());
107
108 assert_eq!(&42u64.to_le_bytes(), &serialized[0..8]);
111
112 assert_eq!(&123u64.to_le_bytes(), &serialized[8..16]);
114
115 assert_eq!(&456u64.to_le_bytes(), &serialized[16..24]);
117
118 assert_eq!(&789u64.to_le_bytes(), &serialized[24..32]);
120
121 assert_eq!(&321u64.to_le_bytes(), &serialized[32..40]);
123
124 assert_eq!(&9876543210u64.to_le_bytes(), &serialized[40..48]);
126
127 let deserialized =
129 HeaderNode::from_slice(&serialized).expect("Failed to deserialize HeaderNode");
130
131 assert_eq!(header_node.tsn, deserialized.tsn);
133 assert_eq!(header_node.next_page_id, deserialized.next_page_id);
134 assert_eq!(
135 header_node.free_lists_tree_root_id,
136 deserialized.free_lists_tree_root_id
137 );
138 assert_eq!(
139 header_node.events_tree_root_id,
140 deserialized.events_tree_root_id
141 );
142 assert_eq!(header_node.next_position, deserialized.next_position);
143 }
144}