umadb_core/
events_tree_nodes.rs

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    // For large data stored across overflow pages
21    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; // event payload in overflow node
58        const HAS_UUID      = 0b0000_0010; // event includes UUID field
59    }
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        // 2 bytes for keys_len
71        let mut total_size = 2;
72
73        // 8 bytes for each Position in keys
74        total_size += self.keys.len() * 8;
75
76        // For each value
77        for value in &self.values {
78            // 1 byte for discriminator
79            total_size += 1;
80            match value {
81                EventValue::Inline(rec) => {
82                    // 2 bytes for event_type length + bytes for the string
83                    total_size += 2 + rec.event_type.len();
84                    // 2 bytes for data length + bytes for the data
85                    total_size += 2 + rec.data.len();
86                    // 2 bytes for number of tags
87                    total_size += 2;
88                    // For each tag: 2 bytes for length + bytes for the string
89                    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                    // 2 bytes for event_type length + bytes for the string
104                    total_size += 2 + event_type.len();
105                    // 8 bytes for data_len (u64)
106                    total_size += 8;
107                    // 2 bytes for number of tags
108                    total_size += 2;
109                    // For each tag: 2 bytes for length + bytes for the string
110                    for tag in tags {
111                        total_size += 2 + tag.len();
112                    }
113                    // 8 bytes for root_id
114                    total_size += 8;
115                    if uuid.is_some() {
116                        total_size += 16;
117                    }
118                }
119            }
120        }
121
122        total_size
123    }
124
125    /// No-allocation serialization into the provided buffer. Returns number of bytes written.
126    pub fn serialize_into(&self, buf: &mut [u8]) -> usize {
127        let mut i = 0usize;
128        // keys_len
129        let klen = self.keys.len() as u16;
130        buf[i..i + 2].copy_from_slice(&klen.to_le_bytes());
131        i += 2;
132        // keys
133        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        // values
139        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        // Check if the slice has at least 2 bytes for keys_len
221        if slice.len() < 2 {
222            return Err(DCBError::DeserializationError(format!(
223                "Expected at least 2 bytes, got {}",
224                slice.len()
225            )));
226        }
227
228        // Extract the length of the keys (first 2 bytes)
229        let keys_len = LittleEndian::read_u16(&slice[0..2]) as usize;
230
231        // Calculate the minimum expected size for the keys
232        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        // Extract the keys (8 bytes each)
242        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        // Extract the values (EventValue)
250        let mut values = Vec::with_capacity(keys_len);
251        let mut offset = 2 + (keys_len * 8);
252
253        for _ in 0..keys_len {
254            // Read discriminator (1 byte)
255            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            // Extract event_type length (2 bytes)
267            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                // Inline: data_len u16 + data bytes
294                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                // num tags
310                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                // Overflow: data_len u64 + tags + root_id
375                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, // PageID(0) indicates end of chain
476    pub data: Vec<u8>,
477}
478
479impl EventOverflowNode {
480    pub fn calc_serialized_size(&self) -> usize {
481        // 8 bytes for next + data bytes
482        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        // 2 bytes for keys_len
513        let mut total_size = 2;
514
515        // 8 bytes for each Position in keys
516        total_size += self.keys.len() * 8;
517
518        // 8 bytes for each PageID in child_ids
519        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        // Check if the slice has at least 2 bytes for keys_len
542        if slice.len() < 2 {
543            return Err(DCBError::DeserializationError(format!(
544                "Expected at least 2 bytes, got {}",
545                slice.len()
546            )));
547        }
548
549        // Extract the length of the keys (first 2 bytes)
550        let keys_len = LittleEndian::read_u16(&slice[0..2]) as usize;
551
552        // Calculate the minimum expected size for the keys
553        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        // Extract the keys (8 bytes each)
563        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        // Calculate the offset after reading keys
571        let offset = 2 + (keys_len * 8);
572
573        // Derive child_ids_len from keys_len (always keys_len + 1)
574        let child_ids_len = keys_len + 1;
575
576        // Calculate the minimum expected size for the child_ids
577        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        // Extract the child_ids (8 bytes each)
587        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        // Replace the last child ID.
598        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        // Create an EventInternalNode with known values
631        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        // Serialize the EventInternalNode
637        let mut serialized = vec![0u8; internal_node.calc_serialized_size()];
638        internal_node.serialize_into(&mut serialized).unwrap();
639
640        // Verify the serialized output is not empty
641        assert!(!serialized.is_empty());
642
643        // Deserialize back to an EventInternalNode
644        let deserialized = EventInternalNode::from_slice(&serialized)
645            .expect("Failed to deserialize EventInternalNode");
646
647        // Verify that the deserialized node matches the original
648        assert_eq!(internal_node, deserialized);
649
650        // Verify specific properties
651        assert_eq!(3, deserialized.keys.len());
652        assert_eq!(4, deserialized.child_ids.len());
653
654        // Check keys
655        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        // Check child_ids
660        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        // Create an EventLeafNode with known values
669        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], // 100 as little-endian bytes
675                    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], // 200 as little-endian bytes
681                    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], // 300 as little-endian bytes
692                    tags: vec!["tag8".to_string(), "tag9".to_string()],
693                    uuid: None,
694                }),
695            ],
696        };
697
698        // Serialize the EventLeafNode
699        let mut serialized = vec![0u8; leaf_node.calc_serialized_size()];
700        leaf_node.serialize_into(&mut serialized);
701
702        // Verify the serialized output is not empty
703        assert!(!serialized.is_empty());
704
705        // Deserialize back to an EventLeafNode
706        let deserialized =
707            EventLeafNode::from_slice(&serialized).expect("Failed to deserialize EventLeafNode");
708
709        // Verify that the deserialized node matches the original
710        assert_eq!(leaf_node, deserialized);
711
712        // Verify specific properties
713        assert_eq!(3, deserialized.keys.len());
714        assert_eq!(3, deserialized.values.len());
715
716        // Check keys
717        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        // Check first value
722        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        // Check second value
736        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        // Check third value
755        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        // Create an EventLeafNode with known values
769        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], // 100 as little-endian bytes
778                    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], // 200 as little-endian bytes
784                    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], // 300 as little-endian bytes
795                    tags: vec!["tag8".to_string(), "tag9".to_string()],
796                    uuid: Some(uuid3),
797                }),
798            ],
799        };
800
801        // Serialize the EventLeafNode
802        let mut serialized = vec![0u8; leaf_node.calc_serialized_size()];
803        leaf_node.serialize_into(&mut serialized);
804
805        // Verify the serialized output is not empty
806        assert!(!serialized.is_empty());
807
808        // Deserialize back to an EventLeafNode
809        let deserialized =
810            EventLeafNode::from_slice(&serialized).expect("Failed to deserialize EventLeafNode");
811
812        // Verify that the deserialized node matches the original
813        assert_eq!(leaf_node, deserialized);
814
815        // Verify specific properties
816        assert_eq!(3, deserialized.keys.len());
817        assert_eq!(3, deserialized.values.len());
818
819        // Check keys
820        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        // Check first value
825        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        // Check second value
839        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        // Check third value
858        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        // Serialize
882        let mut serialized = vec![0u8; leaf_node.calc_serialized_size()];
883        leaf_node.serialize_into(&mut serialized);
884        assert!(!serialized.is_empty());
885        // Deserialize
886        let deserialized = EventLeafNode::from_slice(&serialized)
887            .expect("Failed to deserialize EventLeafNode with overflow");
888        assert_eq!(leaf_node, deserialized);
889
890        // Check specific fields
891        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        // Serialize
926        let mut serialized = vec![0u8; leaf_node.calc_serialized_size()];
927        leaf_node.serialize_into(&mut serialized);
928        assert!(!serialized.is_empty());
929        // Deserialize
930        let deserialized = EventLeafNode::from_slice(&serialized)
931            .expect("Failed to deserialize EventLeafNode with overflow");
932        assert_eq!(leaf_node, deserialized);
933
934        // Check specific fields
935        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        // Validate order and variants
981        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()); // 8 bytes next + 4 bytes data
1017        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}