This commit is contained in:
Dennis Schwerdel 2017-04-02 20:37:34 +02:00 committed by Dennis Schwerdel
parent d11c791652
commit 727f59b2d3
4 changed files with 33 additions and 19 deletions

View File

@ -109,8 +109,6 @@ Recommended: Brotli/2-7
- Random bundle name - Random bundle name
- Metadata - Metadata
- Arbitrarily nested chunk lists - Arbitrarily nested chunk lists
- Cumulative size, chunk count, dir/file count
- Permissive msgpack mode
### CLI functionality ### CLI functionality
- list --tree - list --tree

View File

@ -105,6 +105,9 @@ fn print_inode(inode: &Inode) {
if let Some(ref target) = inode.symlink_target { if let Some(ref target) = inode.symlink_target {
println!("Symlink target: {}", target); println!("Symlink target: {}", target);
} }
println!("Cumulative size: {}", to_file_size(inode.cum_size));
println!("Cumulative file count: {}", inode.cum_files);
println!("Cumulative directory count: {}", inode.cum_dirs);
if let Some(ref children) = inode.children { if let Some(ref children) = inode.children {
println!("Children:"); println!("Children:");
for name in children.keys() { for name in children.keys() {

View File

@ -158,11 +158,11 @@ impl Repository {
options: &BackupOptions, options: &BackupOptions,
backup: &mut Backup, backup: &mut Backup,
failed_paths: &mut Vec<PathBuf> failed_paths: &mut Vec<PathBuf>
) -> Result<ChunkList, RepositoryError> { ) -> Result<Inode, RepositoryError> {
let path = path.as_ref(); let path = path.as_ref();
let mut inode = try!(self.create_inode(path, reference)); let mut inode = try!(self.create_inode(path, reference));
let meta_size = 1000; // add 1000 for encoded metadata let meta_size = 1000; // add 1000 for encoded metadata
backup.total_data_size += inode.size + meta_size; inode.cum_size = inode.size + meta_size;
if let Some(ref_inode) = reference { if let Some(ref_inode) = reference {
if !ref_inode.is_same_meta_quick(&inode) { if !ref_inode.is_same_meta_quick(&inode) {
backup.changed_data_size += inode.size + meta_size; backup.changed_data_size += inode.size + meta_size;
@ -171,7 +171,7 @@ impl Repository {
backup.changed_data_size += inode.size + meta_size; backup.changed_data_size += inode.size + meta_size;
} }
if inode.file_type == FileType::Directory { if inode.file_type == FileType::Directory {
backup.dir_count +=1; inode.cum_dirs = 1;
let mut children = BTreeMap::new(); let mut children = BTreeMap::new();
let parent_dev = try!(path.metadata()).st_dev(); let parent_dev = try!(path.metadata()).st_dev();
for ch in try!(fs::read_dir(path)) { for ch in try!(fs::read_dir(path)) {
@ -194,21 +194,25 @@ impl Repository {
.and_then(|inode| inode.children.as_ref()) .and_then(|inode| inode.children.as_ref())
.and_then(|map| map.get(&name)) .and_then(|map| map.get(&name))
.and_then(|chunks| self.get_inode(chunks).ok()); .and_then(|chunks| self.get_inode(chunks).ok());
let chunks = match self.create_backup_recurse(&child_path, ref_child.as_ref(), options, backup, failed_paths) { let child_inode = match self.create_backup_recurse(&child_path, ref_child.as_ref(), options, backup, failed_paths) {
Ok(chunks) => chunks, Ok(inode) => inode,
Err(_) => { Err(_) => {
warn!("Failed to backup {:?}", child_path); warn!("Failed to backup {:?}", child_path);
failed_paths.push(child_path); failed_paths.push(child_path);
continue continue
} }
}; };
let chunks = try!(self.put_inode(&child_inode));
children.insert(name, chunks); children.insert(name, chunks);
inode.cum_size += child_inode.cum_size;
inode.cum_dirs += child_inode.cum_dirs;
inode.cum_files += child_inode.cum_files;
} }
inode.children = Some(children); inode.children = Some(children);
} else { } else {
backup.file_count +=1; inode.cum_files = 1;
} }
self.put_inode(&inode) Ok(inode)
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -222,10 +226,14 @@ impl Repository {
let info_before = self.info(); let info_before = self.info();
let start = Local::now(); let start = Local::now();
let mut failed_paths = vec![]; let mut failed_paths = vec![];
backup.root = try!(self.create_backup_recurse(path, reference_inode.as_ref(), options, &mut backup, &mut failed_paths)); let root_inode = try!(self.create_backup_recurse(path, reference_inode.as_ref(), options, &mut backup, &mut failed_paths));
backup.root = try!(self.put_inode(&root_inode));
try!(self.flush()); try!(self.flush());
let elapsed = Local::now().signed_duration_since(start); let elapsed = Local::now().signed_duration_since(start);
backup.date = start.timestamp(); backup.date = start.timestamp();
backup.total_data_size = root_inode.cum_size;
backup.file_count = root_inode.cum_files;
backup.dir_count = root_inode.cum_dirs;
backup.duration = elapsed.num_milliseconds() as f32 / 1_000.0; backup.duration = elapsed.num_milliseconds() as f32 / 1_000.0;
let info_after = self.info(); let info_after = self.info();
backup.deduplicated_data_size = info_after.raw_data_size - info_before.raw_data_size; backup.deduplicated_data_size = info_after.raw_data_size - info_before.raw_data_size;

View File

@ -111,12 +111,13 @@ pub struct Inode {
pub mode: u32, pub mode: u32,
pub user: u32, pub user: u32,
pub group: u32, pub group: u32,
pub __old_access_time: i64,
pub timestamp: i64, pub timestamp: i64,
pub __old_create_time: i64,
pub symlink_target: Option<String>, pub symlink_target: Option<String>,
pub contents: Option<FileContents>, pub contents: Option<FileContents>,
pub children: Option<BTreeMap<String, ChunkList>> pub children: Option<BTreeMap<String, ChunkList>>,
pub cum_size: u64,
pub cum_dirs: usize,
pub cum_files: usize
} }
impl Default for Inode { impl Default for Inode {
fn default() -> Self { fn default() -> Self {
@ -127,12 +128,13 @@ impl Default for Inode {
mode: 0o644, mode: 0o644,
user: 1000, user: 1000,
group: 1000, group: 1000,
__old_access_time: 0,
timestamp: 0, timestamp: 0,
__old_create_time: 0,
symlink_target: None, symlink_target: None,
contents: None, contents: None,
children: None children: None,
cum_size: 0,
cum_dirs: 0,
cum_files: 0
} }
} }
} }
@ -143,12 +145,15 @@ serde_impl!(Inode(u8?) {
mode: u32 => 3, mode: u32 => 3,
user: u32 => 4, user: u32 => 4,
group: u32 => 5, group: u32 => 5,
__old_access_time: i64 => 6, //__old_access_time: i64 => 6,
timestamp: i64 => 7, timestamp: i64 => 7,
__old_create_time: i64 => 8, //__old_create_time: i64 => 8,
symlink_target: Option<String> => 9, symlink_target: Option<String> => 9,
contents: Option<FileContents> => 10, contents: Option<FileContents> => 10,
children: BTreeMap<String, ChunkList> => 11 children: BTreeMap<String, ChunkList> => 11,
cum_size: u64 => 12,
cum_dirs: usize => 13,
cum_files: usize => 14
}); });