use crate::wal::WalRecord;
use std::sync::Mutex;
pub struct WalBuffer {
buffer: Mutex<Vec<WalRecord>>,
auto_flush_threshold: usize,
}
impl WalBuffer {
pub fn new(capacity: usize) -> Self {
Self {
buffer: Mutex::new(Vec::with_capacity(capacity)),
auto_flush_threshold: capacity * 3 / 4, }
}
pub fn push(&self, record: WalRecord) {
let mut buf = self.buffer.lock().unwrap();
buf.push(record);
if buf.len() >= self.auto_flush_threshold {
drop(buf); let _ = self.flush();
}
}
pub fn flush(&self) -> std::io::Result<()> {
let mut buf = self.buffer.lock().unwrap();
if buf.is_empty() {
return Ok(());
}
buf.clear();
Ok(())
}
pub fn len(&self) -> usize {
self.buffer.lock().unwrap().len()
}
pub fn is_empty(&self) -> bool {
self.buffer.lock().unwrap().is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_wal_buffer_append() {
let buffer = WalBuffer::new(1024);
let record = WalRecord::Insert {
table: "test".to_string(),
key: vec![1, 2, 3],
value: vec![4, 5, 6],
ts: 0,
};
buffer.push(record);
assert!(!buffer.is_empty());
}
#[test]
fn test_wal_buffer_flush() {
let buffer = WalBuffer::new(1024);
let record = WalRecord::Insert {
table: "test".to_string(),
key: vec![1, 2, 3],
value: vec![4, 5, 6],
ts: 0,
};
buffer.push(record);
assert!(buffer.flush().is_ok());
assert!(buffer.is_empty());
}
}