comparison rust/hg-core/src/utils.rs @ 51189:aba622c7dc7e

rust: add a utility function to merge ordered fallible iterators Adding a function merge_join_results_by, a version of itertools::merge_join_by that works on "fallible" iterators (iterators that can produce errors)
author Arseniy Alekseyev <aalekseyev@janestreet.com>
date Wed, 15 Nov 2023 18:41:33 +0000
parents 331a3cbe1c9e
children e6a44bc91bc2
comparison
equal deleted inserted replaced
51188:976403c95ba3 51189:aba622c7dc7e
9 9
10 use crate::errors::{HgError, IoErrorContext}; 10 use crate::errors::{HgError, IoErrorContext};
11 use crate::utils::hg_path::HgPath; 11 use crate::utils::hg_path::HgPath;
12 use im_rc::ordmap::DiffItem; 12 use im_rc::ordmap::DiffItem;
13 use im_rc::ordmap::OrdMap; 13 use im_rc::ordmap::OrdMap;
14 use itertools::EitherOrBoth;
15 use itertools::Itertools;
14 use std::cell::Cell; 16 use std::cell::Cell;
17 use std::cmp::Ordering;
15 use std::fmt; 18 use std::fmt;
16 use std::{io::Write, ops::Deref}; 19 use std::{io::Write, ops::Deref};
17 20
18 pub mod debug; 21 pub mod debug;
19 pub mod files; 22 pub mod files;
497 Ok(node) => f(node).transpose(), 500 Ok(node) => f(node).transpose(),
498 Err(e) => Some(Err(e)), 501 Err(e) => Some(Err(e)),
499 }) 502 })
500 } 503 }
501 504
505 /// Like `itertools::merge_join_by`, but merges fallible iterators.
506 ///
507 /// The callback is only used for Ok values. Errors are passed through as-is.
508 /// Errors compare less than Ok values, which makes the error handling
509 /// conservative.
510 pub fn merge_join_results_by<'a, I1, I2, F, A, B, E>(
511 iter1: I1,
512 iter2: I2,
513 f: F,
514 ) -> impl Iterator<Item = Result<EitherOrBoth<A, B>, E>> + 'a
515 where
516 I1: Iterator<Item = Result<A, E>> + 'a,
517 I2: Iterator<Item = Result<B, E>> + 'a,
518 F: FnMut(&A, &B) -> Ordering + 'a,
519 {
520 let mut g = f;
521 iter1
522 .merge_join_by(iter2, move |i1, i2| match i1 {
523 Err(_) => Ordering::Less,
524 Ok(i1) => match i2 {
525 Err(_) => Ordering::Greater,
526 Ok(i2) => g(i1, i2),
527 },
528 })
529 .map(|result| match result {
530 EitherOrBoth::Left(Err(e)) => Err(e),
531 EitherOrBoth::Right(Err(e)) => Err(e),
532 EitherOrBoth::Both(Err(e), _) => Err(e),
533 EitherOrBoth::Both(_, Err(e)) => Err(e),
534 EitherOrBoth::Left(Ok(v)) => Ok(EitherOrBoth::Left(v)),
535 EitherOrBoth::Right(Ok(v)) => Ok(EitherOrBoth::Right(v)),
536 EitherOrBoth::Both(Ok(v1), Ok(v2)) => {
537 Ok(EitherOrBoth::Both(v1, v2))
538 }
539 })
540 }
541
502 /// Force the global rayon threadpool to not exceed 16 concurrent threads 542 /// Force the global rayon threadpool to not exceed 16 concurrent threads
503 /// unless the user has specified a value. 543 /// unless the user has specified a value.
504 /// This is a stop-gap measure until we figure out why using more than 16 544 /// This is a stop-gap measure until we figure out why using more than 16
505 /// threads makes `status` slower for each additional thread. 545 /// threads makes `status` slower for each additional thread.
506 /// 546 ///