Skip to main content

regulus_db/persistence/
snapshot.rs

1use std::fs::File;
2use std::io::{BufReader, BufWriter, Write};
3use std::path::Path;
4use crate::storage::{MemoryEngine, SerializableEngineData};
5use crate::types::{DbResult, DbError};
6
7/// 快照管理器
8pub struct SnapshotManager {
9    base_path: std::path::PathBuf,
10}
11
12impl SnapshotManager {
13    pub fn new(base_path: &Path) -> Self {
14        SnapshotManager {
15            base_path: base_path.to_path_buf(),
16        }
17    }
18
19    /// 获取快照文件路径
20    fn snapshot_path(&self) -> std::path::PathBuf {
21        self.base_path.join("data.rdb")
22    }
23
24    /// 保存快照
25    pub fn save(&self, engine: &MemoryEngine) -> DbResult<std::path::PathBuf> {
26        let path = self.snapshot_path();
27        let file = File::create(&path)
28            .map_err(|e| DbError::IoError(e))?;
29        let mut writer = BufWriter::new(file);
30
31        // 使用 engine 提供的 serialize 方法
32        let data = engine.serialize()
33            .map_err(|e| DbError::InternalError(format!("Serialization error: {}", e)))?;
34
35        bincode::serialize_into(&mut writer, &data)
36            .map_err(|e| DbError::InternalError(format!("Bincode error: {}", e)))?;
37
38        writer.flush()
39            .map_err(|e| DbError::IoError(e))?;
40
41        Ok(path)
42    }
43
44    /// 加载快照
45    pub fn load(&self) -> DbResult<Option<MemoryEngine>> {
46        let path = self.snapshot_path();
47
48        if !path.exists() {
49            return Ok(None);
50        }
51
52        let file = File::open(&path)
53            .map_err(|e| DbError::IoError(e))?;
54        let reader = BufReader::new(file);
55
56        let data: SerializableEngineData = bincode::deserialize_from(reader)
57            .map_err(|e| DbError::InternalError(format!("Bincode error: {}", e)))?;
58
59        // 使用 MemoryEngine::deserialize 恢复
60        let engine = MemoryEngine::deserialize(data);
61        Ok(Some(engine))
62    }
63
64    /// 检查快照是否存在
65    pub fn exists(&self) -> bool {
66        self.snapshot_path().exists()
67    }
68}