risingwave_backup/
meta_snapshot.rs1use std::fmt::{Display, Formatter};
16
17use bytes::{Buf, BufMut};
18use risingwave_hummock_sdk::version::HummockVersion;
19
20use crate::error::BackupResult;
21use crate::{MetaSnapshotId, xxhash64_checksum, xxhash64_verify};
22
23pub trait Metadata: Display + Send + Sync {
24 fn encode_to(&self, buf: &mut Vec<u8>) -> BackupResult<()>;
25
26 fn decode(buf: &[u8]) -> BackupResult<Self>
27 where
28 Self: Sized;
29
30 fn hummock_version_ref(&self) -> &HummockVersion;
31
32 fn hummock_version(self) -> HummockVersion;
33}
34
35#[derive(Debug, Default, Clone, PartialEq)]
36pub struct MetaSnapshot<T: Metadata> {
37 pub format_version: u32,
38 pub id: MetaSnapshotId,
39 pub metadata: T,
41}
42
43impl<T: Metadata> MetaSnapshot<T> {
44 pub fn encode(&self) -> BackupResult<Vec<u8>> {
45 let mut buf = vec![];
46 buf.put_u32_le(self.format_version);
47 buf.put_u64_le(self.id);
48 self.metadata.encode_to(&mut buf)?;
49 let checksum = xxhash64_checksum(&buf);
50 buf.put_u64_le(checksum);
51 Ok(buf)
52 }
53
54 pub fn decode(mut buf: &[u8]) -> BackupResult<Self> {
55 let checksum = (&buf[buf.len() - 8..]).get_u64_le();
56 xxhash64_verify(&buf[..buf.len() - 8], checksum)?;
57 let format_version = buf.get_u32_le();
58 let id = buf.get_u64_le();
59 let metadata = T::decode(buf)?;
60 Ok(Self {
61 format_version,
62 id,
63 metadata,
64 })
65 }
66
67 pub fn decode_format_version(mut buf: &[u8]) -> BackupResult<u32> {
68 let checksum = (&buf[buf.len() - 8..]).get_u64_le();
69 xxhash64_verify(&buf[..buf.len() - 8], checksum)?;
70 let format_version = buf.get_u32_le();
71 Ok(format_version)
72 }
73}
74
75impl<T: Metadata> Display for MetaSnapshot<T> {
76 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
77 writeln!(f, "format_version: {}", self.format_version)?;
78 writeln!(f, "id: {}", self.id)?;
79 writeln!(f, "{}", self.metadata)?;
80 Ok(())
81 }
82}