diff --git a/src/lib.rs b/src/lib.rs
index e99b2b8..0a032fb 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,6 +2,7 @@ use crossbeam_channel::{Receiver, Sender};
use fs4::FileExt;
use log::{debug, info, trace, warn};
use std::cmp::Ordering;
+use std::collections::HashMap;
use std::fmt;
use std::fs::{self, File};
use std::io::{Error, ErrorKind, Result};
@@ -471,6 +472,51 @@ impl Wal {
pub fn clear(&mut self) -> Result<()> {
self.truncate(self.first_index())
}
+
+ /// Copy all files to the given path directory. directory should exist and be empty
+ pub fn copy_to_path
(&self, path: P) -> Result<()>
+ where
+ P: AsRef,
+ {
+ if fs::read_dir(path.as_ref())?.next().is_some() {
+ return Err(Error::new(
+ ErrorKind::AlreadyExists,
+ format!("path {:?} not empty", path.as_ref()),
+ ));
+ };
+
+ let open_segment_file = self.open_segment.segment.path().file_name().unwrap();
+ let close_segment_files: HashMap<_, _> = self
+ .closed_segments
+ .iter()
+ .map(|segment| {
+ (
+ segment.segment.path().file_name().unwrap(),
+ &segment.segment,
+ )
+ })
+ .collect();
+
+ for entry in fs::read_dir(self.path())? {
+ let entry = entry?;
+ if !entry.metadata()?.is_file() {
+ continue;
+ }
+
+ // if file is locked by any Segment, call copy_to_path on it
+ let entry_file_name = entry.file_name();
+ let dst_path = path.as_ref().to_owned().join(entry_file_name.clone());
+ if entry_file_name == open_segment_file {
+ self.open_segment.segment.copy_to_path(&dst_path)?;
+ } else if let Some(segment) = close_segment_files.get(entry_file_name.as_os_str()) {
+ segment.copy_to_path(&dst_path)?;
+ } else {
+ // if file is not locked by any Segment, just copy it
+ fs::copy(&entry.path(), &dst_path)?;
+ }
+ }
+ Ok(())
+ }
}
impl fmt::Debug for Wal {
diff --git a/src/segment.rs b/src/segment.rs
index 9590aa5..f0e76fb 100644
--- a/src/segment.rs
+++ b/src/segment.rs
@@ -643,6 +643,27 @@ impl Segment {
}
}
}
+
+ pub(crate) fn copy_to_path(&self, path: P) -> Result<()>
+ where
+ P: AsRef,
+ {
+ if path.as_ref().exists() {
+ return Err(Error::new(
+ ErrorKind::AlreadyExists,
+ format!("Path {:?} already exists", path.as_ref()),
+ ));
+ }
+
+ let mut other = Self::create(path, self.capacity())?;
+ unsafe {
+ other
+ .mmap
+ .as_mut_slice()
+ .copy_from_slice(self.mmap.as_slice());
+ }
+ Ok(())
+ }
}
impl fmt::Debug for Segment {