refactor archiver

This commit is contained in:
Alexander Weiss 2023-03-20 22:38:19 +01:00
parent 82c545e6d1
commit 2e14f78f00
2 changed files with 136 additions and 139 deletions

View File

@ -1,137 +0,0 @@
use std::path::{Path, PathBuf};
use anyhow::Result;
use chrono::Local;
use indicatif::ProgressBar;
use log::*;
use crate::backend::{DecryptWriteBackend, ReadSource, ReadSourceEntry};
use crate::blob::BlobType;
use crate::index::{IndexedBackend, Indexer, SharedIndexer};
use crate::repofile::{ConfigFile, SnapshotFile};
use super::{FileArchiver, Parent, TreeArchiver, TreeIterator};
pub struct Archiver<BE: DecryptWriteBackend, I: IndexedBackend> {
file_archiver: FileArchiver<BE, I>,
tree_archiver: TreeArchiver<BE, I>,
parent: Parent<I>,
indexer: SharedIndexer<BE>,
be: BE,
snap: SnapshotFile,
}
impl<BE: DecryptWriteBackend, I: IndexedBackend> Archiver<BE, I> {
pub fn new(
be: BE,
index: I,
config: &ConfigFile,
parent: Parent<I>,
mut snap: SnapshotFile,
) -> Result<Self> {
let indexer = Indexer::new(be.clone()).into_shared();
let mut summary = snap.summary.take().unwrap();
summary.backup_start = Local::now();
let file_archiver = FileArchiver::new(be.clone(), index.clone(), indexer.clone(), config)?;
let tree_archiver = TreeArchiver::new(be.clone(), index, indexer.clone(), config, summary)?;
Ok(Self {
file_archiver,
tree_archiver,
parent,
be,
indexer,
snap,
})
}
pub fn archive(
mut self,
src: impl ReadSource,
backup_path: &Path,
as_path: Option<&PathBuf>,
p: &ProgressBar,
) -> Result<SnapshotFile> {
if !p.is_hidden() {
if let Some(size) = src.size()? {
p.set_length(size);
}
};
p.set_prefix("backing up...");
// filter out errors and handle as_path
let iter = src.entries().filter_map(|item| match item {
Err(e) => {
warn!("ignoring error {}\n", e);
None
}
Ok(ReadSourceEntry { path, node, open }) => {
let snapshot_path = if let Some(as_path) = as_path {
as_path
.clone()
.join(path.strip_prefix(backup_path).unwrap())
} else {
path
};
Some(if node.is_dir() {
(snapshot_path, node, open)
} else {
(
snapshot_path
.parent()
.expect("file path should have a parent!")
.to_path_buf(),
node,
open,
)
})
}
});
// handle beginning and ending of trees
let iter = TreeIterator::new(iter);
// use parent snapshot
let iter = iter.filter_map(|item| match self.parent.process(item) {
Ok(item) => Some(item),
Err(err) => {
warn!("ignoring error reading parent snapshot: {err:?}");
None
}
});
// archive files
let iter = iter.filter_map(|item| match self.file_archiver.process(item, p.clone()) {
Ok(item) => Some(item),
Err(err) => {
warn!("ignoring error: {err:?}");
None
}
});
// save items in trees
for item in iter {
self.tree_archiver.add(item)?;
}
let snap = self.finalize_snapshot()?;
p.finish_with_message("done");
Ok(snap)
}
pub fn finalize_snapshot(mut self) -> Result<SnapshotFile> {
let stats = self.file_archiver.finalize()?;
let (id, mut summary) = self.tree_archiver.finalize()?;
stats.apply(&mut summary, BlobType::Data);
self.snap.tree = id;
self.indexer.write().unwrap().finalize()?;
summary.finalize(self.snap.time)?;
self.snap.summary = Some(summary);
let id = self.be.save_file(&self.snap)?;
self.snap.id = id;
Ok(self.snap)
}
}

View File

@ -1,11 +1,145 @@
mod archiver_impl;
mod file_archiver;
mod parent;
mod tree;
mod tree_archiver;
pub use archiver_impl::*;
pub use file_archiver::*;
pub use parent::*;
pub use tree::*;
pub use tree_archiver::*;
use std::path::{Path, PathBuf};
use anyhow::Result;
use chrono::Local;
use indicatif::ProgressBar;
use log::*;
use crate::backend::{DecryptWriteBackend, ReadSource, ReadSourceEntry};
use crate::blob::BlobType;
use crate::index::{IndexedBackend, Indexer, SharedIndexer};
use crate::repofile::{ConfigFile, SnapshotFile};
pub struct Archiver<BE: DecryptWriteBackend, I: IndexedBackend> {
file_archiver: FileArchiver<BE, I>,
tree_archiver: TreeArchiver<BE, I>,
parent: Parent<I>,
indexer: SharedIndexer<BE>,
be: BE,
snap: SnapshotFile,
}
impl<BE: DecryptWriteBackend, I: IndexedBackend> Archiver<BE, I> {
pub fn new(
be: BE,
index: I,
config: &ConfigFile,
parent: Parent<I>,
mut snap: SnapshotFile,
) -> Result<Self> {
let indexer = Indexer::new(be.clone()).into_shared();
let mut summary = snap.summary.take().unwrap();
summary.backup_start = Local::now();
let file_archiver = FileArchiver::new(be.clone(), index.clone(), indexer.clone(), config)?;
let tree_archiver = TreeArchiver::new(be.clone(), index, indexer.clone(), config, summary)?;
Ok(Self {
file_archiver,
tree_archiver,
parent,
be,
indexer,
snap,
})
}
pub fn archive(
mut self,
src: impl ReadSource,
backup_path: &Path,
as_path: Option<&PathBuf>,
p: &ProgressBar,
) -> Result<SnapshotFile> {
if !p.is_hidden() {
if let Some(size) = src.size()? {
p.set_length(size);
}
};
p.set_prefix("backing up...");
// filter out errors and handle as_path
let iter = src.entries().filter_map(|item| match item {
Err(e) => {
warn!("ignoring error {}\n", e);
None
}
Ok(ReadSourceEntry { path, node, open }) => {
let snapshot_path = if let Some(as_path) = as_path {
as_path
.clone()
.join(path.strip_prefix(backup_path).unwrap())
} else {
path
};
Some(if node.is_dir() {
(snapshot_path, node, open)
} else {
(
snapshot_path
.parent()
.expect("file path should have a parent!")
.to_path_buf(),
node,
open,
)
})
}
});
// handle beginning and ending of trees
let iter = TreeIterator::new(iter);
// use parent snapshot
let iter = iter.filter_map(|item| match self.parent.process(item) {
Ok(item) => Some(item),
Err(err) => {
warn!("ignoring error reading parent snapshot: {err:?}");
None
}
});
// archive files
let iter = iter.filter_map(|item| match self.file_archiver.process(item, p.clone()) {
Ok(item) => Some(item),
Err(err) => {
warn!("ignoring error: {err:?}");
None
}
});
// save items in trees
for item in iter {
self.tree_archiver.add(item)?;
}
let snap = self.finalize_snapshot()?;
p.finish_with_message("done");
Ok(snap)
}
pub fn finalize_snapshot(mut self) -> Result<SnapshotFile> {
let stats = self.file_archiver.finalize()?;
let (id, mut summary) = self.tree_archiver.finalize()?;
stats.apply(&mut summary, BlobType::Data);
self.snap.tree = id;
self.indexer.write().unwrap().finalize()?;
summary.finalize(self.snap.time)?;
self.snap.summary = Some(summary);
let id = self.be.save_file(&self.snap)?;
self.snap.id = id;
Ok(self.snap)
}
}