From be70804d17087206ee9896a9a0fd3141eb40f635 Mon Sep 17 00:00:00 2001 From: Paul Masurel Date: Wed, 4 May 2022 16:43:04 +0900 Subject: [PATCH] Removed AtomicUsize. --- src/core/executor.rs | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/core/executor.rs b/src/core/executor.rs index f5e15d2b4..def78eb93 100644 --- a/src/core/executor.rs +++ b/src/core/executor.rs @@ -1,8 +1,8 @@ -use std::sync::atomic::AtomicUsize; - use crossbeam::channel; use rayon::{ThreadPool, ThreadPoolBuilder}; +use crate::TantivyError; + /// Search executor whether search request are single thread or multithread. /// /// We don't expose Rayon thread pool directly here for several reasons. @@ -55,10 +55,13 @@ impl Executor { let (fruit_sender, fruit_receiver) = channel::unbounded(); pool.scope(|scope| { for (idx, arg) in args.into_iter().enumerate() { - let idx = AtomicUsize::new(idx); - scope.spawn(|_| { - let fruit = f(arg); - if let Err(err) = fruit_sender.send((idx.into_inner(), fruit)) { + // We name references for f and fruit_sender_ref because we do not + // want these two to be moved into the closure. + let f_ref = &f; + let fruit_sender_ref = &fruit_sender; + scope.spawn(move |_| { + let fruit = f_ref(arg); + if let Err(err) = fruit_sender_ref.send((idx, fruit)) { error!( "Failed to send search task. It probably means all search \ threads have panicked. {:?}", @@ -73,18 +76,19 @@ impl Executor { // This is important as it makes it possible for the fruit_receiver iteration to // terminate. }; - // This is lame, but safe. - let mut results_with_position = Vec::with_capacity(num_fruits); + let mut result_placeholders: Vec> = + std::iter::repeat_with(|| None).take(num_fruits).collect(); for (pos, fruit_res) in fruit_receiver { let fruit = fruit_res?; - results_with_position.push((pos, fruit)); + result_placeholders[pos] = Some(fruit); } - results_with_position.sort_by_key(|(pos, _)| *pos); - assert_eq!(results_with_position.len(), num_fruits); - Ok(results_with_position - .into_iter() - .map(|(_, fruit)| fruit) - .collect::>()) + let results: Vec = result_placeholders.into_iter().flatten().collect(); + if results.len() != num_fruits { + return Err(TantivyError::InternalError( + "One of the mapped execution failed.".to_string(), + )); + } + Ok(results) } } }