linkrs_storage/edge/node_group/
manifest.rs1use linkrs_core::{StorageError, StorageResult};
5
6use super::validate_group_bits;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct TableShardManifest {
15 pub group_bits: u32,
16 pub out_groups: Vec<u32>,
17 pub in_groups: Vec<u32>,
18}
19
20impl TableShardManifest {
21 pub fn encode(&self) -> Vec<u8> {
22 let mut out_groups = self.out_groups.clone();
23 out_groups.sort_unstable();
24 out_groups.dedup();
25 let mut in_groups = self.in_groups.clone();
26 in_groups.sort_unstable();
27 in_groups.dedup();
28 let mut out = Vec::with_capacity(12 + (out_groups.len() + in_groups.len()) * 4);
29 out.extend_from_slice(&self.group_bits.to_le_bytes());
30 out.extend_from_slice(&(out_groups.len() as u32).to_le_bytes());
31 for gid in &out_groups {
32 out.extend_from_slice(&gid.to_le_bytes());
33 }
34 out.extend_from_slice(&(in_groups.len() as u32).to_le_bytes());
35 for gid in &in_groups {
36 out.extend_from_slice(&gid.to_le_bytes());
37 }
38 out
39 }
40
41 pub fn decode(data: &[u8]) -> StorageResult<Self> {
42 let bad_slice = || StorageError::deserialize_error("group manifest slice too short");
43 if data.len() < 8 {
44 return Err(StorageError::deserialize_error(format!(
45 "group manifest too short: got {}",
46 data.len()
47 )));
48 }
49 let group_bits = u32::from_le_bytes(data[0..4].try_into().map_err(|_| bad_slice())?);
50 validate_group_bits(group_bits)?;
51 let mut cursor = 4usize;
52 let take_u32 = |data: &[u8], cursor: &mut usize| -> StorageResult<u32> {
53 if data.len() - *cursor < 4 {
54 return Err(StorageError::deserialize_error(
55 "group manifest slice too short",
56 ));
57 }
58 let value = u32::from_le_bytes(
59 data[*cursor..*cursor + 4]
60 .try_into()
61 .map_err(|_| bad_slice())?,
62 );
63 *cursor += 4;
64 Ok(value)
65 };
66 let out_len = take_u32(data, &mut cursor)? as usize;
67 if data.len() - cursor < out_len * 4 + 4 {
68 return Err(StorageError::deserialize_error(format!(
69 "group manifest too short for {} out groups",
70 out_len
71 )));
72 }
73 let mut out_groups = Vec::with_capacity(out_len);
74 for _ in 0..out_len {
75 out_groups.push(take_u32(data, &mut cursor)?);
76 }
77 let in_len = take_u32(data, &mut cursor)? as usize;
78 if data.len() - cursor != in_len * 4 {
79 return Err(StorageError::deserialize_error(format!(
80 "group manifest trailing bytes: expected {} in groups, {} bytes remain",
81 in_len,
82 data.len() - cursor
83 )));
84 }
85 let mut in_groups = Vec::with_capacity(in_len);
86 for _ in 0..in_len {
87 in_groups.push(take_u32(data, &mut cursor)?);
88 }
89 out_groups.sort_unstable();
90 out_groups.dedup();
91 in_groups.sort_unstable();
92 in_groups.dedup();
93 Ok(Self {
94 group_bits,
95 out_groups,
96 in_groups,
97 })
98 }
99}