Skip to main content

mf_persistence/
ser.rs

1//! 持久化负载的序列化辅助工具。
2//!
3//! 使用简单分帧:将各步骤的序列化字节以 `0x1E`(记录分隔符)连接。
4//! 压缩为可选,建议在分帧之后进行;校验和在压缩(或加密)后的字节上计算。
5
6use std::collections::HashMap;
7use crc32fast::Hasher as Crc32;
8use zstd::stream::encode_all;
9use mf_state::Transaction;
10use serde::{Serialize, Deserialize};
11
12/// 可选的 zstd 压缩(level=1,优先速度)。
13pub fn compress_if_needed(
14    input: &[u8],
15    enable: bool,
16) -> anyhow::Result<Vec<u8>> {
17    if !enable {
18        return Ok(input.to_vec());
19    }
20    let out = encode_all(input, 1)?; // fast
21    Ok(out)
22}
23
24/// CRC32 校验,提供轻量级的数据完整性保护。
25pub fn checksum32(input: &[u8]) -> u32 {
26    let mut h = Crc32::new();
27    h.update(input);
28    h.finalize()
29}
30
31/// 将步骤序列化结果以 RS(0x1E) 作为分隔拼接。
32pub fn serialize_steps_concat(transaction: &Transaction) -> Vec<u8> {
33    let mut payload: Vec<u8> = Vec::new();
34    for step in transaction.steps.iter() {
35        if let Some(s) = step.serialize() {
36            payload.extend_from_slice(&s);
37            payload.push(0x1E);
38        }
39    }
40    payload
41}
42
43// 标准化的步骤帧格式,便于跨版本重放
44#[derive(Serialize, Deserialize, Clone, Debug)]
45pub struct TypeWrapper {
46    pub type_id: String,
47    pub data: Vec<u8>,
48}
49
50// 快照序列化载体(与 StateSerialize 的字段对应)
51#[derive(Serialize, Deserialize, Clone, Debug)]
52pub struct SnapshotData {
53    pub node_pool: Vec<u8>,
54    pub state_fields: HashMap<String, Vec<u8>>,
55}
56
57pub fn frame_steps(transaction: &Transaction) -> Vec<TypeWrapper> {
58    let mut frames: Vec<TypeWrapper> =
59        Vec::with_capacity(transaction.steps.len());
60    for step in transaction.steps.iter() {
61        if let Some(data) = step.serialize() {
62            frames.push(TypeWrapper { type_id: step.name(), data });
63        }
64    }
65    frames
66}
67
68pub fn frame_invert_steps(transaction: &Transaction) -> Vec<TypeWrapper> {
69    if transaction.invert_steps.is_empty() {
70        return Vec::new();
71    }
72    let mut frames: Vec<TypeWrapper> =
73        Vec::with_capacity(transaction.invert_steps.len());
74    let mut invert_steps: Vec<_> =
75        transaction.invert_steps.iter().cloned().collect();
76    invert_steps.reverse();
77    for step in invert_steps {
78        if let Some(data) = step.serialize() {
79            frames.push(TypeWrapper { type_id: step.name(), data });
80        }
81    }
82    frames
83}