1use crate::common::PageID;
2use crate::common::Position;
3use bitflags::bitflags;
4use byteorder::{ByteOrder, LittleEndian};
5use umadb_dcb::DCBError;
6use umadb_dcb::DCBResult;
7use uuid::Uuid;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct EventRecord {
11 pub event_type: String,
12 pub data: Vec<u8>,
13 pub tags: Vec<String>,
14 pub uuid: Option<Uuid>,
15}
16
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub enum EventValue {
19 Inline(EventRecord),
20 Overflow {
22 event_type: String,
23 data_len: u64,
24 tags: Vec<String>,
25 root_id: PageID,
26 uuid: Option<Uuid>,
27 },
28}
29
30impl PartialEq<EventValue> for EventRecord {
31 fn eq(&self, other: &EventValue) -> bool {
32 match other {
33 EventValue::Inline(rec) => self == rec,
34 EventValue::Overflow {
35 event_type,
36 data_len,
37 tags,
38 ..
39 } => {
40 &self.event_type == event_type
41 && &self.tags == tags
42 && (self.data.len() as u64) == *data_len
43 }
44 }
45 }
46}
47
48impl PartialEq<EventRecord> for EventValue {
49 fn eq(&self, other: &EventRecord) -> bool {
50 other == self
51 }
52}
53
54bitflags! {
55 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
56 pub struct EventValueFlags: u8 {
57 const OVERFLOW = 0b0000_0001; const HAS_UUID = 0b0000_0010; }
60}
61
62#[derive(Debug, Clone, PartialEq, Eq)]
63pub struct EventLeafNode {
64 pub keys: Vec<Position>,
65 pub values: Vec<EventValue>,
66}
67
68impl EventLeafNode {
69 pub fn calc_serialized_size(&self) -> usize {
70 let mut total_size = 2;
72
73 total_size += self.keys.len() * 8;
75
76 for value in &self.values {
78 total_size += 1;
80 match value {
81 EventValue::Inline(rec) => {
82 total_size += 2 + rec.event_type.len();
84 total_size += 2 + rec.data.len();
86 total_size += 2;
88 for tag in &rec.tags {
90 total_size += 2 + tag.len();
91 }
92 if rec.uuid.is_some() {
93 total_size += 16;
94 }
95 }
96 EventValue::Overflow {
97 event_type,
98 data_len: _,
99 tags,
100 root_id: _,
101 uuid,
102 } => {
103 total_size += 2 + event_type.len();
105 total_size += 8;
107 total_size += 2;
109 for tag in tags {
111 total_size += 2 + tag.len();
112 }
113 total_size += 8;
115 if uuid.is_some() {
116 total_size += 16;
117 }
118 }
119 }
120 }
121
122 total_size
123 }
124
125 pub fn serialize_into(&self, buf: &mut [u8]) -> usize {
127 let mut i = 0usize;
128 let klen = self.keys.len() as u16;
130 buf[i..i + 2].copy_from_slice(&klen.to_le_bytes());
131 i += 2;
132 for key in &self.keys {
134 let b = key.0.to_le_bytes();
135 buf[i..i + 8].copy_from_slice(&b);
136 i += 8;
137 }
138 for value in &self.values {
140 let mut flags = EventValueFlags::empty();
141 match value {
142 EventValue::Inline(rec) => {
143 if rec.uuid.is_some() {
144 flags |= EventValueFlags::HAS_UUID;
145 }
146 buf[i] = flags.bits();
147 i += 1;
148 let et_len = rec.event_type.len() as u16;
149 buf[i..i + 2].copy_from_slice(&et_len.to_le_bytes());
150 i += 2;
151 let s = rec.event_type.as_bytes();
152 buf[i..i + s.len()].copy_from_slice(s);
153 i += s.len();
154 let dlen = rec.data.len() as u16;
155 buf[i..i + 2].copy_from_slice(&dlen.to_le_bytes());
156 i += 2;
157 buf[i..i + rec.data.len()].copy_from_slice(&rec.data);
158 i += rec.data.len();
159 let tlen = rec.tags.len() as u16;
160 buf[i..i + 2].copy_from_slice(&tlen.to_le_bytes());
161 i += 2;
162 for tag in &rec.tags {
163 let tl = tag.len() as u16;
164 buf[i..i + 2].copy_from_slice(&tl.to_le_bytes());
165 i += 2;
166 let tb = tag.as_bytes();
167 buf[i..i + tb.len()].copy_from_slice(tb);
168 i += tb.len();
169 }
170 if let Some(uuid) = rec.uuid {
171 buf[i..i + 16].copy_from_slice(uuid.as_bytes());
172 i += 16;
173 }
174 }
175 EventValue::Overflow {
176 event_type,
177 data_len,
178 tags,
179 root_id,
180 uuid,
181 } => {
182 flags |= EventValueFlags::OVERFLOW;
183 if uuid.is_some() {
184 flags |= EventValueFlags::HAS_UUID;
185 }
186 buf[i] = flags.bits();
187 i += 1;
188 let et_len = event_type.len() as u16;
189 buf[i..i + 2].copy_from_slice(&et_len.to_le_bytes());
190 i += 2;
191 let s = event_type.as_bytes();
192 buf[i..i + s.len()].copy_from_slice(s);
193 i += s.len();
194 buf[i..i + 8].copy_from_slice(&data_len.to_le_bytes());
195 i += 8;
196 let tlen = tags.len() as u16;
197 buf[i..i + 2].copy_from_slice(&tlen.to_le_bytes());
198 i += 2;
199 for tag in tags {
200 let tl = tag.len() as u16;
201 buf[i..i + 2].copy_from_slice(&tl.to_le_bytes());
202 i += 2;
203 let tb = tag.as_bytes();
204 buf[i..i + tb.len()].copy_from_slice(tb);
205 i += tb.len();
206 }
207 buf[i..i + 8].copy_from_slice(&root_id.0.to_le_bytes());
208 i += 8;
209 if uuid.is_some() {
210 buf[i..i + 16].copy_from_slice(uuid.unwrap().as_bytes());
211 i += 16;
212 }
213 }
214 }
215 }
216 i
217 }
218
219 pub fn from_slice(slice: &[u8]) -> DCBResult<Self> {
220 if slice.len() < 2 {
222 return Err(DCBError::DeserializationError(format!(
223 "Expected at least 2 bytes, got {}",
224 slice.len()
225 )));
226 }
227
228 let keys_len = LittleEndian::read_u16(&slice[0..2]) as usize;
230
231 let min_expected_size = 2 + (keys_len * 8);
233 if slice.len() < min_expected_size {
234 return Err(DCBError::DeserializationError(format!(
235 "Expected at least {} bytes for keys, got {}",
236 min_expected_size,
237 slice.len()
238 )));
239 }
240
241 let mut keys = Vec::with_capacity(keys_len);
243 for i in 0..keys_len {
244 let start = 2 + (i * 8);
245 let position = LittleEndian::read_u64(&slice[start..start + 8]);
246 keys.push(Position(position));
247 }
248
249 let mut values = Vec::with_capacity(keys_len);
251 let mut offset = 2 + (keys_len * 8);
252
253 for _ in 0..keys_len {
254 if offset + 1 > slice.len() {
256 return Err(DCBError::DeserializationError(
257 "Unexpected end of data while reading value kind".to_string(),
258 ));
259 }
260
261 let flags = EventValueFlags::from_bits(slice[offset]).ok_or(
262 DCBError::DeserializationError("unknown flag bits set".to_string()),
263 )?;
264 offset += 1;
265
266 if offset + 2 > slice.len() {
268 return Err(DCBError::DeserializationError(
269 "Unexpected end of data while reading event_type length".to_string(),
270 ));
271 }
272 let event_type_len = LittleEndian::read_u16(&slice[offset..offset + 2]) as usize;
273 offset += 2;
274 if offset + event_type_len > slice.len() {
275 return Err(DCBError::DeserializationError(
276 "Unexpected end of data while reading event_type".to_string(),
277 ));
278 }
279 let event_type = match std::str::from_utf8(&slice[offset..offset + event_type_len]) {
280 Ok(s) => s.to_string(),
281 Err(_) => {
282 return Err(DCBError::DeserializationError(
283 "Invalid UTF-8 sequence in event_type".to_string(),
284 ));
285 }
286 };
287 offset += event_type_len;
288
289 let overflow = flags.contains(EventValueFlags::OVERFLOW);
290 let has_uuid = flags.contains(EventValueFlags::HAS_UUID);
291
292 if !overflow {
293 if offset + 2 > slice.len() {
295 return Err(DCBError::DeserializationError(
296 "Unexpected end of data while reading data length".to_string(),
297 ));
298 }
299 let data_len = LittleEndian::read_u16(&slice[offset..offset + 2]) as usize;
300 offset += 2;
301 if offset + data_len > slice.len() {
302 return Err(DCBError::DeserializationError(
303 "Unexpected end of data while reading data".to_string(),
304 ));
305 }
306 let data = slice[offset..offset + data_len].to_vec();
307 offset += data_len;
308
309 if offset + 2 > slice.len() {
311 return Err(DCBError::DeserializationError(
312 "Unexpected end of data while reading number of tags".to_string(),
313 ));
314 }
315 let num_tags = LittleEndian::read_u16(&slice[offset..offset + 2]) as usize;
316 offset += 2;
317 let mut tags = Vec::with_capacity(num_tags);
318 for _ in 0..num_tags {
319 if offset + 2 > slice.len() {
320 return Err(DCBError::DeserializationError(
321 "Unexpected end of data while reading tag length".to_string(),
322 ));
323 }
324 let tag_len = LittleEndian::read_u16(&slice[offset..offset + 2]) as usize;
325 offset += 2;
326 if offset + tag_len > slice.len() {
327 return Err(DCBError::DeserializationError(
328 "Unexpected end of data while reading tag".to_string(),
329 ));
330 }
331 let tag = match std::str::from_utf8(&slice[offset..offset + tag_len]) {
332 Ok(s) => s.to_string(),
333 Err(_) => {
334 return Err(DCBError::DeserializationError(
335 "Invalid UTF-8 sequence in tag".to_string(),
336 ));
337 }
338 };
339 offset += tag_len;
340 tags.push(tag);
341 }
342
343 let uuid = {
344 if has_uuid {
345 if offset + 16 > slice.len() {
346 return Err(DCBError::DeserializationError(
347 "Unexpected end of data while reading UUID".to_string(),
348 ));
349 }
350
351 match Uuid::from_slice(&slice[offset..offset + 16]) {
352 Ok(uuid) => {
353 offset += 16;
354 Some(uuid)
355 }
356 Err(err) => {
357 return Err(DCBError::DeserializationError(
358 format!("Invalid UUID sequence: {err} ").to_string(),
359 ));
360 }
361 }
362 } else {
363 None
364 }
365 };
366
367 values.push(EventValue::Inline(EventRecord {
368 event_type,
369 data,
370 tags,
371 uuid,
372 }));
373 } else {
374 if offset + 8 > slice.len() {
376 return Err(DCBError::DeserializationError(
377 "Unexpected end of data while reading overflow data_len".to_string(),
378 ));
379 }
380 let data_len = LittleEndian::read_u64(&slice[offset..offset + 8]);
381 offset += 8;
382
383 if offset + 2 > slice.len() {
384 return Err(DCBError::DeserializationError(
385 "Unexpected end of data while reading number of tags".to_string(),
386 ));
387 }
388 let num_tags = LittleEndian::read_u16(&slice[offset..offset + 2]) as usize;
389 offset += 2;
390 let mut tags = Vec::with_capacity(num_tags);
391 for _ in 0..num_tags {
392 if offset + 2 > slice.len() {
393 return Err(DCBError::DeserializationError(
394 "Unexpected end of data while reading tag length".to_string(),
395 ));
396 }
397 let tag_len = LittleEndian::read_u16(&slice[offset..offset + 2]) as usize;
398 offset += 2;
399 if offset + tag_len > slice.len() {
400 return Err(DCBError::DeserializationError(
401 "Unexpected end of data while reading tag".to_string(),
402 ));
403 }
404 let tag = match std::str::from_utf8(&slice[offset..offset + tag_len]) {
405 Ok(s) => s.to_string(),
406 Err(_) => {
407 return Err(DCBError::DeserializationError(
408 "Invalid UTF-8 sequence in tag".to_string(),
409 ));
410 }
411 };
412 offset += tag_len;
413 tags.push(tag);
414 }
415 if offset + 8 > slice.len() {
416 return Err(DCBError::DeserializationError(
417 "Unexpected end of data while reading overflow root_id".to_string(),
418 ));
419 }
420 let root_id = PageID(LittleEndian::read_u64(&slice[offset..offset + 8]));
421 offset += 8;
422
423 let uuid = {
424 if has_uuid {
425 if offset + 16 > slice.len() {
426 return Err(DCBError::DeserializationError(
427 "Unexpected end of data while reading UUID".to_string(),
428 ));
429 }
430
431 match Uuid::from_slice(&slice[offset..offset + 16]) {
432 Ok(uuid) => {
433 offset += 16;
434 Some(uuid)
435 }
436 Err(err) => {
437 return Err(DCBError::DeserializationError(
438 format!("Invalid UUID sequence: {err} ").to_string(),
439 ));
440 }
441 }
442 } else {
443 None
444 }
445 };
446
447 values.push(EventValue::Overflow {
448 event_type,
449 data_len,
450 tags,
451 root_id,
452 uuid,
453 });
454 }
455 }
456
457 Ok(EventLeafNode { keys, values })
458 }
459
460 pub fn pop_last_key_and_value(&mut self) -> DCBResult<(Position, EventValue)> {
461 let last_key = self
462 .keys
463 .pop()
464 .expect("EventLeafNode should have some keys");
465 let last_value = self
466 .values
467 .pop()
468 .expect("EventLeafNode should have some values");
469 Ok((last_key, last_value))
470 }
471}
472
473#[derive(Debug, Clone, PartialEq, Eq)]
474pub struct EventOverflowNode {
475 pub next: PageID, pub data: Vec<u8>,
477}
478
479impl EventOverflowNode {
480 pub fn calc_serialized_size(&self) -> usize {
481 8 + self.data.len()
483 }
484
485 pub fn serialize_into(&self, buf: &mut [u8]) -> usize {
486 let size = self.calc_serialized_size();
487 buf[0..8].copy_from_slice(&self.next.0.to_le_bytes());
488 buf[8..size].copy_from_slice(&self.data);
489 size
490 }
491
492 pub fn from_slice(slice: &[u8]) -> DCBResult<Self> {
493 if slice.len() < 8 {
494 return Err(DCBError::DeserializationError(
495 "Overflow node too small".to_string(),
496 ));
497 }
498 let next = PageID(LittleEndian::read_u64(&slice[0..8]));
499 let data = slice[8..].to_vec();
500 Ok(Self { next, data })
501 }
502}
503
504#[derive(Debug, Clone, PartialEq, Eq)]
505pub struct EventInternalNode {
506 pub keys: Vec<Position>,
507 pub child_ids: Vec<PageID>,
508}
509
510impl EventInternalNode {
511 pub fn calc_serialized_size(&self) -> usize {
512 let mut total_size = 2;
514
515 total_size += self.keys.len() * 8;
517
518 total_size += self.child_ids.len() * 8;
520
521 total_size
522 }
523
524 pub fn serialize_into(&self, buf: &mut [u8]) -> DCBResult<usize> {
525 let mut i = 0usize;
526 let klen = self.keys.len() as u16;
527 buf[i..i + 2].copy_from_slice(&klen.to_le_bytes());
528 i += 2;
529 for key in &self.keys {
530 buf[i..i + 8].copy_from_slice(&key.0.to_le_bytes());
531 i += 8;
532 }
533 for child_id in &self.child_ids {
534 buf[i..i + 8].copy_from_slice(&child_id.0.to_le_bytes());
535 i += 8;
536 }
537 Ok(i)
538 }
539
540 pub fn from_slice(slice: &[u8]) -> DCBResult<Self> {
541 if slice.len() < 2 {
543 return Err(DCBError::DeserializationError(format!(
544 "Expected at least 2 bytes, got {}",
545 slice.len()
546 )));
547 }
548
549 let keys_len = LittleEndian::read_u16(&slice[0..2]) as usize;
551
552 let min_expected_size = 2 + (keys_len * 8);
554 if slice.len() < min_expected_size {
555 return Err(DCBError::DeserializationError(format!(
556 "Expected at least {} bytes for keys, got {}",
557 min_expected_size,
558 slice.len()
559 )));
560 }
561
562 let mut keys = Vec::with_capacity(keys_len);
564 for i in 0..keys_len {
565 let start = 2 + (i * 8);
566 let position = LittleEndian::read_u64(&slice[start..start + 8]);
567 keys.push(Position(position));
568 }
569
570 let offset = 2 + (keys_len * 8);
572
573 let child_ids_len = keys_len + 1;
575
576 let min_expected_size = offset + (child_ids_len * 8);
578 if slice.len() < min_expected_size {
579 return Err(DCBError::DeserializationError(format!(
580 "Expected at least {} bytes for child_ids, got {}",
581 min_expected_size,
582 slice.len()
583 )));
584 }
585
586 let mut child_ids = Vec::with_capacity(child_ids_len);
588 for i in 0..child_ids_len {
589 let start = offset + (i * 8);
590 let page_id = LittleEndian::read_u64(&slice[start..start + 8]);
591 child_ids.push(PageID(page_id));
592 }
593
594 Ok(EventInternalNode { keys, child_ids })
595 }
596 pub fn replace_last_child_id(&mut self, old_id: PageID, new_id: PageID) -> DCBResult<()> {
597 let last_idx = self.child_ids.len() - 1;
599 if self.child_ids[last_idx] == old_id {
600 self.child_ids[last_idx] = new_id;
601 } else {
602 return Err(DCBError::DatabaseCorrupted("Child ID mismatch".to_string()));
603 }
604 Ok(())
605 }
606 pub fn append_promoted_key_and_page_id(
607 &mut self,
608 promoted_key: Position,
609 promoted_page_id: PageID,
610 ) -> DCBResult<()> {
611 self.keys.push(promoted_key);
612 self.child_ids.push(promoted_page_id);
613 Ok(())
614 }
615 pub fn split_off(&mut self) -> DCBResult<(Position, Vec<Position>, Vec<PageID>)> {
616 let middle_idx = self.keys.len() - 2;
617 let promoted_key = self.keys.remove(middle_idx);
618 let new_keys = self.keys.split_off(middle_idx);
619 let new_child_ids = self.child_ids.split_off(middle_idx + 1);
620 Ok((promoted_key, new_keys, new_child_ids))
621 }
622}
623
624#[cfg(test)]
625mod tests {
626 use super::*;
627
628 #[test]
629 fn test_event_internal_serialize() {
630 let internal_node = EventInternalNode {
632 keys: vec![Position(1000), Position(2000), Position(3000)],
633 child_ids: vec![PageID(100), PageID(200), PageID(300), PageID(400)],
634 };
635
636 let mut serialized = vec![0u8; internal_node.calc_serialized_size()];
638 internal_node.serialize_into(&mut serialized).unwrap();
639
640 assert!(!serialized.is_empty());
642
643 let deserialized = EventInternalNode::from_slice(&serialized)
645 .expect("Failed to deserialize EventInternalNode");
646
647 assert_eq!(internal_node, deserialized);
649
650 assert_eq!(3, deserialized.keys.len());
652 assert_eq!(4, deserialized.child_ids.len());
653
654 assert_eq!(Position(1000), deserialized.keys[0]);
656 assert_eq!(Position(2000), deserialized.keys[1]);
657 assert_eq!(Position(3000), deserialized.keys[2]);
658
659 assert_eq!(PageID(100), deserialized.child_ids[0]);
661 assert_eq!(PageID(200), deserialized.child_ids[1]);
662 assert_eq!(PageID(300), deserialized.child_ids[2]);
663 assert_eq!(PageID(400), deserialized.child_ids[3]);
664 }
665
666 #[test]
667 fn test_event_leaf_serialize_without_uuid() {
668 let leaf_node = EventLeafNode {
670 keys: vec![Position(1000), Position(2000), Position(3000)],
671 values: vec![
672 EventValue::Inline(EventRecord {
673 event_type: "event_type_1".to_string(),
674 data: vec![1, 0, 0, 0], tags: vec!["tag1".to_string(), "tag2".to_string(), "tag3".to_string()],
676 uuid: None,
677 }),
678 EventValue::Inline(EventRecord {
679 event_type: "event_type_2".to_string(),
680 data: vec![2, 0, 0, 0], tags: vec![
682 "tag4".to_string(),
683 "tag5".to_string(),
684 "tag6".to_string(),
685 "tag7".to_string(),
686 ],
687 uuid: None,
688 }),
689 EventValue::Inline(EventRecord {
690 event_type: "event_type_3".to_string(),
691 data: vec![3, 0, 0, 0], tags: vec!["tag8".to_string(), "tag9".to_string()],
693 uuid: None,
694 }),
695 ],
696 };
697
698 let mut serialized = vec![0u8; leaf_node.calc_serialized_size()];
700 leaf_node.serialize_into(&mut serialized);
701
702 assert!(!serialized.is_empty());
704
705 let deserialized =
707 EventLeafNode::from_slice(&serialized).expect("Failed to deserialize EventLeafNode");
708
709 assert_eq!(leaf_node, deserialized);
711
712 assert_eq!(3, deserialized.keys.len());
714 assert_eq!(3, deserialized.values.len());
715
716 assert_eq!(Position(1000), deserialized.keys[0]);
718 assert_eq!(Position(2000), deserialized.keys[1]);
719 assert_eq!(Position(3000), deserialized.keys[2]);
720
721 match &deserialized.values[0] {
723 EventValue::Inline(v) => {
724 assert_eq!("event_type_1", v.event_type);
725 assert_eq!(vec![1, 0, 0, 0], v.data);
726 assert_eq!(
727 vec!["tag1".to_string(), "tag2".to_string(), "tag3".to_string()],
728 v.tags
729 );
730 assert_eq!(None, v.uuid);
731 }
732 _ => panic!("Expected Inline for first value"),
733 }
734
735 match &deserialized.values[1] {
737 EventValue::Inline(v) => {
738 assert_eq!("event_type_2", v.event_type);
739 assert_eq!(vec![2, 0, 0, 0], v.data);
740 assert_eq!(
741 vec![
742 "tag4".to_string(),
743 "tag5".to_string(),
744 "tag6".to_string(),
745 "tag7".to_string()
746 ],
747 v.tags
748 );
749 assert_eq!(None, v.uuid);
750 }
751 _ => panic!("Expected Inline for second value"),
752 }
753
754 match &deserialized.values[2] {
756 EventValue::Inline(v) => {
757 assert_eq!("event_type_3", v.event_type);
758 assert_eq!(vec![3, 0, 0, 0], v.data);
759 assert_eq!(vec!["tag8".to_string(), "tag9".to_string()], v.tags);
760 assert_eq!(None, v.uuid);
761 }
762 _ => panic!("Expected Inline for third value"),
763 }
764 }
765
766 #[test]
767 fn test_event_leaf_serialize_with_uuid() {
768 let uuid1 = Uuid::new_v4();
770 let uuid2 = Uuid::new_v4();
771 let uuid3 = Uuid::new_v4();
772 let leaf_node = EventLeafNode {
773 keys: vec![Position(1000), Position(2000), Position(3000)],
774 values: vec![
775 EventValue::Inline(EventRecord {
776 event_type: "event_type_1".to_string(),
777 data: vec![1, 0, 0, 0], tags: vec!["tag1".to_string(), "tag2".to_string(), "tag3".to_string()],
779 uuid: Some(uuid1),
780 }),
781 EventValue::Inline(EventRecord {
782 event_type: "event_type_2".to_string(),
783 data: vec![2, 0, 0, 0], tags: vec![
785 "tag4".to_string(),
786 "tag5".to_string(),
787 "tag6".to_string(),
788 "tag7".to_string(),
789 ],
790 uuid: Some(uuid2),
791 }),
792 EventValue::Inline(EventRecord {
793 event_type: "event_type_3".to_string(),
794 data: vec![3, 0, 0, 0], tags: vec!["tag8".to_string(), "tag9".to_string()],
796 uuid: Some(uuid3),
797 }),
798 ],
799 };
800
801 let mut serialized = vec![0u8; leaf_node.calc_serialized_size()];
803 leaf_node.serialize_into(&mut serialized);
804
805 assert!(!serialized.is_empty());
807
808 let deserialized =
810 EventLeafNode::from_slice(&serialized).expect("Failed to deserialize EventLeafNode");
811
812 assert_eq!(leaf_node, deserialized);
814
815 assert_eq!(3, deserialized.keys.len());
817 assert_eq!(3, deserialized.values.len());
818
819 assert_eq!(Position(1000), deserialized.keys[0]);
821 assert_eq!(Position(2000), deserialized.keys[1]);
822 assert_eq!(Position(3000), deserialized.keys[2]);
823
824 match &deserialized.values[0] {
826 EventValue::Inline(v) => {
827 assert_eq!("event_type_1", v.event_type);
828 assert_eq!(vec![1, 0, 0, 0], v.data);
829 assert_eq!(
830 vec!["tag1".to_string(), "tag2".to_string(), "tag3".to_string()],
831 v.tags
832 );
833 assert_eq!(Some(uuid1), v.uuid);
834 }
835 _ => panic!("Expected Inline for first value"),
836 }
837
838 match &deserialized.values[1] {
840 EventValue::Inline(v) => {
841 assert_eq!("event_type_2", v.event_type);
842 assert_eq!(vec![2, 0, 0, 0], v.data);
843 assert_eq!(
844 vec![
845 "tag4".to_string(),
846 "tag5".to_string(),
847 "tag6".to_string(),
848 "tag7".to_string()
849 ],
850 v.tags
851 );
852 assert_eq!(Some(uuid2), v.uuid);
853 }
854 _ => panic!("Expected Inline for second value"),
855 }
856
857 match &deserialized.values[2] {
859 EventValue::Inline(v) => {
860 assert_eq!("event_type_3", v.event_type);
861 assert_eq!(vec![3, 0, 0, 0], v.data);
862 assert_eq!(vec!["tag8".to_string(), "tag9".to_string()], v.tags);
863 assert_eq!(Some(uuid3), v.uuid);
864 }
865 _ => panic!("Expected Inline for third value"),
866 }
867 }
868
869 #[test]
870 fn test_event_leaf_serialize_with_overflow_single_without_uuid() {
871 let leaf_node = EventLeafNode {
872 keys: vec![Position(111)],
873 values: vec![EventValue::Overflow {
874 event_type: "over_evt".to_string(),
875 data_len: 1234567,
876 tags: vec!["a".to_string(), "b".to_string()],
877 root_id: PageID(123),
878 uuid: None,
879 }],
880 };
881 let mut serialized = vec![0u8; leaf_node.calc_serialized_size()];
883 leaf_node.serialize_into(&mut serialized);
884 assert!(!serialized.is_empty());
885 let deserialized = EventLeafNode::from_slice(&serialized)
887 .expect("Failed to deserialize EventLeafNode with overflow");
888 assert_eq!(leaf_node, deserialized);
889
890 assert_eq!(1, deserialized.keys.len());
892 assert_eq!(Position(111), deserialized.keys[0]);
893 assert_eq!(1, deserialized.values.len());
894 match &deserialized.values[0] {
895 EventValue::Overflow {
896 event_type,
897 data_len,
898 tags,
899 root_id,
900 uuid,
901 } => {
902 assert_eq!("over_evt", event_type);
903 assert_eq!(1234567, *data_len);
904 assert_eq!(vec!["a".to_string(), "b".to_string()], *tags);
905 assert_eq!(PageID(123), *root_id);
906 assert_eq!(None, *uuid);
907 }
908 _ => panic!("Expected Overflow variant"),
909 }
910 }
911
912 #[test]
913 fn test_event_leaf_serialize_with_overflow_single_with_uuid() {
914 let uuid1 = Uuid::new_v4();
915 let leaf_node = EventLeafNode {
916 keys: vec![Position(111)],
917 values: vec![EventValue::Overflow {
918 event_type: "over_evt".to_string(),
919 data_len: 1234567,
920 tags: vec!["a".to_string(), "b".to_string()],
921 root_id: PageID(123),
922 uuid: Some(uuid1),
923 }],
924 };
925 let mut serialized = vec![0u8; leaf_node.calc_serialized_size()];
927 leaf_node.serialize_into(&mut serialized);
928 assert!(!serialized.is_empty());
929 let deserialized = EventLeafNode::from_slice(&serialized)
931 .expect("Failed to deserialize EventLeafNode with overflow");
932 assert_eq!(leaf_node, deserialized);
933
934 assert_eq!(1, deserialized.keys.len());
936 assert_eq!(Position(111), deserialized.keys[0]);
937 assert_eq!(1, deserialized.values.len());
938 match &deserialized.values[0] {
939 EventValue::Overflow {
940 event_type,
941 data_len,
942 tags,
943 root_id,
944 uuid,
945 } => {
946 assert_eq!("over_evt", event_type);
947 assert_eq!(1234567, *data_len);
948 assert_eq!(vec!["a".to_string(), "b".to_string()], *tags);
949 assert_eq!(PageID(123), *root_id);
950 assert_eq!(Some(uuid1), *uuid);
951 }
952 _ => panic!("Expected Overflow variant"),
953 }
954 }
955
956 #[test]
957 fn test_event_leaf_serialize_mixed_inline_and_overflow() {
958 let inline = EventValue::Inline(EventRecord {
959 event_type: "inline_evt".to_string(),
960 data: vec![1, 2, 3],
961 tags: vec!["x".to_string()],
962 uuid: None,
963 });
964 let overflow = EventValue::Overflow {
965 event_type: "overflow_evt".to_string(),
966 data_len: 9999,
967 tags: vec!["y".to_string(), "z".to_string()],
968 root_id: PageID(999),
969 uuid: None,
970 };
971 let leaf_node = EventLeafNode {
972 keys: vec![Position(10), Position(20)],
973 values: vec![inline.clone(), overflow.clone()],
974 };
975 let mut serialized = vec![0u8; leaf_node.calc_serialized_size()];
976 leaf_node.serialize_into(&mut serialized);
977 let deserialized = EventLeafNode::from_slice(&serialized).unwrap();
978 assert_eq!(leaf_node, deserialized);
979
980 match &deserialized.values[0] {
982 EventValue::Inline(rec) => {
983 assert_eq!("inline_evt", rec.event_type);
984 assert_eq!(vec![1, 2, 3], rec.data);
985 assert_eq!(vec!["x".to_string()], rec.tags);
986 assert_eq!(None, rec.uuid);
987 }
988 _ => panic!("Expected Inline at index 0"),
989 }
990 match &deserialized.values[1] {
991 EventValue::Overflow {
992 event_type,
993 data_len,
994 tags,
995 root_id,
996 uuid,
997 } => {
998 assert_eq!("overflow_evt", event_type);
999 assert_eq!(9999, *data_len);
1000 assert_eq!(vec!["y".to_string(), "z".to_string()], *tags);
1001 assert_eq!(PageID(999), *root_id);
1002 assert_eq!(None, *uuid)
1003 }
1004 _ => panic!("Expected Overflow at index 1"),
1005 }
1006 }
1007
1008 #[test]
1009 fn test_event_overflow_node_serialize_roundtrip() {
1010 let node = EventOverflowNode {
1011 next: PageID(77),
1012 data: vec![7, 8, 9, 10],
1013 };
1014 let mut ser = vec![0u8; node.calc_serialized_size()];
1015 node.serialize_into(&mut ser);
1016 assert_eq!(8 + 4, ser.len()); let de = EventOverflowNode::from_slice(&ser).unwrap();
1018 assert_eq!(node, de);
1019 assert_eq!(PageID(77), de.next);
1020 assert_eq!(vec![7, 8, 9, 10], de.data);
1021 }
1022}