Skip to main content

dbx_core/wal/
buffer.rs

1use crate::wal::WalRecord;
2use std::sync::Mutex;
3
4/// WAL Buffer - Memory buffer to minimize disk I/O frequency
5pub struct WalBuffer {
6    buffer: Mutex<Vec<WalRecord>>,
7    auto_flush_threshold: usize,
8}
9
10impl WalBuffer {
11    /// Creates a new WAL buffer
12    pub fn new(capacity: usize) -> Self {
13        Self {
14            buffer: Mutex::new(Vec::with_capacity(capacity)),
15            auto_flush_threshold: capacity * 3 / 4, // Auto-flush at 75%
16        }
17    }
18
19    /// Adds a record to the buffer
20    pub fn push(&self, record: WalRecord) {
21        let mut buf = self.buffer.lock().unwrap();
22        buf.push(record);
23
24        // 자동 플러시 체크
25        if buf.len() >= self.auto_flush_threshold {
26            drop(buf); // 락 해제
27            let _ = self.flush();
28        }
29    }
30
31    /// Flushes buffer to disk
32    pub fn flush(&self) -> std::io::Result<()> {
33        let mut buf = self.buffer.lock().unwrap();
34        if buf.is_empty() {
35            return Ok(());
36        }
37
38        // TODO: 실제 WAL 파일에 쓰기 (비동기 I/O)
39        // 현재는 버퍼만 비움
40        buf.clear();
41        Ok(())
42    }
43
44    /// Checks buffer usage
45    pub fn len(&self) -> usize {
46        self.buffer.lock().unwrap().len()
47    }
48
49    /// Checks if buffer is empty
50    pub fn is_empty(&self) -> bool {
51        self.buffer.lock().unwrap().is_empty()
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_wal_buffer_append() {
61        let buffer = WalBuffer::new(1024);
62        let record = WalRecord::Insert {
63            table: "test".to_string(),
64            key: vec![1, 2, 3],
65            value: vec![4, 5, 6],
66            ts: 0,
67        };
68
69        buffer.push(record);
70        assert!(!buffer.is_empty());
71    }
72
73    #[test]
74    fn test_wal_buffer_flush() {
75        let buffer = WalBuffer::new(1024);
76        let record = WalRecord::Insert {
77            table: "test".to_string(),
78            key: vec![1, 2, 3],
79            value: vec![4, 5, 6],
80            ts: 0,
81        };
82
83        buffer.push(record);
84        assert!(buffer.flush().is_ok());
85        assert!(buffer.is_empty());
86    }
87}