Unbreak no-default-features
In order to avoid problems with mutable references, the approach is to use the eval sender for non-parallel. Computations will still be done synchronously with the fake synchronous rayon module.
This commit is contained in:
parent
43735086d1
commit
4ef92089d5
1 changed files with 1 additions and 30 deletions
|
|
@ -17,7 +17,6 @@ use rayon;
|
|||
use rayon::prelude::*;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering::SeqCst;
|
||||
#[cfg(feature = "parallel")]
|
||||
use std::sync::mpsc::*;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
|
@ -47,46 +46,30 @@ pub(crate) struct Evaluator {
|
|||
nth: AtomicUsize,
|
||||
best_candidate_size: Arc<AtomicMin>,
|
||||
/// images are sent to the thread for evaluation
|
||||
#[cfg(feature = "parallel")]
|
||||
eval_send: SyncSender<Candidate>,
|
||||
// the thread helps evaluate images asynchronously
|
||||
#[cfg(feature = "parallel")]
|
||||
eval_thread: thread::JoinHandle<Option<Candidate>>,
|
||||
// in non-parallel mode, images are evaluated synchronously
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
eval_best_candidate: Option<Candidate>,
|
||||
}
|
||||
|
||||
impl Evaluator {
|
||||
pub fn new(deadline: Arc<Deadline>) -> Self {
|
||||
#[cfg(feature = "parallel")]
|
||||
let (tx, rx) = sync_channel(4);
|
||||
Self {
|
||||
deadline,
|
||||
best_candidate_size: Arc::new(AtomicMin::new(None)),
|
||||
nth: AtomicUsize::new(0),
|
||||
#[cfg(feature = "parallel")]
|
||||
eval_send: tx,
|
||||
#[cfg(feature = "parallel")]
|
||||
eval_thread: thread::spawn(move || rx.into_iter().min_by_key(Candidate::cmp_key)),
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
eval_best_candidate: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Wait for all evaluations to finish and return smallest reduction
|
||||
/// Or `None` if all reductions were worse than baseline.
|
||||
#[cfg(feature = "parallel")]
|
||||
fn get_best_candidate(self) -> Option<Candidate> {
|
||||
drop(self.eval_send); // disconnect the sender, breaking the loop in the thread
|
||||
self.eval_thread.join().expect("eval thread")
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
fn get_best_candidate(self) -> Option<Candidate> {
|
||||
self.eval_best_candidate
|
||||
}
|
||||
|
||||
pub fn get_result(self) -> Option<PngData> {
|
||||
self.get_best_candidate().map(|candidate| candidate.image)
|
||||
}
|
||||
|
|
@ -108,7 +91,6 @@ impl Evaluator {
|
|||
let best_candidate_size = self.best_candidate_size.clone();
|
||||
// sends it off asynchronously for compression,
|
||||
// but results will be collected via the message queue
|
||||
#[cfg(feature = "parallel")]
|
||||
let eval_send = self.eval_send.clone();
|
||||
rayon::spawn(move || {
|
||||
let filters_iter = STD_FILTERS.par_iter().with_max_len(1);
|
||||
|
|
@ -144,18 +126,7 @@ impl Evaluator {
|
|||
nth,
|
||||
};
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
{
|
||||
eval_send.send(new).expect("send");
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
{
|
||||
match self.eval_best_candidate {
|
||||
Some(prev) if prev.cmp_key() < new.cmp_key() => {}
|
||||
_ => self.eval_best_candidate = Some(new),
|
||||
}
|
||||
}
|
||||
eval_send.send(new).expect("send");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue