use super::noop::NoopConsumer;
use super::{IntoParallelIterator, ParallelExtend, ParallelIterator};
use std::borrow::Cow;
use std::collections::LinkedList;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::collections::{BinaryHeap, VecDeque};
use std::hash::{BuildHasher, Hash};
fn extend<C, I, F>(collection: &mut C, par_iter: I, reserve: F)
where
I: IntoParallelIterator,
F: FnOnce(&mut C, &LinkedList<Vec<I::Item>>),
C: Extend<I::Item>,
{
let list = collect(par_iter);
reserve(collection, &list);
for vec in list {
collection.extend(vec);
}
}
pub(super) fn collect<I>(par_iter: I) -> LinkedList<Vec<I::Item>>
where
I: IntoParallelIterator,
{
par_iter
.into_par_iter()
.fold(Vec::new, vec_push)
.map(as_list)
.reduce(LinkedList::new, list_append)
}
fn vec_push<T>(mut vec: Vec<T>, elem: T) -> Vec<T> {
vec.push(elem);
vec
}
fn as_list<T>(item: T) -> LinkedList<T> {
let mut list = LinkedList::new();
list.push_back(item);
list
}
fn list_append<T>(mut list1: LinkedList<T>, mut list2: LinkedList<T>) -> LinkedList<T> {
list1.append(&mut list2);
list1
}
pub(super) fn len<T>(list: &LinkedList<Vec<T>>) -> usize {
list.iter().map(Vec::len).sum()
}
fn no_reserve<C, T>(_: &mut C, _: &LinkedList<Vec<T>>) {}
fn heap_reserve<T: Ord, U>(heap: &mut BinaryHeap<T>, list: &LinkedList<Vec<U>>) {
heap.reserve(len(list));
}
impl<T> ParallelExtend<T> for BinaryHeap<T>
where
T: Ord + Send,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = T>,
{
extend(self, par_iter, heap_reserve);
}
}
impl<'a, T> ParallelExtend<&'a T> for BinaryHeap<T>
where
T: 'a + Copy + Ord + Send + Sync,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = &'a T>,
{
extend(self, par_iter, heap_reserve);
}
}
impl<K, V> ParallelExtend<(K, V)> for BTreeMap<K, V>
where
K: Ord + Send,
V: Send,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = (K, V)>,
{
extend(self, par_iter, no_reserve);
}
}
impl<'a, K: 'a, V: 'a> ParallelExtend<(&'a K, &'a V)> for BTreeMap<K, V>
where
K: Copy + Ord + Send + Sync,
V: Copy + Send + Sync,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = (&'a K, &'a V)>,
{
extend(self, par_iter, no_reserve);
}
}
impl<T> ParallelExtend<T> for BTreeSet<T>
where
T: Ord + Send,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = T>,
{
extend(self, par_iter, no_reserve);
}
}
impl<'a, T> ParallelExtend<&'a T> for BTreeSet<T>
where
T: 'a + Copy + Ord + Send + Sync,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = &'a T>,
{
extend(self, par_iter, no_reserve);
}
}
fn map_reserve<K, V, S, U>(map: &mut HashMap<K, V, S>, list: &LinkedList<Vec<U>>)
where
K: Eq + Hash,
S: BuildHasher,
{
map.reserve(len(list));
}
impl<K, V, S> ParallelExtend<(K, V)> for HashMap<K, V, S>
where
K: Eq + Hash + Send,
V: Send,
S: BuildHasher + Send,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = (K, V)>,
{
extend(self, par_iter, map_reserve);
}
}
impl<'a, K: 'a, V: 'a, S> ParallelExtend<(&'a K, &'a V)> for HashMap<K, V, S>
where
K: Copy + Eq + Hash + Send + Sync,
V: Copy + Send + Sync,
S: BuildHasher + Send,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = (&'a K, &'a V)>,
{
extend(self, par_iter, map_reserve);
}
}
fn set_reserve<T, S, U>(set: &mut HashSet<T, S>, list: &LinkedList<Vec<U>>)
where
T: Eq + Hash,
S: BuildHasher,
{
set.reserve(len(list));
}
impl<T, S> ParallelExtend<T> for HashSet<T, S>
where
T: Eq + Hash + Send,
S: BuildHasher + Send,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = T>,
{
extend(self, par_iter, set_reserve);
}
}
impl<'a, T, S> ParallelExtend<&'a T> for HashSet<T, S>
where
T: 'a + Copy + Eq + Hash + Send + Sync,
S: BuildHasher + Send,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = &'a T>,
{
extend(self, par_iter, set_reserve);
}
}
fn list_push_back<T>(mut list: LinkedList<T>, elem: T) -> LinkedList<T> {
list.push_back(elem);
list
}
impl<T> ParallelExtend<T> for LinkedList<T>
where
T: Send,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = T>,
{
let mut list = par_iter
.into_par_iter()
.fold(LinkedList::new, list_push_back)
.reduce(LinkedList::new, list_append);
self.append(&mut list);
}
}
impl<'a, T> ParallelExtend<&'a T> for LinkedList<T>
where
T: 'a + Copy + Send + Sync,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = &'a T>,
{
self.par_extend(par_iter.into_par_iter().cloned())
}
}
fn string_push(mut string: String, ch: char) -> String {
string.push(ch);
string
}
impl ParallelExtend<char> for String {
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = char>,
{
let list: LinkedList<_> = par_iter
.into_par_iter()
.fold(String::new, string_push)
.map(as_list)
.reduce(LinkedList::new, list_append);
self.reserve(list.iter().map(String::len).sum());
self.extend(list)
}
}
impl<'a> ParallelExtend<&'a char> for String {
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = &'a char>,
{
self.par_extend(par_iter.into_par_iter().cloned())
}
}
fn string_reserve<T: AsRef<str>>(string: &mut String, list: &LinkedList<Vec<T>>) {
let len = list
.iter()
.flat_map(|vec| vec)
.map(T::as_ref)
.map(str::len)
.sum();
string.reserve(len);
}
impl<'a> ParallelExtend<&'a str> for String {
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = &'a str>,
{
extend(self, par_iter, string_reserve);
}
}
impl ParallelExtend<String> for String {
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = String>,
{
extend(self, par_iter, string_reserve);
}
}
impl<'a> ParallelExtend<Cow<'a, str>> for String {
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = Cow<'a, str>>,
{
extend(self, par_iter, string_reserve);
}
}
fn deque_reserve<T, U>(deque: &mut VecDeque<T>, list: &LinkedList<Vec<U>>) {
deque.reserve(len(list));
}
impl<T> ParallelExtend<T> for VecDeque<T>
where
T: Send,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = T>,
{
extend(self, par_iter, deque_reserve);
}
}
impl<'a, T> ParallelExtend<&'a T> for VecDeque<T>
where
T: 'a + Copy + Send + Sync,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = &'a T>,
{
extend(self, par_iter, deque_reserve);
}
}
impl<'a, T> ParallelExtend<&'a T> for Vec<T>
where
T: 'a + Copy + Send + Sync,
{
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = &'a T>,
{
self.par_extend(par_iter.into_par_iter().cloned())
}
}
impl ParallelExtend<()> for () {
fn par_extend<I>(&mut self, par_iter: I)
where
I: IntoParallelIterator<Item = ()>,
{
par_iter.into_par_iter().drive_unindexed(NoopConsumer)
}
}