mirror of
https://github.com/darakian/ddh.git
synced 2026-09-10 07:06:21 -04:00
Move all hashing to single function. Fix minor bug and make mode clear.
This commit is contained in:
parent
43d1d0299d
commit
a835ec16a6
36
src/lib.rs
36
src/lib.rs
|
|
@ -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()
|
||||
|
|
|
|||
11
src/main.rs
11
src/main.rs
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue