|
|
|
@ -80,7 +80,7 @@ fn absolute(path: impl AsRef<std::path::Path>) -> std::path::PathBuf
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature="threads")]
|
|
|
|
|
async fn rebase_one_async(path: impl AsRef<std::path::Path>, hash: hash::Sha256Hash) -> Result<Option<(std::path::PathBuf, hash::Sha256Hash)>, error::Error>
|
|
|
|
|
async fn rebase_one_async(path: impl AsRef<std::path::Path>, hash: hash::Sha256Hash, semaphore: Option<std::sync::Arc<tokio::sync::Semaphore>>) -> Result<Option<(std::path::PathBuf, hash::Sha256Hash)>, error::Error>
|
|
|
|
|
{
|
|
|
|
|
use std::{
|
|
|
|
|
convert::TryInto,
|
|
|
|
@ -91,6 +91,10 @@ async fn rebase_one_async(path: impl AsRef<std::path::Path>, hash: hash::Sha256H
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
let path = path.as_ref();
|
|
|
|
|
let _lock = match semaphore {
|
|
|
|
|
Some(sem) => Some(sem.acquire_owned().await),
|
|
|
|
|
None => None,
|
|
|
|
|
};
|
|
|
|
|
let mut file = OpenOptions::new()
|
|
|
|
|
.read(true)
|
|
|
|
|
.open(path).await?;
|
|
|
|
@ -113,11 +117,13 @@ async fn rebase(config: config::Rebase) -> Result<(), Box<dyn std::error::Error>
|
|
|
|
|
path::{
|
|
|
|
|
Path,
|
|
|
|
|
},
|
|
|
|
|
sync::Arc,
|
|
|
|
|
};
|
|
|
|
|
use tokio::{
|
|
|
|
|
fs::{
|
|
|
|
|
OpenOptions,
|
|
|
|
|
},
|
|
|
|
|
sync::Semaphore,
|
|
|
|
|
};
|
|
|
|
|
let mut hashes = container::DupeMap::new();
|
|
|
|
|
for (transient, load) in config.load.iter().map(|x| (false, x)).chain(config.save.iter().map(|x| (true, x)))
|
|
|
|
@ -140,6 +146,7 @@ async fn rebase(config: config::Rebase) -> Result<(), Box<dyn std::error::Error>
|
|
|
|
|
|
|
|
|
|
let mut remove = Vec::new();
|
|
|
|
|
let mut children = Vec::with_capacity(hashes.cache_len());
|
|
|
|
|
let semaphore = config.max_threads.map(|num| Arc::new(Semaphore::new(num.into())));
|
|
|
|
|
for (path, (hash, trans)) in hashes.cache_iter()
|
|
|
|
|
{
|
|
|
|
|
if !trans { //Don't rebuild transient ones, this is desired I think? Maybe not... Dunno.
|
|
|
|
@ -147,8 +154,9 @@ async fn rebase(config: config::Rebase) -> Result<(), Box<dyn std::error::Error>
|
|
|
|
|
//Getting hash
|
|
|
|
|
let path = path.clone();
|
|
|
|
|
let hash = *hash;
|
|
|
|
|
let semaphore = semaphore.as_ref().map(|semaphore| Arc::clone(semaphore));
|
|
|
|
|
children.push(tokio::task::spawn(async move {
|
|
|
|
|
rebase_one_async(path, hash).await
|
|
|
|
|
rebase_one_async(path, hash, semaphore).await
|
|
|
|
|
}));
|
|
|
|
|
} else {
|
|
|
|
|
remove.push(path.clone());
|
|
|
|
@ -266,6 +274,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>>
|
|
|
|
|
log!(Debug, lmode => "Loaded hashes: {}", hashes);
|
|
|
|
|
log!(Info, lmode => "Starting checks (threaded)");
|
|
|
|
|
let hashes = Arc::new(Mutex::new(hashes));
|
|
|
|
|
let semaphore = args.max_threads.map(|num| Arc::new(tokio::sync::Semaphore::new(num.into())));
|
|
|
|
|
for path in args.paths.iter()
|
|
|
|
|
{
|
|
|
|
|
let path = Path::new(path);
|
|
|
|
@ -274,9 +283,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>>
|
|
|
|
|
let mode = args.mode.clone();
|
|
|
|
|
let path = absolute(&path);
|
|
|
|
|
let hashes= Arc::clone(&hashes);
|
|
|
|
|
let semaphore = semaphore.as_ref().map(|sem| Arc::clone(sem));
|
|
|
|
|
children.push(tokio::task::spawn(async move {
|
|
|
|
|
log!(Debug, mode.logging_mode => " + {:?}", path);
|
|
|
|
|
let res = mode.error_mode.handle(proc::do_dir_async(path.clone(), 0, hashes, mode.clone()).await).log_and_forget(&mode.logging_mode, log::Level::Error);
|
|
|
|
|
let res = mode.error_mode.handle(proc::do_dir_async(path.clone(), 0, hashes, mode.clone(), semaphore).await).log_and_forget(&mode.logging_mode, log::Level::Error);
|
|
|
|
|
log!(Info, mode.logging_mode => " - {:?}", path);
|
|
|
|
|
res
|
|
|
|
|
}));
|
|
|
|
|