risingwave_backup/
meta_snapshot.rs

1// Copyright 2025 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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    /// Snapshot of meta store.
40    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}