Skip to content

Commit

Permalink
Refactor the checking algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
breard-r committed Nov 21, 2024
1 parent 95f48f7 commit a6b7166
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 71 deletions.
84 changes: 43 additions & 41 deletions src/check.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::files::HashedFile;
use dioxus_logger::tracing::warn;
use std::collections::HashSet;
use crate::files::{HashedFile, HashedFileList};
use dioxus_logger::tracing::{info, warn};
use std::collections::{HashMap, HashSet};
use std::fmt;
use std::path::PathBuf;

Expand Down Expand Up @@ -55,61 +55,63 @@ impl CheckResult {
}
}

macro_rules! populate_map {
($dest_map: ident, $from_lst: ident, $base_dir: ident, $errors: ident, $t: ident, $add_err: expr) => {
for ref_file in $from_lst.get_files() {
let hash = ref_file.get_hash();
let rel_path = ref_file.get_relative_path();
let ref_file =
HashedFile::new_base_dir($base_dir, rel_path, 0, hash, ref_file.get_hash_func());
match ref_file.get_absolute_path() {
Ok(absolute_path) => {
$dest_map.insert(absolute_path, ref_file);
}
Err(_) => {
if $add_err {
add_missing_file(&mut $errors, &ref_file, $t);
}
}
};
}
};
}

pub fn check(
calculated_set: &Vec<HashedFile>,
reference_set: &Vec<HashedFile>,
calculated_fl: &HashedFileList,
reference_fl: &HashedFileList,
t: CheckType,
) -> CheckResult {
info!("Starting fingerprint check");
let mut errors = HashSet::new();
let base_dir = calculated_fl.get_base_dir();

for ref_file in reference_set {
// Get the canonical absolute path of the reference file.
match ref_file.get_absolute_path() {
Ok(ref_file_abs_path) => {
// We have the canonical absolute path of the reference file.
// Now, let's check if we can find it in the calculated set.
match get_calc_file(calculated_set, ref_file_abs_path) {
Ok(calc_file) => {
if ref_file.get_hash() != calc_file.get_hash() {
// The hashes from both files does not match.
add_non_matching_file(&mut errors, ref_file, t);
}
}
Err(_) => {
// No matching file found in the calculated set.
add_missing_file(&mut errors, ref_file, t);
}
};
let mut reference_map = HashMap::with_capacity(reference_fl.len());
populate_map!(reference_map, reference_fl, base_dir, errors, t, true);
let mut calculated_map = HashMap::with_capacity(calculated_fl.len());
populate_map!(calculated_map, calculated_fl, base_dir, errors, t, false);

for (path, ref_file) in reference_map.iter() {
match calculated_map.get(path) {
Some(calc_file) => {
if calc_file.get_hash() != ref_file.get_hash() {
add_non_matching_file(&mut errors, ref_file, t);
}
}
Err(_) => {
// Unable to get the canonical path: the file does not exists on disk.
None => {
add_missing_file(&mut errors, ref_file, t);
}
};
}
}

// Return the result
if errors.is_empty() {
info!("Fingerprint check done: ok");
CheckResult::Ok
} else {
warn!("Fingerprint check done: {} errors", errors.len());
CheckResult::Error(errors.into_iter().collect())
}
}

fn get_calc_file(
calculated_set: &Vec<HashedFile>,
ref_file_abs_path: PathBuf,
) -> Result<&HashedFile, ()> {
for calc_file in calculated_set {
if let Ok(calc_file_abs_path) = calc_file.get_absolute_path() {
if calc_file_abs_path == ref_file_abs_path {
return Ok(calc_file);
}
}
}
Err(())
}

#[inline]
fn add_missing_file(errors: &mut HashSet<CheckResultError>, file: &HashedFile, t: CheckType) {
let path = file.get_relative_path().to_path_buf();
Expand Down
32 changes: 18 additions & 14 deletions src/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,19 +296,8 @@ impl HashedFileList {
}
}

pub fn get_files(&self, base_dir: &Path) -> Vec<HashedFile> {
self.files
.values()
.map(|v| {
let mut f = v.clone();
f.base_dir = base_dir.to_path_buf();
f
})
.collect()
}

pub fn get_files_no_base_dir(&self) -> Vec<HashedFile> {
self.get_files(PathBuf::new().as_path())
pub fn get_files(&self) -> std::collections::hash_map::Values<FileId, HashedFile> {
self.files.values()
}

pub fn insert_file(&mut self, file: HashedFile) {
Expand Down Expand Up @@ -457,9 +446,24 @@ impl HashedFile {
where
P: AsRef<Path>,
S: AsRef<str>,
{
HashedFile::new_base_dir(PathBuf::new(), relative_path, size, hash, hash_func)
}

pub fn new_base_dir<P1, P2, S>(
base_dir: P1,
relative_path: P2,
size: u64,
hash: S,
hash_func: HashFunc,
) -> Self
where
P1: AsRef<Path>,
P2: AsRef<Path>,
S: AsRef<str>,
{
Self {
base_dir: PathBuf::new(),
base_dir: base_dir.as_ref().into(),
relative_path: relative_path.as_ref().to_path_buf(),
size,
hash: hash.as_ref().into(),
Expand Down
6 changes: 3 additions & 3 deletions src/receipt.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::files::{HashedFile, HashedFileList};
use crate::files::HashedFileList;
use crate::hash::HashFunc;
use crate::parsers::{
cksum_bsd_get_files, cksum_gnu_get_files, cnil_content_file_get_files,
Expand Down Expand Up @@ -31,8 +31,8 @@ impl Receipt {
})
}

pub fn get_files(&self, base_dir: &Path) -> Vec<HashedFile> {
self.files.get_files(base_dir)
pub fn get_file_list(&self) -> &HashedFileList {
&self.files
}

pub fn get_main_hashing_function(&self) -> HashFunc {
Expand Down
4 changes: 2 additions & 2 deletions src/serializers/ctn_file_cksum_bsd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::fs::File;
use std::io::{self, Write};

pub fn ctn_file_cksum_bsd(ctn_file: &mut File, hashed_list: &HashedFileList) -> io::Result<()> {
for file in hashed_list.get_files_no_base_dir() {
let line = format_line(&file);
for file in hashed_list.get_files() {
let line = format_line(file);
ctn_file.write_all(line.as_bytes())?;
}
Ok(())
Expand Down
4 changes: 2 additions & 2 deletions src/serializers/ctn_file_cksum_gnu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::fs::File;
use std::io::{self, Write};

pub fn ctn_file_cksum_gnu(ctn_file: &mut File, hashed_list: &HashedFileList) -> io::Result<()> {
for file in hashed_list.get_files_no_base_dir() {
let line = format_line(&file);
for file in hashed_list.get_files() {
let line = format_line(file);
ctn_file.write_all(line.as_bytes())?;
}
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion src/serializers/ctn_file_cnil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub fn ctn_file_cnil(ctn_file: &mut File, hashed_list: &HashedFileList) -> io::R
"Taille (octets)",
hashed_list.get_main_hashing_function()
);
for file in hashed_list.get_files_no_base_dir() {
for file in hashed_list.get_files() {
write_line!(
ctn_file,
file.get_relative_path().display(),
Expand Down
11 changes: 3 additions & 8 deletions src/views/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,6 @@ async fn calc_fingerprints(

// Checking fingerprints against the content file
info!("Checking fingerprints against the content file");
let hashed_file_lst = hashed_file_list.get_files(base_dir);
if let Ok(ctn_file_path) =
hashed_file_list.get_content_file_absolute_path(&config)
{
Expand All @@ -302,8 +301,8 @@ async fn calc_fingerprints(
match Receipt::new(&ctn_file_path, default_hash) {
Ok(ctn_file) => {
match check(
&hashed_file_lst,
&ctn_file.get_files(base_dir),
&hashed_file_list,
ctn_file.get_file_list(),
CheckType::ContentFile,
) {
CheckResult::Ok => hashed_file_list.set_result_ok(),
Expand All @@ -325,11 +324,7 @@ async fn calc_fingerprints(
// Checking fingerprints against the receipt
if let Some(rcpt) = receipt_opt {
info!("Checking fingerprints against the receipt");
match check(
&hashed_file_lst,
&rcpt.get_files(base_dir),
CheckType::Receipt,
) {
match check(&hashed_file_list, rcpt.get_file_list(), CheckType::Receipt) {
CheckResult::Ok => {
if !hashed_file_list.get_result().is_err() {
hashed_file_list.set_result_ok()
Expand Down

0 comments on commit a6b7166

Please sign in to comment.