Move all hashing to single function. Fix minor bug and make mode clear.

This commit is contained in:
Jon Moroney 2018-11-13 10:41:37 -08:00
parent 43d1d0299d
commit a835ec16a6
2 changed files with 20 additions and 27 deletions

View file

@ -26,6 +26,12 @@ pub enum Verbosity{
All,
}
#[derive(PartialEq)]
pub enum HashMode{
Full,
Partial
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Fileinfo{
full_hash: Option<u64>,
@ -49,33 +55,17 @@ impl Fileinfo{
pub fn set_full_hash(&mut self, hash: u64) -> (){
self.full_hash = Some(hash)
}
pub fn set_partial_hash(&mut self, hash: u64) -> (){
self.partial_hash = Some(hash)
}
pub fn get_partial_hash(&self) -> Option<u64>{
self.full_hash
self.partial_hash
}
pub fn get_file_name(&self) -> &str{ //Gets the first file name. More useful than a hash value as an identifier.
self.file_paths.iter().next().unwrap().to_str().unwrap().rsplit("/").next().unwrap()
}
pub fn generate_partial_hash(&mut self) -> Option<u64>{
let mut hasher = DefaultHasher::new();
match fs::File::open(self.file_paths.iter().next().expect("Error reading path")) {
Ok(f) => {
let mut buffer_reader = BufReader::new(f);
let mut hash_buffer = [0;4096];
match buffer_reader.read(&mut hash_buffer) {
Ok(n) if n>0 => hasher.write(&hash_buffer[0..]),
Ok(n) if n==0 => return None,
Err(_e) => return None,
_ => return None,
}
self.partial_hash = Some(hasher.finish());
}
Err(_e) => return None,
}
return self.get_partial_hash()
}
pub fn generate_hash(&mut self) -> Option<u64>{
pub fn generate_hash(&mut self, mode: HashMode) -> Option<u64>{
let mut hasher = DefaultHasher::new();
match fs::File::open(self.file_paths.iter().next().expect("Error reading path")) {
Ok(f) => {
@ -88,6 +78,10 @@ impl Fileinfo{
Err(e) => println!("{:?} reading {:?}", e, self.file_paths.iter().next().expect("Error opening file for hashing")),
_ => println!("Should not be here"),
}
if mode == HashMode::Partial{
self.set_partial_hash(hasher.finish());
return self.get_partial_hash()
}
}
self.set_full_hash(hasher.finish());
return self.get_full_hash()

View file

@ -1,9 +1,8 @@
//Std imports
use std::io::{Read, BufReader, stdin};
use std::hash::{Hasher};
use std::io::{stdin};
use std::path::{Path};
use std::sync::mpsc::{Sender, channel};
use std::collections::hash_map::{DefaultHasher, HashMap, Entry};
use std::collections::hash_map::{HashMap, Entry};
use std::fs::{self, DirEntry};
use std::io::prelude::*;
@ -16,7 +15,7 @@ use clap::{Arg, App};
use rayon::prelude::*;
extern crate ddh;
use ddh::{Fileinfo, PrintFmt, Verbosity}; //Struct used to store most information about the file and some extras
use ddh::{Fileinfo, PrintFmt, Verbosity, HashMode}; //Struct used to store most information about the file and some extras
fn main() {
let arguments = App::new("Directory Difference hTool")
@ -121,7 +120,7 @@ fn differentiate_and_consolidate(file_length: u64, mut files: Vec<Fileinfo>) ->
n if n>1 => {
//Hash stage one
files.par_iter_mut().for_each(|file_ref| {
file_ref.generate_partial_hash().expect("Error hashing");
file_ref.generate_hash(HashMode::Partial).expect("Error hashing");
});
files.par_sort_unstable_by(|a, b| b.get_partial_hash().cmp(&a.get_partial_hash())); //O(nlog(n))
if file_length>4096 /*4KB*/ { //only hash again if we are not done hashing
@ -131,7 +130,7 @@ fn differentiate_and_consolidate(file_length: u64, mut files: Vec<Fileinfo>) ->
false
}else{false});
files.par_iter_mut().filter(|x| x.get_full_hash().is_some()).for_each(|file_ref| {
file_ref.generate_hash();
file_ref.generate_hash(HashMode::Full);
});
}
},