Skip to content

Commit

Permalink
feat(WALManager): append 작업 정의 & 파일 저장 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
wHoIsDReAmer committed Nov 21, 2024
1 parent ba1572e commit 20dd6ed
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 10 deletions.
66 changes: 56 additions & 10 deletions src/wal/manager.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::time::SystemTime;
#[allow(dead_code)]
#[allow(unused_variables)]
#[allow(unused_assignments)]
Expand All @@ -11,7 +12,7 @@ use super::types::{EntryType, WALEntry};

pub struct WALManager {
sequence: usize,
entries: Vec<WALEntry>,
buffers: Vec<WALEntry>,
page_size: usize,
directory: PathBuf,
}
Expand All @@ -22,25 +23,70 @@ impl WALManager {
fn new(sequence: usize, entries: Vec<WALEntry>, page_size: usize, directory: PathBuf) -> Self {
Self {
sequence,
entries,
buffers: entries,
page_size,
directory,
}
}

pub fn append(&mut self, entry: WALEntry) -> Result<(), WALError> {
todo!()
pub fn append(&mut self, entry: WALEntry) -> Result<(), RRDBError> {
self.buffers.push(entry);

self.check_and_mark()?;
Ok(())
}

fn check_and_mark(&mut self) -> Result<(), RRDBError> {
let size = self.buffers.iter().map(|entry| entry.size()).sum::<usize>();

if size > self.page_size {
self.checkpoint()?;
}

Ok(())
}

fn save_to_file(&mut self) -> Result<(), RRDBError> {
let path = self.directory.join(format!("{}.log", self.sequence));

let encoded = bitcode::encode(&self.buffers);

fs::write(&path, encoded).map_err(|e| WALError::wrap(e.to_string()))?;

// fsync 디스크 동기화 보장
let file = fs::OpenOptions::new()
.write(true)
.open(path)
.map_err(|e| WALError::wrap(e.to_string()))?;
file.sync_all().map_err(|e| WALError::wrap(e.to_string()))?;

Ok(())
}

fn checkpoint(&mut self) -> Result<(), RRDBError> {
self.buffers.push(WALEntry {
data: None,
entry_type: EntryType::Checkpoint,
timestamp: WALManager::get_current_secs()?,
transaction_id: None,
});
self.save_to_file()?;

self.buffers.clear();
self.sequence += 1;

Ok(())
}

pub fn flush(&mut self) -> Result<(), WALError> {
todo!()
}

fn read_entries<F>(&self, path: &PathBuf, mut callback: F) -> Result<(), WALError>
where
F: FnMut(&WALEntry) -> Result<(), WALError>,
{
todo!()
fn get_current_secs() -> Result<f64, RRDBError> {
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.map_err(|e| WALError::wrap(e.to_string()))
.map(|duration| duration.as_secs_f64())
}
}

Expand Down Expand Up @@ -105,4 +151,4 @@ impl WALBuilder {

Ok((sequence, entries))
}
}
}
7 changes: 7 additions & 0 deletions src/wal/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ pub struct WALEntry {
pub transaction_id: Option<u64>,
}

impl WALEntry {
pub fn size(&self) -> usize {
let data_size = self.data.as_ref().map_or(0, |data| data.len());
size_of::<EntryType>() + size_of::<f64>() + size_of::<u64>() + data_size
}
}

#[derive(Clone, Debug, Encode, Decode)]
pub enum EntryType {
Insert,
Expand Down

0 comments on commit 20dd6ed

Please sign in to comment.