Skip to content

Commit 3c8cb9e

Browse files
committed
Minimal indexmap support for rustc-rayon
1 parent f192a48 commit 3c8cb9e

File tree

3 files changed

+232
-0
lines changed

3 files changed

+232
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ exclude = ["ci"]
2222
name = "rayon"
2323

2424
[dependencies]
25+
indexmap = { version = "2", optional = true }
2526
rustc-rayon-core = { version = "0.5", path = "rayon-core" }
2627

2728
# This is a public dependency!

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ pub mod vec;
110110

111111
mod math;
112112
mod par_either;
113+
mod par_indexmap;
113114

114115
mod compile_fail;
115116

src/par_indexmap.rs

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
#![cfg(feature = "indexmap")]
2+
//! Minimal `indexmap` support for `rustc-rayon`
3+
4+
use crate::iter::plumbing::{bridge, Consumer, Producer, ProducerCallback, UnindexedConsumer};
5+
use crate::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
6+
7+
mod map {
8+
use super::*;
9+
use indexmap::map::{IndexMap, Iter, IterMut, Slice};
10+
11+
impl<'a, K, V, S> IntoParallelIterator for &'a IndexMap<K, V, S>
12+
where
13+
K: Sync,
14+
V: Sync,
15+
{
16+
type Item = (&'a K, &'a V);
17+
type Iter = ParIter<'a, K, V>;
18+
19+
fn into_par_iter(self) -> Self::Iter {
20+
ParIter {
21+
slice: self.as_slice(),
22+
}
23+
}
24+
}
25+
26+
#[derive(Debug)]
27+
pub struct ParIter<'a, K, V> {
28+
slice: &'a Slice<K, V>,
29+
}
30+
31+
impl<'a, K: Sync, V: Sync> ParallelIterator for ParIter<'a, K, V> {
32+
type Item = (&'a K, &'a V);
33+
34+
fn drive_unindexed<C>(self, consumer: C) -> C::Result
35+
where
36+
C: UnindexedConsumer<Self::Item>,
37+
{
38+
bridge(self, consumer)
39+
}
40+
41+
fn opt_len(&self) -> Option<usize> {
42+
Some(self.slice.len())
43+
}
44+
}
45+
46+
impl<K: Sync, V: Sync> IndexedParallelIterator for ParIter<'_, K, V> {
47+
fn drive<C>(self, consumer: C) -> C::Result
48+
where
49+
C: Consumer<Self::Item>,
50+
{
51+
bridge(self, consumer)
52+
}
53+
54+
fn len(&self) -> usize {
55+
self.slice.len()
56+
}
57+
58+
fn with_producer<CB>(self, callback: CB) -> CB::Output
59+
where
60+
CB: ProducerCallback<Self::Item>,
61+
{
62+
callback.callback(IterProducer { slice: self.slice })
63+
}
64+
}
65+
66+
struct IterProducer<'a, K, V> {
67+
slice: &'a Slice<K, V>,
68+
}
69+
70+
impl<'a, K: Sync, V: Sync> Producer for IterProducer<'a, K, V> {
71+
type Item = (&'a K, &'a V);
72+
type IntoIter = Iter<'a, K, V>;
73+
74+
fn into_iter(self) -> Self::IntoIter {
75+
self.slice.iter()
76+
}
77+
78+
fn split_at(self, index: usize) -> (Self, Self) {
79+
let (left, right) = self.slice.split_at(index);
80+
(Self { slice: left }, Self { slice: right })
81+
}
82+
}
83+
84+
impl<'a, K, V, S> IntoParallelIterator for &'a mut IndexMap<K, V, S>
85+
where
86+
K: Sync + Send,
87+
V: Send,
88+
{
89+
type Item = (&'a K, &'a mut V);
90+
type Iter = ParIterMut<'a, K, V>;
91+
92+
fn into_par_iter(self) -> Self::Iter {
93+
ParIterMut {
94+
slice: self.as_mut_slice(),
95+
}
96+
}
97+
}
98+
99+
#[derive(Debug)]
100+
pub struct ParIterMut<'a, K, V> {
101+
slice: &'a mut Slice<K, V>,
102+
}
103+
104+
impl<'a, K: Sync + Send, V: Send> ParallelIterator for ParIterMut<'a, K, V> {
105+
type Item = (&'a K, &'a mut V);
106+
107+
fn drive_unindexed<C>(self, consumer: C) -> C::Result
108+
where
109+
C: UnindexedConsumer<Self::Item>,
110+
{
111+
bridge(self, consumer)
112+
}
113+
114+
fn opt_len(&self) -> Option<usize> {
115+
Some(self.slice.len())
116+
}
117+
}
118+
119+
impl<K: Sync + Send, V: Send> IndexedParallelIterator for ParIterMut<'_, K, V> {
120+
fn drive<C>(self, consumer: C) -> C::Result
121+
where
122+
C: Consumer<Self::Item>,
123+
{
124+
bridge(self, consumer)
125+
}
126+
127+
fn len(&self) -> usize {
128+
self.slice.len()
129+
}
130+
131+
fn with_producer<CB>(self, callback: CB) -> CB::Output
132+
where
133+
CB: ProducerCallback<Self::Item>,
134+
{
135+
callback.callback(IterMutProducer { slice: self.slice })
136+
}
137+
}
138+
139+
struct IterMutProducer<'a, K, V> {
140+
slice: &'a mut Slice<K, V>,
141+
}
142+
143+
impl<'a, K: Sync + Send, V: Send> Producer for IterMutProducer<'a, K, V> {
144+
type Item = (&'a K, &'a mut V);
145+
type IntoIter = IterMut<'a, K, V>;
146+
147+
fn into_iter(self) -> Self::IntoIter {
148+
self.slice.iter_mut()
149+
}
150+
151+
fn split_at(self, index: usize) -> (Self, Self) {
152+
let (left, right) = self.slice.split_at_mut(index);
153+
(Self { slice: left }, Self { slice: right })
154+
}
155+
}
156+
}
157+
158+
mod set {
159+
use super::*;
160+
use indexmap::set::{IndexSet, Iter, Slice};
161+
162+
impl<'a, T: Sync, S> IntoParallelIterator for &'a IndexSet<T, S> {
163+
type Item = &'a T;
164+
type Iter = ParIter<'a, T>;
165+
166+
fn into_par_iter(self) -> Self::Iter {
167+
ParIter {
168+
slice: self.as_slice(),
169+
}
170+
}
171+
}
172+
173+
#[derive(Debug)]
174+
pub struct ParIter<'a, T> {
175+
slice: &'a Slice<T>,
176+
}
177+
178+
impl<'a, T: Sync> ParallelIterator for ParIter<'a, T> {
179+
type Item = &'a T;
180+
181+
fn drive_unindexed<C>(self, consumer: C) -> C::Result
182+
where
183+
C: UnindexedConsumer<Self::Item>,
184+
{
185+
bridge(self, consumer)
186+
}
187+
188+
fn opt_len(&self) -> Option<usize> {
189+
Some(self.slice.len())
190+
}
191+
}
192+
193+
impl<T: Sync> IndexedParallelIterator for ParIter<'_, T> {
194+
fn drive<C>(self, consumer: C) -> C::Result
195+
where
196+
C: Consumer<Self::Item>,
197+
{
198+
bridge(self, consumer)
199+
}
200+
201+
fn len(&self) -> usize {
202+
self.slice.len()
203+
}
204+
205+
fn with_producer<CB>(self, callback: CB) -> CB::Output
206+
where
207+
CB: ProducerCallback<Self::Item>,
208+
{
209+
callback.callback(IterProducer { slice: self.slice })
210+
}
211+
}
212+
213+
struct IterProducer<'a, T> {
214+
slice: &'a Slice<T>,
215+
}
216+
217+
impl<'a, T: Sync> Producer for IterProducer<'a, T> {
218+
type Item = &'a T;
219+
type IntoIter = Iter<'a, T>;
220+
221+
fn into_iter(self) -> Self::IntoIter {
222+
self.slice.iter()
223+
}
224+
225+
fn split_at(self, index: usize) -> (Self, Self) {
226+
let (left, right) = self.slice.split_at(index);
227+
(Self { slice: left }, Self { slice: right })
228+
}
229+
}
230+
}

0 commit comments

Comments
 (0)