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}