ic_dbms_api/memory/
encode.rs

1use std::borrow::Cow;
2
3use crate::memory::{MSize, MemoryResult};
4use crate::prelude::PageOffset;
5
6/// Default alignment in bytes for [`DataSize::Dynamic`] data types.
7pub const DEFAULT_ALIGNMENT: MSize = 32;
8
9/// This trait defines the encoding and decoding behaviour for data types used in the DBMS canister.
10pub trait Encode: Clone {
11    /// The size characteristic of the data type.
12    ///
13    /// The [`DataSize`] can either be a fixed size in bytes or dynamic.
14    const SIZE: DataSize;
15
16    /// The alignment requirement in bytes for the data type.
17    ///
18    /// If [`Self::SIZE`] is [`DataSize::Fixed`], the alignment must be equal to the size,
19    /// otherwise it can be any value.
20    ///
21    /// This value  should never be less than 8 for [`DataSize::Dynamic`] types to ensure proper memory alignment.
22    ///
23    /// We should set a default value (probably 32) for dynamic types to avoid misalignment issues, but letting an expert user to
24    /// override it if necessary.
25    const ALIGNMENT: PageOffset;
26
27    /// Encodes the data type into a vector of bytes.
28    fn encode(&'_ self) -> Cow<'_, [u8]>;
29
30    /// Decodes the data type from a slice of bytes.
31    fn decode(data: Cow<[u8]>) -> MemoryResult<Self>
32    where
33        Self: Sized;
34
35    /// Returns the size in bytes of the encoded data type.
36    fn size(&self) -> MSize;
37}
38
39/// Represents the size of data types used in the DBMS canister.
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub enum DataSize {
42    /// A fixed size in bytes.
43    Fixed(MSize),
44    /// A variable size.
45    Dynamic,
46}
47
48impl DataSize {
49    /// Returns the size in bytes if the data size is fixed.
50    pub fn get_fixed_size(&self) -> Option<MSize> {
51        match self {
52            DataSize::Fixed(size) => Some(*size),
53            DataSize::Dynamic => None,
54        }
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn test_should_get_data_size_fixed() {
64        let size = DataSize::Fixed(10);
65        assert_eq!(size.get_fixed_size(), Some(10));
66
67        let variable_size = DataSize::Dynamic;
68        assert_eq!(variable_size.get_fixed_size(), None);
69    }
70}