Skip to main content

raft_log/raft_log/
dump.rs

1use std::io;
2use std::sync::Arc;
3
4use chunked_wal::ChunkedWal;
5use chunked_wal::WalLock;
6
7use crate::ChunkId;
8use crate::Config;
9use crate::RaftLog;
10use crate::RaftLogRecord;
11use crate::RaftWalTypes;
12use crate::Types;
13use crate::raft_log::dump_api::DumpApi;
14use crate::types::Segment;
15
16/// A dump utility that reads WAL records from disk.
17///
18/// It acquires an exclusive lock on the directory to prevent concurrent writes
19/// while reading.
20pub struct Dump<T> {
21    config: Arc<Config>,
22
23    /// Holds the WAL directory lock while reading files from disk.
24    _wal_lock: WalLock,
25
26    _p: std::marker::PhantomData<T>,
27}
28
29impl<T: Types> DumpApi<T> for Dump<T> {
30    /// Reads all WAL records from disk and passes them to the provided callback
31    /// function.
32    ///
33    /// The callback receives:
34    /// - `chunk_id`: The ID of the chunk containing the record
35    /// - `index`: The 0-based index of the record within its chunk
36    /// - `result`: The result containing either the record data or an IO error
37    ///
38    /// # Errors
39    /// Returns an IO error if reading the chunks fails or if the callback
40    /// returns an error.
41    fn write_with<D>(&self, write_record: D) -> Result<(), io::Error>
42    where D: FnMut(
43            ChunkId,
44            u64,
45            Result<(Segment, RaftLogRecord<T>), io::Error>,
46        ) -> Result<(), io::Error> {
47        ChunkedWal::<RaftWalTypes<T>>::dump_records(
48            &self.config.wal,
49            &self._wal_lock,
50            write_record,
51        )
52    }
53}
54
55/// A dump utility that reads WAL records from an existing RaftLog instance.
56///
57/// Unlike [`Dump`], this does not acquire a directory lock since it operates on
58/// an already initialized RaftLog.
59pub struct RefDump<'a, T: Types> {
60    pub(crate) raft_log: &'a RaftLog<T>,
61}
62
63impl<T: Types> DumpApi<T> for RefDump<'_, T> {
64    /// Reads all WAL records from the RaftLog and passes them to the provided
65    /// callback function.
66    ///
67    /// The callback receives:
68    /// - `chunk_id`: The ID of the chunk containing the record
69    /// - `index`: The 0-based index of the record within its chunk
70    /// - `result`: The result containing either the record data or an IO error
71    ///
72    /// # Errors
73    /// Returns an IO error if reading the chunks fails or if the callback
74    /// returns an error.
75    fn write_with<D>(&self, write_record: D) -> Result<(), io::Error>
76    where D: FnMut(
77            ChunkId,
78            u64,
79            Result<(Segment, RaftLogRecord<T>), io::Error>,
80        ) -> Result<(), io::Error> {
81        self.raft_log.wal.dump_loaded_records(write_record)
82    }
83}
84
85impl<T: Types> Dump<T> {
86    /// Creates a new Dump instance with the given configuration.
87    ///
88    /// # Errors
89    /// Returns an IO error if acquiring the directory lock fails.
90    pub fn new(config: Arc<Config>) -> Result<Self, io::Error> {
91        let wal_lock =
92            ChunkedWal::<RaftWalTypes<T>>::acquire_lock(&config.wal)?;
93
94        Ok(Self {
95            config,
96            _wal_lock: wal_lock,
97            _p: std::marker::PhantomData,
98        })
99    }
100}