### Example Micropool Output Source: https://docs.rs/micropool/latest/micropool/index.html This is a possible output from the scheduling system example, illustrating the order of thread execution and task completion. Note how different threads handle synchronous and asynchronous tasks. ```text A ThreadId(1) // The main thread is #1 D ThreadId(2) // Thread #2 begins helping the outer micropool::join call C ThreadId(1) // Thread #1 helps to finish the outer micropool::join call F ThreadId(1) // Thread #1 steals work from thread #2, to help complete the inner micropool::join call E ThreadId(2) // Thread #2 finishes the inner micropool::join call B ThreadId(2) // Thread #2 grabs and completes the background task; thread #1 should not execute this ``` -------------------------------- ### ZipableSource Example Usage Source: https://docs.rs/micropool/latest/micropool/iter/trait.ZipableSource.html Demonstrates the usage of zip_eq with two sources, asserting the expected sums. ```rust assert_eq!(sum_left, 5 * 3); // 1 + ... + 5 assert_eq!(sum_right, 50 + 5 * 3); // 11 + ... + 15 ``` -------------------------------- ### try_fold_per_thread Example with Ok Result Source: https://docs.rs/micropool/latest/micropool/iter/trait.ParallelIteratorExt.html Demonstrates using try_fold_per_thread to accumulate results into nested vectors. This example shows a successful fold where all operations return Ok. ```rust let input: [Result; 8] = [Ok(1), Ok(2), Ok(3), Ok(4), Ok(5), Ok(6), Ok(7), Ok(8)]; let collection: Result>, i32> = input .par_iter() .copied() .with_thread_pool(&mut thread_pool) .try_fold_per_thread( Vec::new, |mut vec, x| -> Result, i32> { vec.push(x?); Ok(vec) }, Vec::with_capacity, |mut vecvec, vec| { vecvec.push(vec?); Ok(vecvec) }, ); assert!(collection.is_ok()); let mut values: Vec = collection.unwrap().into_iter().flatten().collect(); values.sort_unstable(); assert_eq!(values, &[1, 2, 3, 4, 5, 6, 7, 8]); ``` -------------------------------- ### step_by(n: usize) Source: https://docs.rs/micropool/latest/micropool/iter/struct.MutSliceParallelSource.html Returns a parallel source that produces every `n`-th item from this source, starting with the first one. ```APIDOC ## step_by(n: usize) ### Description Returns a parallel source that produces every `n`-th item from this source, starting with the first one. ### Method `step_by` ### Parameters #### Path Parameters - **n** (usize) - Required - The step size. ``` -------------------------------- ### step_by Source: https://docs.rs/micropool/latest/micropool/iter/struct.TakeExact.html Returns a parallel source that produces every `n`-th item from this source, starting with the first one. ```APIDOC ## step_by ### Description Returns a parallel source that produces every `n`-th item from this source, starting with the first one. ### Method Signature ```rust fn step_by(self, n: usize) -> StepBy ``` ``` -------------------------------- ### try_reduce Example with Successful Reduction Source: https://docs.rs/micropool/latest/micropool/iter/trait.ParallelIteratorExt.html Illustrates using try_reduce to sum elements of a parallel iterator, with a successful reduction. The initializer provides the starting value, and the combining function handles potential overflow. ```rust let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let sum = input .par_iter() .copied() .with_thread_pool(&mut thread_pool) .try_reduce(|| 0i32, |x, y| x.checked_add(y).ok_or("error")); assert_eq!(sum, Ok(5 * 11)); ``` -------------------------------- ### par_iter_mut Method Example Source: https://docs.rs/micropool/latest/micropool/iter/trait.IntoExactParallelRefMutSource.html Example demonstrating the usage of the par_iter_mut method to perform parallel mutation on a collection. ```APIDOC ## fn par_iter_mut(&'data mut self) -> Self::Source Converts `&mut self` into a parallel source. ### Example ```rust let mut values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; values .par_iter_mut() .with_thread_pool(&mut thread_pool) // Assuming thread_pool is available .for_each(|x| { *x *= 2; }); assert_eq!(values, [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]); ``` ``` -------------------------------- ### Install Local Advertise Mask Source: https://docs.rs/micropool/latest/src/micropool/thread_pool.rs.html Installs a thread-local mask for advertising available jobs and executes a closure. It restores the previous mask after the closure completes, ensuring thread-local state is managed correctly. Panics are handled by `abort_on_panic`. ```rust fn install_local_advertise_mask(mask: &AtomicBits, f: impl FnOnce() -> R) -> R { abort_on_panic(|| { let previous = LOCAL_ADVERTISE_MASK.get(); LOCAL_ADVERTISE_MASK.set(mask); let result = f(); LOCAL_ADVERTISE_MASK.set(previous); result }) } ``` -------------------------------- ### Zipping Unequal Length Iterators with zip_eq (Panic Example) Source: https://docs.rs/micropool/latest/micropool/iter/trait.ZipableSource.html This example demonstrates that zip_eq will panic when used with iterators of unequal lengths. It's included to highlight the behavior. ```rust let left = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let right = [11, 12, 13, 14, 15]; let _ = (left.par_iter(), right.par_iter()) .zip_eq() .with_thread_pool(&mut thread_pool) .map(|(&a, &b)| (a, b)) .reduce(|| (0, 0), |(a, b), (c, d)| (a + c, b + d)); ``` -------------------------------- ### try_for_each_init Example Source: https://docs.rs/micropool/latest/micropool/iter/trait.ParallelIteratorExt.html Demonstrates using try_for_each_init to process items in parallel with a thread-local initializer and a fallible operation. It breaks early on the first error encountered. ```rust use rand::RngExt; let set = Mutex::new(HashSet::new()); let result = (0..257) .into_par_iter() .with_thread_pool(&mut thread_pool) .try_for_each_init( rand::rng, // A thread-local RNG that is neither Send nor Sync. |rng, _| { let byte: u8 = rng.random(); if set.lock().unwrap().insert(byte) { Ok(()) } else { Err(byte) } }, ); // Even a biased random number generator cannot yield more than 256 distinct bytes. assert!(result.is_err()); ``` -------------------------------- ### Illustrate Micropool Scheduling Properties Source: https://docs.rs/micropool/latest/micropool/index.html This example demonstrates the core properties of the micropool scheduling system, including the execution of synchronous and asynchronous tasks, and how threads assist in completing join operations. Observe the thread IDs to understand work stealing and task execution order. ```rust println!("A {:?}", std::thread::current().id()); let background_task = micropool::spawn_owned(|| println!("B {:?}", std::thread::current().id())); micropool::join(|| { std::thread::sleep(std::time::Duration::from_millis(20)); println!("C {:?}", std::thread::current().id()) }, || { println!("D {:?}", std::thread::current().id()); micropool::join(|| { std::thread::sleep(std::time::Duration::from_millis(200)); println!("E {:?}", std::thread::current().id()); }, || { println!("F {:?}", std::thread::current().id()); }); }); ``` -------------------------------- ### Step Through Parallel Source Source: https://docs.rs/micropool/latest/micropool/iter/trait.ExactParallelSourceExt.html Produces every `n`-th item from a parallel source, starting with the first. ```Rust let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let sum = input .par_iter() .step_by(2) .with_thread_pool(&mut thread_pool) .sum::(); assert_eq!(sum, 1 + 3 + 5 + 7 + 9); let sum = input .par_iter() .step_by(3) .with_thread_pool(&mut thread_pool) .sum::(); assert_eq!(sum, 1 + 4 + 7 + 10); ``` -------------------------------- ### try_for_each Example with Early Error Return Source: https://docs.rs/micropool/latest/micropool/iter/trait.ParallelIteratorExt.html Shows how try_for_each stops execution and returns an error immediately when a closure returns Err. This example simulates a duplicate item causing an error. ```rust let input = [1, 1, 1, 1, 1, 6, 7, 8, 9, 10]; let set = Mutex::new(HashSet::new()); let result = input .par_iter() .with_thread_pool(&mut thread_pool) .try_for_each(|&x| { if set.lock().unwrap().insert(x) { Ok(()) } else { Err(x) } }); assert_eq!(result, Err(1)); ``` -------------------------------- ### Spawning and Joining Many Tasks Source: https://docs.rs/micropool/latest/src/micropool/lib.rs.html Shows how to spawn multiple tasks using `spawn_owned` and then join them to retrieve results. This example includes tasks that simulate work with `thread::sleep`. Note that tasks with longer sleep durations will take longer to complete. ```rust let first_task = crate::spawn_owned(|| 2); let second_task = crate::spawn_owned(|| 2); assert_eq!(first_task.join(), second_task.join()); for _ in 0..1000 { let third_task = crate::spawn_owned(|| std::thread::sleep(std::time::Duration::new(0, 10))); let fourth_task = crate::spawn_owned(|| std::thread::sleep(std::time::Duration::new(0, 200))); assert_eq!(third_task.join(), fourth_task.join()); } ``` -------------------------------- ### Creating and using RangeInclusiveParallelSource Source: https://docs.rs/micropool/latest/micropool/iter/struct.RangeInclusiveParallelSource.html Demonstrates how to create a RangeInclusiveParallelSource from a usize range and compute its sum in parallel using a thread pool. This example requires a pre-configured thread pool. ```rust let iter: RangeInclusiveParallelSource = (1..=10).into_par_iter(); let sum = iter.with_thread_pool(&mut thread_pool).sum::(); assert_eq!(sum, 5 * 11); ``` -------------------------------- ### try_reduce Example with Empty Iterator Source: https://docs.rs/micropool/latest/micropool/iter/trait.ParallelIteratorExt.html Demonstrates the behavior of try_reduce with an empty parallel iterator. It returns the initial value provided by the initializer function. ```rust let sum = [] .par_iter() .copied() .with_thread_pool(&mut thread_pool) .try_reduce(|| 0i32, |x, y| x.checked_add(y).ok_or("error")); assert_eq!(sum, Ok(0)); ``` -------------------------------- ### try_collect with a non-exact source Source: https://docs.rs/micropool/latest/micropool/iter/struct.BaseExactParallelIterator.html This example shows that try_collect will not work if the pipeline is not exact after a filter operation. The source must remain exact throughout. ```rust let collection: Result, ()> = (1..=10) .into_par_iter() .filter(|x| *x % 2 == 0) // After this, the pipeline isn't exact anymore. .map(Ok) .with_thread_pool(&mut thread_pool) .try_collect(); ``` -------------------------------- ### ThreadPoolState Initialization Source: https://docs.rs/micropool/latest/src/micropool/thread_pool.rs.html Initializes the internal state for a `ThreadPool`, including setting up atomic bitmasks for job management, event handling, and thread synchronization primitives. This is part of the thread pool's setup process. ```rust pub fn new(builder: &ThreadPoolBuilder) -> Self { let global_advertise_mask = AtomicBits::new(builder.max_jobs); let running_jobs = AtomicBits::new(builder.max_jobs); Self { global_advertise_mask, idle_spin_cycles: builder.idle_spin_cycles, jobs: repeat_with(JobSlot::default) .take(running_jobs.len()) .collect(), num_threads: builder.num_threads, on_change: Event::new(), running_jobs, should_stop: AtomicBool::new(false), tasks: spin::Mutex::new(VecDeque::new()), } } ``` -------------------------------- ### take Source: https://docs.rs/micropool/latest/micropool/iter/struct.VecDequeRefMutParallelSource.html Returns a parallel source that produces the first `n` items. ```APIDOC #### fn take(self, n: usize) -> Take Returns a parallel source that produces the first `n` items from this source, or all the items if this source has fewer than `n` items. Read more ``` -------------------------------- ### take Source: https://docs.rs/micropool/latest/micropool/iter/struct.VecDequeRefParallelSource.html Returns a parallel source that produces the first `n` items from this source. ```APIDOC ## take ### Description Returns a parallel source that produces the first `n` items from this source, or all the items if this source has fewer than `n` items. ### Method `take(n: usize)` ### Parameters #### Path Parameters - **n** (usize) - The maximum number of items to take. ### Returns A new parallel source that yields at most `n` items. ``` -------------------------------- ### take Source: https://docs.rs/micropool/latest/micropool/iter/struct.MapInit.html Creates a new parallel source that yields at most the first N elements. ```APIDOC ## take ### Description Returns a parallel source that produces the first `n` items from this source, or all the items if this source has fewer than `n` items. ### Signature fn take(self, n: usize) -> Take ``` -------------------------------- ### Get Type ID for Any Trait Source: https://docs.rs/micropool/latest/micropool/struct.OwnedTask.html Implements the Any trait for any type T, providing a method to get the TypeId of the instance. ```rust fn type_id(&self) -> TypeId; ``` -------------------------------- ### Try to Get SharedTask Result Source: https://docs.rs/micropool/latest/micropool/struct.SharedTask.html Attempts to get the result of a SharedTask if completed. Returns the original task if not yet completed. ```rust pub fn try_join(&self) -> Option<&T> ``` -------------------------------- ### try_for_each Example with No Errors Source: https://docs.rs/micropool/latest/micropool/iter/trait.ParallelIteratorExt.html Demonstrates the use of try_for_each to process each item of a parallel iterator with a fallible closure. This example shows a successful execution where all closures return Ok. ```rust let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let set = Mutex::new(HashSet::new()); let result = input .par_iter() .with_thread_pool(&mut thread_pool) .try_for_each(|&x| { if set.lock().unwrap().insert(x) { Ok(()) } else { Err(x) } }); assert_eq!(result, Ok(())); assert_eq!(set.into_inner().unwrap(), (1..=10).collect()); ``` -------------------------------- ### take Source: https://docs.rs/micropool/latest/micropool/iter/struct.SliceParallelSource.html Returns a parallel source that produces the first `n` items from this source, or all the items if this source has fewer than `n` items. ```APIDOC ## take ### Description Returns a parallel source that produces the first `n` items from this source, or all the items if this source has fewer than `n` items. ### Parameters #### Query Parameters - **n** (usize) - Required - The maximum number of items to take. ### Signature `fn take(self, n: usize) -> Take` ``` -------------------------------- ### take Source: https://docs.rs/micropool/latest/micropool/iter/trait.ExactParallelSourceExt.html Takes the first `n` items. ```APIDOC ## take ### Description Takes the first `n` items. ### Signature ```rust fn take(self, n: usize) -> Take ``` ``` -------------------------------- ### step_by Source: https://docs.rs/micropool/latest/micropool/iter/struct.MapInit.html Creates a new parallel source that yields every Nth element. ```APIDOC ## step_by ### Description Returns a parallel source that produces every `n`-th item from this source, starting with the first one. ### Signature fn step_by(self, n: usize) -> StepBy ``` -------------------------------- ### type_id Source: https://docs.rs/micropool/latest/micropool/iter/enum.MinMaxResult.html Gets the TypeId of the object. ```APIDOC ## fn type_id(&self) -> TypeId ### Description Gets the `TypeId` of `self`. ### Method `type_id` ### Parameters None ### Response - **TypeId**: The unique identifier for the type. ``` -------------------------------- ### step_by Source: https://docs.rs/micropool/latest/micropool/iter/struct.VecDequeRefMutParallelSource.html Returns a parallel source that produces every `n`-th item. ```APIDOC #### fn step_by(self, n: usize) -> StepBy Returns a parallel source that produces every `n`-th item from this source, starting with the first one. Read more ``` -------------------------------- ### OwnedTask::cancel Source: https://docs.rs/micropool/latest/src/micropool/task.rs.html Cancels this task, preventing it from running if it was not yet started. ```APIDOC ## OwnedTask::cancel ### Description Cancels this task, preventing it from running if it was not yet started. ### Method `OwnedTask::cancel` ### Parameters - `self` (OwnedTask): The task to cancel. This consumes the task. ### Returns - `()`: This method does not return a value. ``` -------------------------------- ### Get TypeId of an item Source: https://docs.rs/micropool/latest/micropool/iter/struct.FilterMap.html Retrieves the `TypeId` of an item. This is part of the `Any` trait implementation. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Get Length of AtomicBits Source: https://docs.rs/micropool/latest/src/micropool/thread_pool.rs.html Returns the total number of bits that can be stored in the AtomicBits array. ```rust pub fn len(&self) -> usize { Self::ELEMENT_BITS * self.0.len() } ``` -------------------------------- ### MapInit Source: https://docs.rs/micropool/latest/micropool/iter/index.html This struct is created by the `map_init()` method on `ParallelSourceExt` and `map_init()` on `ExactParallelSourceExt`. ```APIDOC ## Struct: MapInit ### Description Represents a parallel iterator that maps items using a closure that can be initialized. Created using the `map_init()` method. ### Usage Can be created from `ParallelSourceExt::map_init()` or `ExactParallelSourceExt::map_init()`. ``` -------------------------------- ### Get Number of Threads in ThreadPool Source: https://docs.rs/micropool/latest/micropool/struct.ThreadPool.html Returns the total number of worker threads in this pool. ```rust pub fn num_threads(&self) -> usize ``` -------------------------------- ### step_by Source: https://docs.rs/micropool/latest/micropool/iter/struct.VecDequeRefParallelSource.html Returns a parallel source that produces every `n`-th item from this source. ```APIDOC ## step_by ### Description Returns a parallel source that produces every `n`-th item from this source, starting with the first one. ### Method `step_by(n: usize)` ### Parameters #### Path Parameters - **n** (usize) - The step interval. ### Returns A new parallel source that yields every `n`-th item. ``` -------------------------------- ### take(n: usize) Source: https://docs.rs/micropool/latest/micropool/iter/struct.MutSliceParallelSource.html Returns a parallel source that produces the first `n` items from this source, or all the items if this source has fewer than `n` items. ```APIDOC ## take(n: usize) ### Description Returns a parallel source that produces the first `n` items from this source, or all the items if this source has fewer than `n` items. ### Method `take` ### Parameters #### Path Parameters - **n** (usize) - Required - The maximum number of items to take. ``` -------------------------------- ### OwnedTask::try_join Source: https://docs.rs/micropool/latest/src/micropool/task.rs.html Attempts to get the result of this task if it has been completed. Otherwise, returns the original task. ```APIDOC ## OwnedTask::try_join ### Description Attempts to get the result of this task if it has been completed. Otherwise, returns the original task. ### Method `OwnedTask::try_join` ### Parameters - `self` (OwnedTask): The task to attempt to join. This consumes the task. ### Returns - `Result`: `Ok(T)` if the task was completed and the result is available, or `Err(OwnedTask)` if the task is not yet complete, returning the original task. ``` -------------------------------- ### TakeExact: Take a specific number of items Source: https://docs.rs/micropool/latest/micropool/iter/struct.SkipExact.html Returns a parallel source that produces the first `n` items from this source, panicking if this source has fewer than `n` items. ```rust fn take_exact(self, n: usize) -> TakeExact ``` -------------------------------- ### Cancel OwnedTask Source: https://docs.rs/micropool/latest/micropool/struct.OwnedTask.html Cancels an OwnedTask, preventing it from running if it has not yet started. This method consumes the task. ```rust pub fn cancel(self) -> (); ``` -------------------------------- ### try_from Source: https://docs.rs/micropool/latest/micropool/iter/struct.VecParallelSource.html Performs the conversion. ```APIDOC ## try_from ### Description Performs the conversion. ### Signature `fn try_from(value: U) -> Result>::Error>` ### Associated Types * `Error`: The type returned in the event of a conversion error. ``` -------------------------------- ### map_init Source: https://docs.rs/micropool/latest/micropool/iter/trait.ExactParallelSourceExt.html Maps each item using an initialized state. ```APIDOC ## map_init ### Description Maps each item using an initialized state. ### Signature ```rust fn map_init(self, init: Init, f: F) -> MapInit where Init: Fn() -> I + Sync, F: Fn(&mut I, Self::Item) -> T + Sync ``` ``` -------------------------------- ### map_init Source: https://docs.rs/micropool/latest/micropool/iter/struct.Rev.html Creates a new parallel source by applying a mapping function with per-thread initialization. ```APIDOC ## map_init ### Description Applies the function `f` to each item of this source, together with a per-thread mutable value returned by `init`, and returns a parallel source producing the mapped items. ### Method map_init ### Type Parameters - **I**: The type of the per-thread initialized value. - **Init**: The type of the initializer function, must implement `Fn() -> I + Sync`. - **T**: The type of the mapped items. - **F**: The type of the mapping function, must implement `Fn(&mut I, Self::Item) -> T + Sync`. ### Parameters - **init** (Init) - The initializer function for per-thread values. - **f** (F) - The mapping function that uses the initialized value and the item. ### Returns MapInit - A new parallel source with mapped items. ``` -------------------------------- ### VecDequeRefMutParallelSource Usage Example Source: https://docs.rs/micropool/latest/micropool/iter/struct.VecDequeRefMutParallelSource.html Demonstrates how to create and use VecDequeRefMutParallelSource to modify elements of a VecDeque in parallel. The elements must be Send. ```APIDOC ## VecDequeRefMutParallelSource ### Description A parallel source over a mutable reference to a `VecDeque`. This struct is created by the `par_iter_mut()` method on `IntoExactParallelRefMutSource`. ### Example ```rust use std::collections::VecDeque; let mut values: VecDeque<_> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect(); let iter: VecDequeRefMutParallelSource<_> = values.par_iter_mut(); iter.with_thread_pool(&mut thread_pool) // Assuming thread_pool is available .for_each(|x| *x *= 2); assert_eq!( values, [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] .into_iter() .collect::>() ); ``` ### Constraints The element type must be `Send`. ### Example (Invalid - Non-Send type) ```rust use std::rc::Rc; use std::collections::VecDeque; let mut values: VecDeque<_> = [Rc::new(1), Rc::new(2), Rc::new(3), Rc::new(4)] .into_iter() .collect(); let iter: VecDequeRefMutParallelSource<_> = values.par_iter_mut(); // This would not compile due to Rc not being Send ``` ``` -------------------------------- ### ExactSourceDescriptor Required Methods Source: https://docs.rs/micropool/latest/micropool/iter/trait.ExactSourceDescriptor.html Defines the methods for initializing thread context and fetching items by index. ```rust fn init(&self) -> Self::ThreadContext; ``` ```rust unsafe fn exact_fetch_item( &self, context: &mut Self::ThreadContext, index: usize, ) -> Self::Item; ``` -------------------------------- ### Cancel SharedTask Source: https://docs.rs/micropool/latest/micropool/struct.SharedTask.html Cancels a SharedTask, preventing it from running if not yet started. All clones must be cancelled for the effect to take hold. ```rust pub fn cancel(self) ``` -------------------------------- ### ThreadPool::install Source: https://docs.rs/micropool/latest/micropool/struct.ThreadPool.html Changes the current context to this thread pool. Any attempts to use `crate::join` or parallel iterators will operate within this pool. Panics if called recursively. ```APIDOC ## ThreadPool::install ### Description Changes the current context to this thread pool. Any attempts to use `crate::join` or parallel iterators will operate within this pool. Panics if called recursively. ### Signature `pub fn install(&self, f: impl FnOnce() -> R) -> R` ``` -------------------------------- ### try_collect_per_thread example Source: https://docs.rs/micropool/latest/micropool/iter/struct.BaseExactParallelIterator.html Collects results into a Vec of Vecs, where each inner Vec contains items processed by a thread. This is suitable for non-exact sources. ```rust use std::collections::HashSet; let collection: Result>, ()> = (1..=10) .into_par_iter() .filter(|x| *x % 2 == 0) .map(Ok) .with_thread_pool(&mut thread_pool) .try_collect_per_thread(); assert!(collection.is_ok()); // All even numbers will be in the resulting collection (in arbitrary order). let values: HashSet<_> = collection.unwrap().into_iter().flatten().collect(); assert_eq!(values, [2, 4, 6, 8, 10].into_iter().collect()); ``` -------------------------------- ### Try to Join OwnedTask Source: https://docs.rs/micropool/latest/micropool/struct.OwnedTask.html Attempts to get the result of an OwnedTask if it has been completed. If not completed, it returns the original task. This method consumes the task. ```rust pub fn try_join(self) -> Result; ``` -------------------------------- ### Zipping Arrays with zip_eq Source: https://docs.rs/micropool/latest/micropool/iter/trait.ZipableSource.html Demonstrates zipping multiple arrays using zip_eq to calculate sums across corresponding elements. Requires the 'rayon' crate for parallel iteration. ```rust use std::array; // arrays[0] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] // arrays[1] = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] // ... let arrays: [[i32; 10]; 20] = array::from_fn(|i| array::from_fn(|j| (10 * i + j) as i32)); let sums: [i32; 20] = arrays .each_ref() .map(|a| a.par_iter()) .zip_eq() .with_thread_pool(&mut thread_pool) .map(|a| a.map(|x| *x)) .reduce(|| [0; 20], |a, b| array::from_fn(|i| a[i] + b[i]])); // Each sum is: 100 * i + (0 + ... + 9) assert_eq!(sums, array::from_fn(|i| 100 * i as i32 + 45)); ``` -------------------------------- ### Get Owned Min and Max Elements Source: https://docs.rs/micropool/latest/micropool/iter/enum.MinMaxResult.html Consumes the MinMaxResult and returns both the minimal and maximal elements as a tuple if they exist. Requires `T: Clone`. ```rust assert_eq!(MinMaxResult::::NoElements.into_option(), None); assert_eq!(MinMaxResult::OneElement(42).into_option(), Some((42, 42))); assert_eq!( MinMaxResult::MinMax { min: 42, max: 123 }.into_option(), Some((42, 123)) ); ``` -------------------------------- ### Get References to Min and Max Elements Source: https://docs.rs/micropool/latest/micropool/iter/enum.MinMaxResult.html Returns references to both the minimal and maximal elements as a tuple if the MinMaxResult is not empty. Requires `T: Clone`. ```rust assert_eq!(MinMaxResult::::NoElements.as_option(), None); assert_eq!(MinMaxResult::OneElement(42).as_option(), Some((&42, &42))); assert_eq!( MinMaxResult::MinMax { min: 42, max: 123 }.as_option(), Some((&42, &123)) ); ``` -------------------------------- ### Using par_iter to sum elements in parallel Source: https://docs.rs/micropool/latest/micropool/iter/trait.IntoExactParallelRefSource.html Demonstrates how to use the `par_iter` method to create a parallel source and compute the sum of elements in a collection. ```rust let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let sum = input .par_iter() .with_thread_pool(&mut thread_pool) .sum::(); assert_eq!(sum, 5 * 11); ``` -------------------------------- ### Build and Initialize Global ThreadPool Source: https://docs.rs/micropool/latest/src/micropool/thread_pool.rs.html Initializes the global thread pool with the current `ThreadPoolBuilder` configuration. This is optional and panics if the global pool is already initialized. ```rust pub fn build_global(self) { let mut run = false; GLOBAL_POOL.call_once(|| { run = true; self.build() }); if !run { panic!("ThreadPoolBuilder::build_global called after global pool was already active"); } } ``` -------------------------------- ### Get Owned Maximum Element Source: https://docs.rs/micropool/latest/micropool/iter/enum.MinMaxResult.html Consumes the MinMaxResult and returns the maximal element if it exists. Use this when you need ownership of the maximum value. ```rust assert_eq!(MinMaxResult::::NoElements.into_max(), None); assert_eq!(MinMaxResult::OneElement(42).into_max(), Some(42)); assert_eq!( MinMaxResult::MinMax { min: 42, max: 123 }.into_max(), Some(123) ); ``` -------------------------------- ### Get Owned Minimum Element Source: https://docs.rs/micropool/latest/micropool/iter/enum.MinMaxResult.html Consumes the MinMaxResult and returns the minimal element if it exists. Use this when you need ownership of the minimum value. ```rust assert_eq!(MinMaxResult::::NoElements.into_min(), None); assert_eq!(MinMaxResult::OneElement(42).into_min(), Some(42)); assert_eq!( MinMaxResult::MinMax { min: 42, max: 123 }.into_min(), Some(42) ); ``` -------------------------------- ### MapInit ParallelSource Implementation Source: https://docs.rs/micropool/latest/micropool/iter/trait.ParallelSource.html Implements ParallelSource for a MapInit iterator, which initializes state and then maps items from an inner source. ```rust impl ParallelSource for MapInit where Inner: ParallelSource, Init: Fn() -> I + Sync, F: Fn(&mut I, ::Item) -> T + Sync, { type Item = T; } ``` -------------------------------- ### MapInit: Transform items with per-thread initialization Source: https://docs.rs/micropool/latest/micropool/iter/struct.SkipExact.html Applies a function to each item, using a per-thread mutable value initialized by `init`. Returns a parallel source producing the mapped items. ```rust fn map_init(self, init: Init, f: F) -> MapInit where Init: Fn() -> I + Sync, F: Fn(&mut I, Self::Item) -> T + Sync ``` -------------------------------- ### MutSliceParallelSource Usage Example Source: https://docs.rs/micropool/latest/micropool/iter/struct.MutSliceParallelSource.html Demonstrates how to create a MutSliceParallelSource from a mutable slice and process its elements in parallel. Ensure the thread pool is properly managed. ```rust let mut values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let iter: MutSliceParallelSource<_> = values.par_iter_mut(); iter.with_thread_pool(&mut thread_pool) .for_each(|x| *x *= 2); assert_eq!(values, [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]); ``` -------------------------------- ### ThreadPool::new Source: https://docs.rs/micropool/latest/src/micropool/thread_pool.rs.html Initializes a new thread pool with a given builder configuration. This is the primary way to create a new pool. ```APIDOC ## ThreadPool::new ### Description Initializes a new thread pool with the provided `ThreadPoolBuilder`. This method sets up the worker threads and the shared state for managing tasks. ### Signature ```rust fn new(builder: ThreadPoolBuilder) -> Self ``` ### Parameters * `builder` (ThreadPoolBuilder) - The configuration for the new thread pool, including the number of threads and the spawn handler. ``` -------------------------------- ### SourceCleanup Trait Definition Source: https://docs.rs/micropool/latest/micropool/iter/trait.SourceCleanup.html Defines the SourceCleanup trait with a boolean constant NEEDS_CLEANUP and methods for getting the source length and cleaning up item ranges. ```rust pub trait SourceCleanup { const NEEDS_CLEANUP: bool; // Required methods fn len(&self) -> usize; unsafe fn cleanup_item_range(&self, range: Range); } ``` -------------------------------- ### Creating and Summing VecParallelSource Source: https://docs.rs/micropool/latest/micropool/iter/struct.VecParallelSource.html Demonstrates how to create a VecParallelSource from a Vec and compute the sum of its elements using a thread pool. ```rust let input = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let iter: VecParallelSource<_> = input.into_par_iter(); let sum = iter.with_thread_pool(&mut thread_pool).sum::(); assert_eq!(sum, 5 * 11); ``` -------------------------------- ### as_option() method Source: https://docs.rs/micropool/latest/micropool/iter/enum.MinMaxResult.html Returns references to the minimal-maximal elements, if this result isn’t empty. ```APIDOC ## pub fn as_option(&self) -> Option<(&T, &T)> where T: Clone, Returns references to the minimal-maximal elements, if this result isn’t empty. ### Example ```rust assert_eq!(MinMaxResult::::NoElements.as_option(), None); assert_eq!(MinMaxResult::OneElement(42).as_option(), Some((&42, &42))); assert_eq!(MinMaxResult::MinMax { min: 42, max: 123 }.as_option(), Some((&42, &123))); ``` ``` -------------------------------- ### SharedTask::cancel Source: https://docs.rs/micropool/latest/src/micropool/task.rs.html Cancels this task, preventing it from running if it was not yet started. If this task was cloned, then `SharedTask::cancel` must be called on all clones to have an effect. ```APIDOC ## SharedTask::cancel ### Description Cancels this task, preventing it from running if it was not yet started. If this task was cloned, then `SharedTask::cancel` must be called on all clones to have an effect. ### Method `SharedTask::cancel` ### Parameters - `self` (SharedTask): The task to cancel. This consumes the task. ### Returns - `()`: This method does not return a value. ``` -------------------------------- ### new Method Source: https://docs.rs/micropool/latest/micropool/iter/trait.ExactParallelSink.html Creates a new parallel sink instance capable of collecting a specified number of items. ```rust fn new(len: usize) -> Self; ``` -------------------------------- ### Take: Take a number of items from a parallel source Source: https://docs.rs/micropool/latest/micropool/iter/struct.SkipExact.html Returns a parallel source that produces the first `n` items. If the source has fewer than `n` items, all items are produced. ```rust fn take(self, n: usize) -> Take ``` -------------------------------- ### Get Maximum Element Reference Source: https://docs.rs/micropool/latest/micropool/iter/enum.MinMaxResult.html Returns a reference to the maximal element if the MinMaxResult is not empty. Useful for inspecting the maximum value without consuming the result. ```rust assert_eq!(MinMaxResult::::NoElements.max(), None); assert_eq!(MinMaxResult::OneElement(42).max(), Some(&42)); assert_eq!(MinMaxResult::MinMax { min: 42, max: 123 }.max(), Some(&123)); ``` -------------------------------- ### Get Minimum Element Reference Source: https://docs.rs/micropool/latest/micropool/iter/enum.MinMaxResult.html Returns a reference to the minimal element if the MinMaxResult is not empty. Useful for inspecting the minimum value without consuming the result. ```rust assert_eq!(MinMaxResult::::NoElements.min(), None); assert_eq!(MinMaxResult::OneElement(42).min(), Some(&42)); assert_eq!(MinMaxResult::MinMax { min: 42, max: 123 }.min(), Some(&42)); ``` -------------------------------- ### TakeExact Source: https://docs.rs/micropool/latest/micropool/iter/index.html This struct is created by the `take_exact()` method on `ExactParallelSourceExt`. ```APIDOC ## Struct: TakeExact ### Description Represents a parallel iterator that yields exactly a specified number of elements. Created using the `take_exact()` method. ### Usage Created from `ExactParallelSourceExt::take_exact()`. ``` -------------------------------- ### try_for_each Example with Always Failing Closure Source: https://docs.rs/micropool/latest/micropool/iter/trait.ParallelIteratorExt.html Illustrates a scenario where the closure passed to try_for_each always returns an error. The function will return the first error encountered. ```rust let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let result = input .par_iter() .with_thread_pool(&mut thread_pool) .try_for_each(|&x| Err(x)); assert!(result.is_err()); ``` -------------------------------- ### ParallelSource Descriptor Method Source: https://docs.rs/micropool/latest/micropool/iter/trait.ParallelSource.html Returns an object describing how to fetch items from the source. This descriptor must be Sync. ```rust fn descriptor(self) -> impl SourceDescriptor + Sync; ``` -------------------------------- ### try_into Source: https://docs.rs/micropool/latest/micropool/iter/struct.VecParallelSource.html Performs the conversion. ```APIDOC ## try_into ### Description Performs the conversion. ### Signature `fn try_into(self) -> Result>::Error>` ### Associated Types * `Error`: The type returned in the event of a conversion error. ``` -------------------------------- ### try_fold_per_thread Example with Err Result Source: https://docs.rs/micropool/latest/micropool/iter/trait.ParallelIteratorExt.html Illustrates how try_fold_per_thread handles errors. When an operation within the fold returns an Err, the process stops early and returns that error. ```rust let input = [Ok(1), Ok(2), Ok(3), Ok(4), Err(5), Ok(6), Ok(7), Ok(8)]; let collection: Result>, i32> = input .par_iter() .copied() .with_thread_pool(&mut thread_pool) .try_fold_per_thread( Vec::new, |mut vec, x| -> Result, i32> { vec.push(x?); Ok(vec) }, Vec::with_capacity, |mut vecvec, vec| { vecvec.push(vec?); Ok(vecvec) }, ); assert_eq!(collection, Err(5)); ``` -------------------------------- ### Join OwnedTask and Get Result Source: https://docs.rs/micropool/latest/micropool/struct.OwnedTask.html Joins the current thread with an OwnedTask, completing all remaining work. After all work is complete, it yields the result. This method consumes the task. ```rust pub fn join(self) -> T; ``` -------------------------------- ### into_option() method Source: https://docs.rs/micropool/latest/micropool/iter/enum.MinMaxResult.html Returns the minimal-maximal pair, if this result isn’t empty. ```APIDOC ## pub fn into_option(self) -> Option<(T, T)> where T: Clone, Returns the minimal-maximal pair, if this result isn’t empty. ### Example ```rust assert_eq!(MinMaxResult::::NoElements.into_option(), None); assert_eq!(MinMaxResult::OneElement(42).into_option(), Some((42, 42))); assert_eq!(MinMaxResult::MinMax { min: 42, max: 123 }.into_option(), Some((42, 123))); ``` ``` -------------------------------- ### Install ThreadPool Context Source: https://docs.rs/micropool/latest/src/micropool/thread_pool.rs.html Changes the current context to this thread pool, affecting subsequent calls to `crate::join` or parallel iterators. Panics if called recursively. ```rust pub fn install(&self, f: impl FnOnce() -> R) -> R { abort_on_panic(|| { assert!( LOCAL_POOL.get().is_null(), "cannot call install recursively" ); LOCAL_POOL.set(self); let result = f(); LOCAL_POOL.set(std::ptr::null()); result }) } ``` -------------------------------- ### StepBy: Select every Nth item from a parallel source Source: https://docs.rs/micropool/latest/micropool/iter/struct.SkipExact.html Returns a parallel source that produces every `n`-th item, starting with the first one. ```rust fn step_by(self, n: usize) -> StepBy ``` -------------------------------- ### try_reduce Example with Reduction Error Source: https://docs.rs/micropool/latest/micropool/iter/trait.ParallelIteratorExt.html Shows try_reduce encountering an error during reduction due to integer overflow. The operation stops early, returning the first error encountered. ```rust let input = [1, 2, 3, 4, i32::MAX, 6, 7, 8, 9, 10]; let sum = input .par_iter() .copied() .with_thread_pool(&mut thread_pool) .try_reduce(|| 0i32, |x, y| x.checked_add(y).ok_or("error")); assert_eq!(sum, Err("error")); ``` -------------------------------- ### Initialize ThreadPool Source: https://docs.rs/micropool/latest/src/micropool/thread_pool.rs.html Initializes a new ThreadPool with a given builder. This involves creating shared state and spawning worker threads. ```rust fn new(mut builder: ThreadPoolBuilder) -> Self { let state = Arc::new(ThreadPoolState::new(&builder)); let mut join_handles = Vec::with_capacity(builder.num_threads); for i in 0..builder.num_threads { let state_cloned = state.clone(); join_handles.push((builder.spawn_handler)( i, Box::new(move || { let thread_pool = Self { join_handles: None, state: state_cloned, }; LOCAL_POOL.set(&thread_pool); thread_pool.state.join() }), )); } Self { join_handles: Some(join_handles), state, } } ``` -------------------------------- ### Get the number of threads in the current pool Source: https://docs.rs/micropool/latest/src/micropool/lib.rs.html Returns the total number of worker threads available in the current thread pool. This is a utility function for querying pool configuration. ```rust pub fn num_threads() -> usize { ThreadPool::with_current(|pool| pool.num_threads()) } ``` -------------------------------- ### Zipping with Minimum Length using zip_min Source: https://docs.rs/micropool/latest/micropool/iter/trait.ZipableSource.html Demonstrates zip_min, which creates a zipped iterator with a length equal to the minimum of the input iterators' lengths. Requires 'rayon'. ```rust let left = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let right = [11, 12, 13, 14, 15]; let (sum_left, sum_right) = (left.par_iter(), right.par_iter()) // Produces 5 tuples. .zip_min() .with_thread_pool(&mut thread_pool) .map(|(&a, &b)| (a, b)) .reduce(|| (0, 0), |(a, b), (c, d)| (a + c, b + d)); ``` -------------------------------- ### VecParallelSource with Non-Send Type (Compile Error Example) Source: https://docs.rs/micropool/latest/micropool/iter/struct.VecParallelSource.html Illustrates a scenario where VecParallelSource cannot be created because the element type (Rc) does not implement the `Send` trait, which is a requirement for parallel processing. ```rust use std::rc::Rc; let input = vec![Rc::new(1), Rc::new(2), Rc::new(3), Rc::new(4)]; let iter: VecParallelSource<_> = input.into_par_iter(); ``` -------------------------------- ### MutSliceParallelSource Compile-Time Error Example Source: https://docs.rs/micropool/latest/micropool/iter/struct.MutSliceParallelSource.html Illustrates a compile-time error when attempting to create a MutSliceParallelSource with elements that are not `Send`. The element type must implement the `Send` trait for parallel processing. ```rust use std::rc::Rc; let mut values = [Rc::new(1), Rc::new(2), Rc::new(3), Rc::new(4)]; let iter: MutSliceParallelSource<_> = values.par_iter_mut(); ``` -------------------------------- ### take_exact(n: usize) Source: https://docs.rs/micropool/latest/micropool/iter/struct.MutSliceParallelSource.html Returns a parallel source that produces the first `n` items from this source, panicking if this source has fewer than `n` items. ```APIDOC ## take_exact(n: usize) ### Description Returns a parallel source that produces the first `n` items from this source, panicking if this source has fewer than `n` items. ### Method `take_exact` ### Parameters #### Path Parameters - **n** (usize) - Required - The exact number of items to take. ``` -------------------------------- ### ZipEq<(A, B, C, D, E, F, G, H)> ExactParallelSource Source: https://docs.rs/micropool/latest/micropool/iter/struct.ZipEq.html Implements ExactParallelSource for a tuple of 8 elements, providing the item type and a method to get the source descriptor. ```APIDOC ## ZipEq<(A, B, C, D, E, F, G, H)> ExactParallelSource ### Description This implementation provides the `ExactParallelSource` for a tuple containing 8 elements. It defines the `Item` type and the `exact_descriptor` method. ### Type Item ```rust ::Item, ::Item, ::Item, ::Item, ::Item, ::Item, ::Item, ::Item ``` ### Method exact_descriptor Returns an object that describes how to fetch items from this source. ```rust fn exact_descriptor( self, ) -> impl ExactSourceDescriptor as ExactParallelSource>::Item> + Sync ``` ```