1use crate::wal::WalRecord;
2use std::sync::Mutex;
3
4pub struct WalBuffer {
6 buffer: Mutex<Vec<WalRecord>>,
7 auto_flush_threshold: usize,
8}
9
10impl WalBuffer {
11 pub fn new(capacity: usize) -> Self {
13 Self {
14 buffer: Mutex::new(Vec::with_capacity(capacity)),
15 auto_flush_threshold: capacity * 3 / 4, }
17 }
18
19 pub fn push(&self, record: WalRecord) {
21 let mut buf = self.buffer.lock().unwrap();
22 buf.push(record);
23
24 if buf.len() >= self.auto_flush_threshold {
26 drop(buf); let _ = self.flush();
28 }
29 }
30
31 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 buf.clear();
41 Ok(())
42 }
43
44 pub fn len(&self) -> usize {
46 self.buffer.lock().unwrap().len()
47 }
48
49 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}