diff --git a/TODO.md b/TODO.md index f3c2678..ca9fc17 100644 --- a/TODO.md +++ b/TODO.md @@ -22,7 +22,7 @@ * Benchmarks * Full fuse method coverage * Clippy -* Do not estimate meta size +* Central repository layout class ## Other * Homepage diff --git a/src/repository/backup.rs b/src/repository/backup.rs index e12ddfb..0407a5e 100644 --- a/src/repository/backup.rs +++ b/src/repository/backup.rs @@ -154,15 +154,8 @@ impl Repository { ) -> Result { let path = path.as_ref(); let mut inode = try!(self.create_inode(path, reference)); - let meta_size = inode.estimate_meta_size(); - inode.cum_size = inode.size + meta_size; - if let Some(ref_inode) = reference { - if !ref_inode.is_same_meta_quick(&inode) { - backup.changed_data_size += inode.size + meta_size; - } - } else { - backup.changed_data_size += inode.size + meta_size; - } + let mut meta_size = 0; + inode.cum_size = inode.size; if inode.file_type == FileType::Directory { inode.cum_dirs = 1; let mut children = BTreeMap::new(); @@ -197,14 +190,30 @@ impl Repository { Err(err) => return Err(err) }; let chunks = try!(self.put_inode(&child_inode)); - children.insert(name, chunks); inode.cum_size += child_inode.cum_size; + for &(_, len) in chunks.iter() { + meta_size += len as u64; + } inode.cum_dirs += child_inode.cum_dirs; inode.cum_files += child_inode.cum_files; + children.insert(name, chunks); } inode.children = Some(children); } else { inode.cum_files = 1; + if let Some(FileData::ChunkedIndirect(ref chunks)) = inode.data { + for &(_, len) in chunks.iter() { + meta_size += len as u64; + } + } + } + inode.cum_size += meta_size; + if let Some(ref_inode) = reference { + if !ref_inode.is_same_meta_quick(&inode) { + backup.changed_data_size += inode.size + meta_size; + } + } else { + backup.changed_data_size += inode.size + meta_size; } Ok(inode) } @@ -226,6 +235,9 @@ impl Repository { let elapsed = Local::now().signed_duration_since(start); backup.date = start.timestamp(); backup.total_data_size = root_inode.cum_size; + for &(_, len) in backup.root.iter() { + backup.total_data_size += len as u64; + } backup.file_count = root_inode.cum_files; backup.dir_count = root_inode.cum_dirs; backup.duration = elapsed.num_milliseconds() as f32 / 1_000.0; diff --git a/src/repository/metadata.rs b/src/repository/metadata.rs index 4e5e853..572506a 100644 --- a/src/repository/metadata.rs +++ b/src/repository/metadata.rs @@ -265,11 +265,6 @@ impl Inode { pub fn decode(data: &[u8]) -> Result { Ok(try!(msgpack::decode(&data))) } - - #[inline] - pub fn estimate_meta_size(&self) -> u64 { - 1000 - } } diff --git a/src/repository/tarfile.rs b/src/repository/tarfile.rs index 1251e85..220870d 100644 --- a/src/repository/tarfile.rs +++ b/src/repository/tarfile.rs @@ -68,10 +68,15 @@ impl Repository { let path = try!(entry.path()).to_path_buf(); match self.import_tar_entry(&mut entry) { Ok(mut inode) => { - inode.cum_size = inode.size + inode.estimate_meta_size(); + inode.cum_size = inode.size; if inode.file_type == FileType::Directory { inode.cum_dirs = 1; } else { + if let Some(FileData::ChunkedIndirect(ref chunks)) = inode.data { + for &(_, len) in chunks.iter() { + inode.cum_size += len as u64; + } + } inode.cum_files = 1; } if let Some(parent_path) = path.parent() { @@ -106,10 +111,13 @@ impl Repository { if let Some(parent_path) = path.parent() { if let Some(&mut (ref mut parent_inode, ref mut children)) = inodes.get_mut(parent_path) { children.remove(&inode.name); - parent_inode.children.as_mut().unwrap().insert(inode.name.clone(), chunks); parent_inode.cum_size += inode.cum_size; + for &(_, len) in chunks.iter() { + parent_inode.cum_size += len as u64; + } parent_inode.cum_files += inode.cum_files; parent_inode.cum_dirs += inode.cum_dirs; + parent_inode.children.as_mut().unwrap().insert(inode.name.clone(), chunks); continue } } @@ -124,17 +132,20 @@ impl Repository { file_type: FileType::Directory, mode: 0o755, name: "archive".to_string(), - cum_size: 1000, + cum_size: 0, cum_files: 0, cum_dirs: 1, ..Default::default() }; let mut children = BTreeMap::new(); for (inode, chunks) in roots { - children.insert(inode.name, chunks); root_inode.cum_size += inode.cum_size; + for &(_, len) in chunks.iter() { + root_inode.cum_size += len as u64; + } root_inode.cum_files += inode.cum_files; root_inode.cum_dirs += inode.cum_dirs; + children.insert(inode.name, chunks); } root_inode.children = Some(children); let chunks = try!(self.put_inode(&root_inode));