1 //! Parallel iterator types for `IndexMap` with [rayon](https://docs.rs/rayon/1.0/rayon). 2 //! 3 //! You will rarely need to interact with this module directly unless you need to name one of the 4 //! iterator types. 5 //! 6 //! Requires crate feature `"rayon"` 7 8 use super::collect; 9 use rayon::iter::plumbing::{Consumer, ProducerCallback, UnindexedConsumer}; 10 use rayon::prelude::*; 11 12 use crate::vec::Vec; 13 use core::cmp::Ordering; 14 use core::fmt; 15 use core::hash::{BuildHasher, Hash}; 16 use core::ops::RangeBounds; 17 18 use crate::Bucket; 19 use crate::Entries; 20 use crate::IndexMap; 21 22 /// Requires crate feature `"rayon"`. 23 impl<K, V, S> IntoParallelIterator for IndexMap<K, V, S> 24 where 25 K: Send, 26 V: Send, 27 { 28 type Item = (K, V); 29 type Iter = IntoParIter<K, V>; 30 into_par_iter(self) -> Self::Iter31 fn into_par_iter(self) -> Self::Iter { 32 IntoParIter { 33 entries: self.into_entries(), 34 } 35 } 36 } 37 38 /// A parallel owning iterator over the entries of a `IndexMap`. 39 /// 40 /// This `struct` is created by the [`into_par_iter`] method on [`IndexMap`] 41 /// (provided by rayon's `IntoParallelIterator` trait). See its documentation for more. 42 /// 43 /// [`into_par_iter`]: ../struct.IndexMap.html#method.into_par_iter 44 /// [`IndexMap`]: ../struct.IndexMap.html 45 pub struct IntoParIter<K, V> { 46 entries: Vec<Bucket<K, V>>, 47 } 48 49 impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoParIter<K, V> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 51 let iter = self.entries.iter().map(Bucket::refs); 52 f.debug_list().entries(iter).finish() 53 } 54 } 55 56 impl<K: Send, V: Send> ParallelIterator for IntoParIter<K, V> { 57 type Item = (K, V); 58 59 parallel_iterator_methods!(Bucket::key_value); 60 } 61 62 impl<K: Send, V: Send> IndexedParallelIterator for IntoParIter<K, V> { 63 indexed_parallel_iterator_methods!(Bucket::key_value); 64 } 65 66 /// Requires crate feature `"rayon"`. 67 impl<'a, K, V, S> IntoParallelIterator for &'a IndexMap<K, V, S> 68 where 69 K: Sync, 70 V: Sync, 71 { 72 type Item = (&'a K, &'a V); 73 type Iter = ParIter<'a, K, V>; 74 into_par_iter(self) -> Self::Iter75 fn into_par_iter(self) -> Self::Iter { 76 ParIter { 77 entries: self.as_entries(), 78 } 79 } 80 } 81 82 /// A parallel iterator over the entries of a `IndexMap`. 83 /// 84 /// This `struct` is created by the [`par_iter`] method on [`IndexMap`] 85 /// (provided by rayon's `IntoParallelRefIterator` trait). See its documentation for more. 86 /// 87 /// [`par_iter`]: ../struct.IndexMap.html#method.par_iter 88 /// [`IndexMap`]: ../struct.IndexMap.html 89 pub struct ParIter<'a, K, V> { 90 entries: &'a [Bucket<K, V>], 91 } 92 93 impl<K, V> Clone for ParIter<'_, K, V> { clone(&self) -> Self94 fn clone(&self) -> Self { 95 ParIter { ..*self } 96 } 97 } 98 99 impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for ParIter<'_, K, V> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 101 let iter = self.entries.iter().map(Bucket::refs); 102 f.debug_list().entries(iter).finish() 103 } 104 } 105 106 impl<'a, K: Sync, V: Sync> ParallelIterator for ParIter<'a, K, V> { 107 type Item = (&'a K, &'a V); 108 109 parallel_iterator_methods!(Bucket::refs); 110 } 111 112 impl<K: Sync, V: Sync> IndexedParallelIterator for ParIter<'_, K, V> { 113 indexed_parallel_iterator_methods!(Bucket::refs); 114 } 115 116 /// Requires crate feature `"rayon"`. 117 impl<'a, K, V, S> IntoParallelIterator for &'a mut IndexMap<K, V, S> 118 where 119 K: Sync + Send, 120 V: Send, 121 { 122 type Item = (&'a K, &'a mut V); 123 type Iter = ParIterMut<'a, K, V>; 124 into_par_iter(self) -> Self::Iter125 fn into_par_iter(self) -> Self::Iter { 126 ParIterMut { 127 entries: self.as_entries_mut(), 128 } 129 } 130 } 131 132 /// A parallel mutable iterator over the entries of a `IndexMap`. 133 /// 134 /// This `struct` is created by the [`par_iter_mut`] method on [`IndexMap`] 135 /// (provided by rayon's `IntoParallelRefMutIterator` trait). See its documentation for more. 136 /// 137 /// [`par_iter_mut`]: ../struct.IndexMap.html#method.par_iter_mut 138 /// [`IndexMap`]: ../struct.IndexMap.html 139 pub struct ParIterMut<'a, K, V> { 140 entries: &'a mut [Bucket<K, V>], 141 } 142 143 impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for ParIterMut<'_, K, V> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result144 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 145 let iter = self.entries.iter().map(Bucket::refs); 146 f.debug_list().entries(iter).finish() 147 } 148 } 149 150 impl<'a, K: Sync + Send, V: Send> ParallelIterator for ParIterMut<'a, K, V> { 151 type Item = (&'a K, &'a mut V); 152 153 parallel_iterator_methods!(Bucket::ref_mut); 154 } 155 156 impl<K: Sync + Send, V: Send> IndexedParallelIterator for ParIterMut<'_, K, V> { 157 indexed_parallel_iterator_methods!(Bucket::ref_mut); 158 } 159 160 /// Requires crate feature `"rayon"`. 161 impl<'a, K, V, S> ParallelDrainRange<usize> for &'a mut IndexMap<K, V, S> 162 where 163 K: Send, 164 V: Send, 165 { 166 type Item = (K, V); 167 type Iter = ParDrain<'a, K, V>; 168 par_drain<R: RangeBounds<usize>>(self, range: R) -> Self::Iter169 fn par_drain<R: RangeBounds<usize>>(self, range: R) -> Self::Iter { 170 ParDrain { 171 entries: self.core.par_drain(range), 172 } 173 } 174 } 175 176 /// A parallel draining iterator over the entries of a `IndexMap`. 177 /// 178 /// This `struct` is created by the [`par_drain`] method on [`IndexMap`] 179 /// (provided by rayon's `ParallelDrainRange` trait). See its documentation for more. 180 /// 181 /// [`par_drain`]: ../struct.IndexMap.html#method.par_drain 182 /// [`IndexMap`]: ../struct.IndexMap.html 183 pub struct ParDrain<'a, K: Send, V: Send> { 184 entries: rayon::vec::Drain<'a, Bucket<K, V>>, 185 } 186 187 impl<K: Send, V: Send> ParallelIterator for ParDrain<'_, K, V> { 188 type Item = (K, V); 189 190 parallel_iterator_methods!(Bucket::key_value); 191 } 192 193 impl<K: Send, V: Send> IndexedParallelIterator for ParDrain<'_, K, V> { 194 indexed_parallel_iterator_methods!(Bucket::key_value); 195 } 196 197 /// Parallel iterator methods and other parallel methods. 198 /// 199 /// The following methods **require crate feature `"rayon"`**. 200 /// 201 /// See also the `IntoParallelIterator` implementations. 202 impl<K, V, S> IndexMap<K, V, S> 203 where 204 K: Sync, 205 V: Sync, 206 { 207 /// Return a parallel iterator over the keys of the map. 208 /// 209 /// While parallel iterators can process items in any order, their relative order 210 /// in the map is still preserved for operations like `reduce` and `collect`. par_keys(&self) -> ParKeys<'_, K, V>211 pub fn par_keys(&self) -> ParKeys<'_, K, V> { 212 ParKeys { 213 entries: self.as_entries(), 214 } 215 } 216 217 /// Return a parallel iterator over the values of the map. 218 /// 219 /// While parallel iterators can process items in any order, their relative order 220 /// in the map is still preserved for operations like `reduce` and `collect`. par_values(&self) -> ParValues<'_, K, V>221 pub fn par_values(&self) -> ParValues<'_, K, V> { 222 ParValues { 223 entries: self.as_entries(), 224 } 225 } 226 } 227 228 impl<K, V, S> IndexMap<K, V, S> 229 where 230 K: Hash + Eq + Sync, 231 V: Sync, 232 S: BuildHasher, 233 { 234 /// Returns `true` if `self` contains all of the same key-value pairs as `other`, 235 /// regardless of each map's indexed order, determined in parallel. par_eq<V2, S2>(&self, other: &IndexMap<K, V2, S2>) -> bool where V: PartialEq<V2>, V2: Sync, S2: BuildHasher + Sync,236 pub fn par_eq<V2, S2>(&self, other: &IndexMap<K, V2, S2>) -> bool 237 where 238 V: PartialEq<V2>, 239 V2: Sync, 240 S2: BuildHasher + Sync, 241 { 242 self.len() == other.len() 243 && self 244 .par_iter() 245 .all(move |(key, value)| other.get(key).map_or(false, |v| *value == *v)) 246 } 247 } 248 249 /// A parallel iterator over the keys of a `IndexMap`. 250 /// 251 /// This `struct` is created by the [`par_keys`] method on [`IndexMap`]. See its 252 /// documentation for more. 253 /// 254 /// [`par_keys`]: ../struct.IndexMap.html#method.par_keys 255 /// [`IndexMap`]: ../struct.IndexMap.html 256 pub struct ParKeys<'a, K, V> { 257 entries: &'a [Bucket<K, V>], 258 } 259 260 impl<K, V> Clone for ParKeys<'_, K, V> { clone(&self) -> Self261 fn clone(&self) -> Self { 262 ParKeys { ..*self } 263 } 264 } 265 266 impl<K: fmt::Debug, V> fmt::Debug for ParKeys<'_, K, V> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result267 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 268 let iter = self.entries.iter().map(Bucket::key_ref); 269 f.debug_list().entries(iter).finish() 270 } 271 } 272 273 impl<'a, K: Sync, V: Sync> ParallelIterator for ParKeys<'a, K, V> { 274 type Item = &'a K; 275 276 parallel_iterator_methods!(Bucket::key_ref); 277 } 278 279 impl<K: Sync, V: Sync> IndexedParallelIterator for ParKeys<'_, K, V> { 280 indexed_parallel_iterator_methods!(Bucket::key_ref); 281 } 282 283 /// A parallel iterator over the values of a `IndexMap`. 284 /// 285 /// This `struct` is created by the [`par_values`] method on [`IndexMap`]. See its 286 /// documentation for more. 287 /// 288 /// [`par_values`]: ../struct.IndexMap.html#method.par_values 289 /// [`IndexMap`]: ../struct.IndexMap.html 290 pub struct ParValues<'a, K, V> { 291 entries: &'a [Bucket<K, V>], 292 } 293 294 impl<K, V> Clone for ParValues<'_, K, V> { clone(&self) -> Self295 fn clone(&self) -> Self { 296 ParValues { ..*self } 297 } 298 } 299 300 impl<K, V: fmt::Debug> fmt::Debug for ParValues<'_, K, V> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result301 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 302 let iter = self.entries.iter().map(Bucket::value_ref); 303 f.debug_list().entries(iter).finish() 304 } 305 } 306 307 impl<'a, K: Sync, V: Sync> ParallelIterator for ParValues<'a, K, V> { 308 type Item = &'a V; 309 310 parallel_iterator_methods!(Bucket::value_ref); 311 } 312 313 impl<K: Sync, V: Sync> IndexedParallelIterator for ParValues<'_, K, V> { 314 indexed_parallel_iterator_methods!(Bucket::value_ref); 315 } 316 317 /// Requires crate feature `"rayon"`. 318 impl<K, V, S> IndexMap<K, V, S> 319 where 320 K: Send, 321 V: Send, 322 { 323 /// Return a parallel iterator over mutable references to the values of the map 324 /// 325 /// While parallel iterators can process items in any order, their relative order 326 /// in the map is still preserved for operations like `reduce` and `collect`. par_values_mut(&mut self) -> ParValuesMut<'_, K, V>327 pub fn par_values_mut(&mut self) -> ParValuesMut<'_, K, V> { 328 ParValuesMut { 329 entries: self.as_entries_mut(), 330 } 331 } 332 } 333 334 impl<K, V, S> IndexMap<K, V, S> 335 where 336 K: Hash + Eq + Send, 337 V: Send, 338 S: BuildHasher, 339 { 340 /// Sort the map’s key-value pairs in parallel, by the default ordering of the keys. par_sort_keys(&mut self) where K: Ord,341 pub fn par_sort_keys(&mut self) 342 where 343 K: Ord, 344 { 345 self.with_entries(|entries| { 346 entries.par_sort_by(|a, b| K::cmp(&a.key, &b.key)); 347 }); 348 } 349 350 /// Sort the map’s key-value pairs in place and in parallel, using the comparison 351 /// function `cmp`. 352 /// 353 /// The comparison function receives two key and value pairs to compare (you 354 /// can sort by keys or values or their combination as needed). par_sort_by<F>(&mut self, cmp: F) where F: Fn(&K, &V, &K, &V) -> Ordering + Sync,355 pub fn par_sort_by<F>(&mut self, cmp: F) 356 where 357 F: Fn(&K, &V, &K, &V) -> Ordering + Sync, 358 { 359 self.with_entries(|entries| { 360 entries.par_sort_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value)); 361 }); 362 } 363 364 /// Sort the key-value pairs of the map in parallel and return a by-value parallel 365 /// iterator of the key-value pairs with the result. par_sorted_by<F>(self, cmp: F) -> IntoParIter<K, V> where F: Fn(&K, &V, &K, &V) -> Ordering + Sync,366 pub fn par_sorted_by<F>(self, cmp: F) -> IntoParIter<K, V> 367 where 368 F: Fn(&K, &V, &K, &V) -> Ordering + Sync, 369 { 370 let mut entries = self.into_entries(); 371 entries.par_sort_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value)); 372 IntoParIter { entries } 373 } 374 375 /// Sort the map's key-value pairs in parallel, by the default ordering of the keys. par_sort_unstable_keys(&mut self) where K: Ord,376 pub fn par_sort_unstable_keys(&mut self) 377 where 378 K: Ord, 379 { 380 self.with_entries(|entries| { 381 entries.par_sort_unstable_by(|a, b| K::cmp(&a.key, &b.key)); 382 }); 383 } 384 385 /// Sort the map's key-value pairs in place and in parallel, using the comparison 386 /// function `cmp`. 387 /// 388 /// The comparison function receives two key and value pairs to compare (you 389 /// can sort by keys or values or their combination as needed). par_sort_unstable_by<F>(&mut self, cmp: F) where F: Fn(&K, &V, &K, &V) -> Ordering + Sync,390 pub fn par_sort_unstable_by<F>(&mut self, cmp: F) 391 where 392 F: Fn(&K, &V, &K, &V) -> Ordering + Sync, 393 { 394 self.with_entries(|entries| { 395 entries.par_sort_unstable_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value)); 396 }); 397 } 398 399 /// Sort the key-value pairs of the map in parallel and return a by-value parallel 400 /// iterator of the key-value pairs with the result. par_sorted_unstable_by<F>(self, cmp: F) -> IntoParIter<K, V> where F: Fn(&K, &V, &K, &V) -> Ordering + Sync,401 pub fn par_sorted_unstable_by<F>(self, cmp: F) -> IntoParIter<K, V> 402 where 403 F: Fn(&K, &V, &K, &V) -> Ordering + Sync, 404 { 405 let mut entries = self.into_entries(); 406 entries.par_sort_unstable_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value)); 407 IntoParIter { entries } 408 } 409 } 410 411 /// A parallel mutable iterator over the values of a `IndexMap`. 412 /// 413 /// This `struct` is created by the [`par_values_mut`] method on [`IndexMap`]. See its 414 /// documentation for more. 415 /// 416 /// [`par_values_mut`]: ../struct.IndexMap.html#method.par_values_mut 417 /// [`IndexMap`]: ../struct.IndexMap.html 418 pub struct ParValuesMut<'a, K, V> { 419 entries: &'a mut [Bucket<K, V>], 420 } 421 422 impl<K, V: fmt::Debug> fmt::Debug for ParValuesMut<'_, K, V> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result423 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 424 let iter = self.entries.iter().map(Bucket::value_ref); 425 f.debug_list().entries(iter).finish() 426 } 427 } 428 429 impl<'a, K: Send, V: Send> ParallelIterator for ParValuesMut<'a, K, V> { 430 type Item = &'a mut V; 431 432 parallel_iterator_methods!(Bucket::value_mut); 433 } 434 435 impl<K: Send, V: Send> IndexedParallelIterator for ParValuesMut<'_, K, V> { 436 indexed_parallel_iterator_methods!(Bucket::value_mut); 437 } 438 439 /// Requires crate feature `"rayon"`. 440 impl<K, V, S> FromParallelIterator<(K, V)> for IndexMap<K, V, S> 441 where 442 K: Eq + Hash + Send, 443 V: Send, 444 S: BuildHasher + Default + Send, 445 { from_par_iter<I>(iter: I) -> Self where I: IntoParallelIterator<Item = (K, V)>,446 fn from_par_iter<I>(iter: I) -> Self 447 where 448 I: IntoParallelIterator<Item = (K, V)>, 449 { 450 let list = collect(iter); 451 let len = list.iter().map(Vec::len).sum(); 452 let mut map = Self::with_capacity_and_hasher(len, S::default()); 453 for vec in list { 454 map.extend(vec); 455 } 456 map 457 } 458 } 459 460 /// Requires crate feature `"rayon"`. 461 impl<K, V, S> ParallelExtend<(K, V)> for IndexMap<K, V, S> 462 where 463 K: Eq + Hash + Send, 464 V: Send, 465 S: BuildHasher + Send, 466 { par_extend<I>(&mut self, iter: I) where I: IntoParallelIterator<Item = (K, V)>,467 fn par_extend<I>(&mut self, iter: I) 468 where 469 I: IntoParallelIterator<Item = (K, V)>, 470 { 471 for vec in collect(iter) { 472 self.extend(vec); 473 } 474 } 475 } 476 477 /// Requires crate feature `"rayon"`. 478 impl<'a, K: 'a, V: 'a, S> ParallelExtend<(&'a K, &'a V)> for IndexMap<K, V, S> 479 where 480 K: Copy + Eq + Hash + Send + Sync, 481 V: Copy + Send + Sync, 482 S: BuildHasher + Send, 483 { par_extend<I>(&mut self, iter: I) where I: IntoParallelIterator<Item = (&'a K, &'a V)>,484 fn par_extend<I>(&mut self, iter: I) 485 where 486 I: IntoParallelIterator<Item = (&'a K, &'a V)>, 487 { 488 for vec in collect(iter) { 489 self.extend(vec); 490 } 491 } 492 } 493 494 #[cfg(test)] 495 mod tests { 496 use super::*; 497 use std::string::String; 498 499 #[test] insert_order()500 fn insert_order() { 501 let insert = [0, 4, 2, 12, 8, 7, 11, 5, 3, 17, 19, 22, 23]; 502 let mut map = IndexMap::new(); 503 504 for &elt in &insert { 505 map.insert(elt, ()); 506 } 507 508 assert_eq!(map.par_keys().count(), map.len()); 509 assert_eq!(map.par_keys().count(), insert.len()); 510 insert.par_iter().zip(map.par_keys()).for_each(|(a, b)| { 511 assert_eq!(a, b); 512 }); 513 (0..insert.len()) 514 .into_par_iter() 515 .zip(map.par_keys()) 516 .for_each(|(i, k)| { 517 assert_eq!(map.get_index(i).unwrap().0, k); 518 }); 519 } 520 521 #[test] partial_eq_and_eq()522 fn partial_eq_and_eq() { 523 let mut map_a = IndexMap::new(); 524 map_a.insert(1, "1"); 525 map_a.insert(2, "2"); 526 let mut map_b = map_a.clone(); 527 assert!(map_a.par_eq(&map_b)); 528 map_b.swap_remove(&1); 529 assert!(!map_a.par_eq(&map_b)); 530 map_b.insert(3, "3"); 531 assert!(!map_a.par_eq(&map_b)); 532 533 let map_c: IndexMap<_, String> = 534 map_b.into_par_iter().map(|(k, v)| (k, v.into())).collect(); 535 assert!(!map_a.par_eq(&map_c)); 536 assert!(!map_c.par_eq(&map_a)); 537 } 538 539 #[test] extend()540 fn extend() { 541 let mut map = IndexMap::new(); 542 map.par_extend(vec![(&1, &2), (&3, &4)]); 543 map.par_extend(vec![(5, 6)]); 544 assert_eq!( 545 map.into_par_iter().collect::<Vec<_>>(), 546 vec![(1, 2), (3, 4), (5, 6)] 547 ); 548 } 549 550 #[test] keys()551 fn keys() { 552 let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; 553 let map: IndexMap<_, _> = vec.into_par_iter().collect(); 554 let keys: Vec<_> = map.par_keys().copied().collect(); 555 assert_eq!(keys.len(), 3); 556 assert!(keys.contains(&1)); 557 assert!(keys.contains(&2)); 558 assert!(keys.contains(&3)); 559 } 560 561 #[test] values()562 fn values() { 563 let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; 564 let map: IndexMap<_, _> = vec.into_par_iter().collect(); 565 let values: Vec<_> = map.par_values().copied().collect(); 566 assert_eq!(values.len(), 3); 567 assert!(values.contains(&'a')); 568 assert!(values.contains(&'b')); 569 assert!(values.contains(&'c')); 570 } 571 572 #[test] values_mut()573 fn values_mut() { 574 let vec = vec![(1, 1), (2, 2), (3, 3)]; 575 let mut map: IndexMap<_, _> = vec.into_par_iter().collect(); 576 map.par_values_mut().for_each(|value| *value *= 2); 577 let values: Vec<_> = map.par_values().copied().collect(); 578 assert_eq!(values.len(), 3); 579 assert!(values.contains(&2)); 580 assert!(values.contains(&4)); 581 assert!(values.contains(&6)); 582 } 583 } 584