From 2887f7b5ff31dae5ff786c2c10e7027990fd8c92 Mon Sep 17 00:00:00 2001 From: theMackabu Date: Thu, 21 Nov 2024 12:02:39 -0800 Subject: [PATCH] improve hashing layer --- maid/client/cli/mod.rs | 2 +- maid/client/task/cache.rs | 59 ++++++++++++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/maid/client/cli/mod.rs b/maid/client/cli/mod.rs index 71b1f2a..3fea755 100644 --- a/maid/client/cli/mod.rs +++ b/maid/client/cli/mod.rs @@ -181,7 +181,7 @@ pub fn exec(task: &str, args: &Vec, path: &String, silent: bool, is_dep: config_path.clone(), toml::to_string(&CacheConfig { target: cache.target, - hash: hash.clone(), + hash: hash.to_owned(), }) .unwrap(), ) { diff --git a/maid/client/task/cache.rs b/maid/client/task/cache.rs index 633ce2d..d6b0f9e 100644 --- a/maid/client/task/cache.rs +++ b/maid/client/task/cache.rs @@ -1,11 +1,56 @@ -use macros_rs::crashln; -use merkle_hash::{bytes_to_hex, Algorithm, MerkleTree}; +use maid::log::prelude::*; +use merkle_hash::{Algorithm, MerkleTree}; +use std::path::Path; -pub fn create_hash(path: &str) -> String { - let tree = match MerkleTree::builder(path).algorithm(Algorithm::Blake3).hash_names(false).build() { - Ok(v) => v, - Err(e) => crashln!("Invalid UTF-8 sequence: {}", e), +const DEFAULT_HASH: &str = "0000000000000000000000000000000000000000000000000000000000000000"; + +fn bytes_to_hex(bytes: impl AsRef<[u8]>) -> &'static str { + const TABLE: &[u8; 16] = b"0123456789abcdef"; + static mut HEX_BUFFER: [u8; 1024] = [0; 1024]; + + let bytes = bytes.as_ref(); + let len = bytes.len(); + + // Safety: we ensure exclusive access and stay within bounds + unsafe { + let buf = &mut HEX_BUFFER[..(len * 2)]; + + for (i, &byte) in bytes.iter().enumerate() { + let idx = i * 2; + buf[idx] = TABLE[(byte >> 4) as usize]; + buf[idx + 1] = TABLE[(byte & 0xf) as usize]; + } + + std::str::from_utf8_unchecked(&buf[..(len * 2)]) + } +} + +pub fn create_hash<'hash>(path: impl AsRef) -> &'hash str { + let path = path.as_ref(); + + if !path.exists() { + warn!("Path does not exist: {}", path.display()); + return DEFAULT_HASH; + } + + let path = match path.to_str() { + Some(path) => path, + None => return DEFAULT_HASH, }; - bytes_to_hex(tree.root.item.hash) + match MerkleTree::builder(path) + .algorithm(Algorithm::Blake3) + .hash_names(false) + .build() + { + Ok(tree) => { + let hash = bytes_to_hex(tree.root.item.hash); + debug!(path, "Successfully created tree hash"); + return hash; + } + Err(err) => { + warn!(%err, path, "Failed to create tree hash"); + return DEFAULT_HASH; + } + }; } -- GitLab