1use crate::events_tree_nodes::{EventInternalNode, EventLeafNode, EventOverflowNode};
2use crate::free_lists_tree_nodes::{
3 FreeListInternalNode, FreeListLeafNode, FreeListTsnInternalNode, FreeListTsnLeafNode,
4};
5use crate::header_node::HeaderNode;
6use crate::tags_tree_nodes::{TagInternalNode, TagLeafNode, TagsInternalNode, TagsLeafNode};
7use umadb_dcb::{DCBError, DCBResult};
8
9const PAGE_TYPE_HEADER: u8 = b'1';
11const PAGE_TYPE_FREELIST_LEAF: u8 = b'2';
12const PAGE_TYPE_FREELIST_INTERNAL: u8 = b'3';
13const PAGE_TYPE_EVENT_LEAF: u8 = b'4';
14const PAGE_TYPE_EVENT_INTERNAL: u8 = b'5';
15const PAGE_TYPE_TAGS_LEAF: u8 = b'6';
16const PAGE_TYPE_TAGS_INTERNAL: u8 = b'7';
17const PAGE_TYPE_TAG_LEAF: u8 = b'8';
18const PAGE_TYPE_TAG_INTERNAL: u8 = b'9';
19const PAGE_TYPE_EVENT_OVERFLOW: u8 = b'a';
20const PAGE_TYPE_FREELIST_TSN_LEAF: u8 = b'b';
21const PAGE_TYPE_FREELIST_TSN_INTERNAL: u8 = b'c';
22
23#[derive(Debug, Clone, PartialEq, Eq)]
25pub enum Node {
26 Header(HeaderNode),
27 FreeListLeaf(FreeListLeafNode),
28 FreeListInternal(FreeListInternalNode),
29 EventLeaf(EventLeafNode),
30 EventInternal(EventInternalNode),
31 EventOverflow(EventOverflowNode),
32 TagsLeaf(TagsLeafNode),
33 TagsInternal(TagsInternalNode),
34 TagLeaf(TagLeafNode),
35 TagInternal(TagInternalNode),
36 FreeListTsnLeaf(FreeListTsnLeafNode),
37 FreeListTsnInternal(FreeListTsnInternalNode),
38}
39
40impl Node {
41 pub fn get_type_byte(&self) -> u8 {
42 match self {
43 Node::Header(_) => PAGE_TYPE_HEADER,
44 Node::FreeListLeaf(_) => PAGE_TYPE_FREELIST_LEAF,
45 Node::FreeListInternal(_) => PAGE_TYPE_FREELIST_INTERNAL,
46 Node::EventLeaf(_) => PAGE_TYPE_EVENT_LEAF,
47 Node::EventInternal(_) => PAGE_TYPE_EVENT_INTERNAL,
48 Node::EventOverflow(_) => PAGE_TYPE_EVENT_OVERFLOW,
49 Node::TagsLeaf(_) => PAGE_TYPE_TAGS_LEAF,
50 Node::TagsInternal(_) => PAGE_TYPE_TAGS_INTERNAL,
51 Node::TagLeaf(_) => PAGE_TYPE_TAG_LEAF,
52 Node::TagInternal(_) => PAGE_TYPE_TAG_INTERNAL,
53 Node::FreeListTsnLeaf(_) => PAGE_TYPE_FREELIST_TSN_LEAF,
54 Node::FreeListTsnInternal(_) => PAGE_TYPE_FREELIST_TSN_INTERNAL,
55 }
56 }
57
58 pub fn type_name(&self) -> &'static str {
59 match self {
60 Node::Header(_) => "Header",
61 Node::FreeListLeaf(_) => "FreeListLeaf",
62 Node::FreeListInternal(_) => "FreeListInternal",
63 Node::EventLeaf(_) => "EventLeaf",
64 Node::EventInternal(_) => "EventInternal",
65 Node::EventOverflow(_) => "EventOverflow",
66 Node::TagsLeaf(_) => "TagsLeaf",
67 Node::TagsInternal(_) => "TagsInternal",
68 Node::TagLeaf(_) => "TagLeaf",
69 Node::TagInternal(_) => "TagInternal",
70 Node::FreeListTsnLeaf(_) => "FreeListTsnLeaf",
71 Node::FreeListTsnInternal(_) => "FreeListTsnInternal",
72 }
73 }
74
75 pub fn calc_serialized_size(&self) -> usize {
76 match self {
77 Node::Header(_) => 48, Node::FreeListLeaf(node) => node.calc_serialized_size(),
79 Node::FreeListInternal(node) => node.calc_serialized_size(),
80 Node::EventLeaf(node) => node.calc_serialized_size(),
81 Node::EventInternal(node) => node.calc_serialized_size(),
82 Node::EventOverflow(node) => node.calc_serialized_size(),
83 Node::TagsLeaf(node) => node.calc_serialized_size(),
84 Node::TagsInternal(node) => node.calc_serialized_size(),
85 Node::TagLeaf(node) => node.calc_serialized_size(),
86 Node::TagInternal(node) => node.calc_serialized_size(),
87 Node::FreeListTsnLeaf(node) => node.calc_serialized_size(),
88 Node::FreeListTsnInternal(node) => node.calc_serialized_size(),
89 }
90 }
91
92 pub fn serialize_into(&self, buf: &mut [u8]) -> DCBResult<usize> {
96 match self {
97 Node::Header(node) => {
98 let n = node.serialize_into(buf);
99 Ok(n)
100 }
101 Node::FreeListLeaf(node) => {
102 let n = node.serialize_into(buf);
103 Ok(n)
104 }
105 Node::FreeListInternal(node) => {
106 let n = node.serialize_into(buf);
107 Ok(n)
108 }
109 Node::EventLeaf(node) => {
110 let n = node.serialize_into(buf);
111 Ok(n)
112 }
113 Node::EventInternal(node) => {
114 let n = node.serialize_into(buf)?;
115 Ok(n)
116 }
117 Node::EventOverflow(node) => {
118 let n = node.serialize_into(buf);
119 Ok(n)
120 }
121 Node::TagsLeaf(node) => {
122 let n = node.serialize_into(buf);
123 Ok(n)
124 }
125 Node::TagsInternal(node) => {
126 let n = node.serialize_into(buf);
127 Ok(n)
128 }
129 Node::TagLeaf(node) => {
130 let n = node.serialize_into(buf);
131 Ok(n)
132 }
133 Node::TagInternal(node) => {
134 let n = node.serialize_into(buf);
135 Ok(n)
136 }
137 Node::FreeListTsnLeaf(node) => {
138 let n = node.serialize_into(buf);
139 Ok(n)
140 }
141 Node::FreeListTsnInternal(node) => {
142 let n = node.serialize_into(buf);
143 Ok(n)
144 }
145 }
146 }
147
148 pub fn deserialize(node_type: u8, data: &[u8]) -> DCBResult<Self> {
149 match node_type {
150 PAGE_TYPE_HEADER => {
151 let node = HeaderNode::from_slice(data)?;
152 Ok(Node::Header(node))
153 }
154 PAGE_TYPE_FREELIST_LEAF => {
155 let node = FreeListLeafNode::from_slice(data)?;
156 Ok(Node::FreeListLeaf(node))
157 }
158 PAGE_TYPE_FREELIST_INTERNAL => {
159 let node = FreeListInternalNode::from_slice(data)?;
160 Ok(Node::FreeListInternal(node))
161 }
162 PAGE_TYPE_EVENT_LEAF => {
163 let node = EventLeafNode::from_slice(data)?;
164 Ok(Node::EventLeaf(node))
165 }
166 PAGE_TYPE_EVENT_INTERNAL => {
167 let node = EventInternalNode::from_slice(data)?;
168 Ok(Node::EventInternal(node))
169 }
170 PAGE_TYPE_EVENT_OVERFLOW => {
171 let node = EventOverflowNode::from_slice(data)?;
172 Ok(Node::EventOverflow(node))
173 }
174 PAGE_TYPE_TAGS_LEAF => {
175 let node = TagsLeafNode::from_slice(data)?;
176 Ok(Node::TagsLeaf(node))
177 }
178 PAGE_TYPE_TAGS_INTERNAL => {
179 let node = TagsInternalNode::from_slice(data)?;
180 Ok(Node::TagsInternal(node))
181 }
182 PAGE_TYPE_TAG_LEAF => {
183 let node = TagLeafNode::from_slice(data)?;
184 Ok(Node::TagLeaf(node))
185 }
186 PAGE_TYPE_TAG_INTERNAL => {
187 let node = TagInternalNode::from_slice(data)?;
188 Ok(Node::TagInternal(node))
189 }
190 PAGE_TYPE_FREELIST_TSN_LEAF => {
191 let node = FreeListTsnLeafNode::from_slice(data)?;
192 Ok(Node::FreeListTsnLeaf(node))
193 }
194 PAGE_TYPE_FREELIST_TSN_INTERNAL => {
195 let node = FreeListTsnInternalNode::from_slice(data)?;
196 Ok(Node::FreeListTsnInternal(node))
197 }
198 _ => Err(DCBError::DatabaseCorrupted(format!(
199 "Invalid node type: {node_type}"
200 ))),
201 }
202 }
203}