rust/hg-core/src/utils.rs
author Mitchell Kember <mkember@janestreet.com>
Thu, 16 Jan 2025 13:15:02 -0500
changeset 52760 94e2547e6f3d
parent 52759 36d39726c0af
permissions -rw-r--r--
rust: move code from utils to utils::strings This moves string-related functions in hg::utils into the recently added hg::utils::strings module.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42751
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42748
diff changeset
     1
// utils module
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42748
diff changeset
     2
//
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42748
diff changeset
     3
// Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42748
diff changeset
     4
//
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42748
diff changeset
     5
// This software may be used and distributed according to the terms of the
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42748
diff changeset
     6
// GNU General Public License version 2 or any later version.
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42748
diff changeset
     7
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42748
diff changeset
     8
//! Contains useful functions, traits, structs, etc. for use in core.
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42748
diff changeset
     9
46445
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46090
diff changeset
    10
use crate::errors::{HgError, IoErrorContext};
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    11
use im_rc::ordmap::DiffItem;
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    12
use im_rc::ordmap::OrdMap;
51151
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
    13
use itertools::EitherOrBoth;
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
    14
use itertools::Itertools;
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
    15
use std::cmp::Ordering;
44268
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44265
diff changeset
    16
50214
8e0d823ef182 testing: introduce util function to synchronize concurrent commands on files
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48417
diff changeset
    17
pub mod debug;
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    18
pub mod files;
42956
3fe40dd6355d rust-hgpath: add HgPath and HgPathBuf structs to encapsulate handling of paths
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42863
diff changeset
    19
pub mod hg_path;
44265
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44079
diff changeset
    20
pub mod path_auditor;
52759
36d39726c0af rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents: 52280
diff changeset
    21
pub mod strings;
42437
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    22
46445
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46090
diff changeset
    23
pub fn current_dir() -> Result<std::path::PathBuf, HgError> {
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46090
diff changeset
    24
    std::env::current_dir().map_err(|error| HgError::IoError {
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46090
diff changeset
    25
        error,
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46090
diff changeset
    26
        context: IoErrorContext::CurrentDir,
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46090
diff changeset
    27
    })
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46090
diff changeset
    28
}
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
    29
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
    30
pub fn current_exe() -> Result<std::path::PathBuf, HgError> {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
    31
    std::env::current_exe().map_err(|error| HgError::IoError {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
    32
        error,
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
    33
        context: IoErrorContext::CurrentExe,
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
    34
    })
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46445
diff changeset
    35
}
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    36
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    37
pub(crate) enum MergeResult<V> {
49934
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
    38
    Left,
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
    39
    Right,
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
    40
    New(V),
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    41
}
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    42
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    43
/// Return the union of the two given maps,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    44
/// calling `merge(key, left_value, right_value)` to resolve keys that exist in
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    45
/// both.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    46
///
50412
331a3cbe1c9e rustdoc: fixed warnings about links
Georges Racinet <georges.racinet@octobus.net>
parents: 50321
diff changeset
    47
/// CC <https://github.com/bodil/im-rs/issues/166>
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    48
pub(crate) fn ordmap_union_with_merge<K, V>(
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    49
    left: OrdMap<K, V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    50
    right: OrdMap<K, V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    51
    mut merge: impl FnMut(&K, &V, &V) -> MergeResult<V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    52
) -> OrdMap<K, V>
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    53
where
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    54
    K: Clone + Ord,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    55
    V: Clone + PartialEq,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    56
{
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    57
    if left.ptr_eq(&right) {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    58
        // One of the two maps is an unmodified clone of the other
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    59
        left
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    60
    } else if left.len() / 2 > right.len() {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    61
        // When two maps have different sizes,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    62
        // their size difference is a lower bound on
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    63
        // how many keys of the larger map are not also in the smaller map.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    64
        // This in turn is a lower bound on the number of differences in
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    65
        // `OrdMap::diff` and the "amount of work" that would be done
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    66
        // by `ordmap_union_with_merge_by_diff`.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    67
        //
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    68
        // Here `left` is more than twice the size of `right`,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    69
        // so the number of differences is more than the total size of
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    70
        // `right`. Therefore an algorithm based on iterating `right`
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    71
        // is more efficient.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    72
        //
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    73
        // This helps a lot when a tiny (or empty) map is merged
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    74
        // with a large one.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    75
        ordmap_union_with_merge_by_iter(left, right, merge)
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    76
    } else if left.len() < right.len() / 2 {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    77
        // Same as above but with `left` and `right` swapped
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    78
        ordmap_union_with_merge_by_iter(right, left, |key, a, b| {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    79
            // Also swapped in `merge` arguments:
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    80
            match merge(key, b, a) {
49934
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
    81
                MergeResult::New(v) => MergeResult::New(v),
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    82
                // … and swap back in `merge` result:
49934
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
    83
                MergeResult::Left => MergeResult::Right,
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
    84
                MergeResult::Right => MergeResult::Left,
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    85
            }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    86
        })
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    87
    } else {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    88
        // For maps of similar size, use the algorithm based on `OrdMap::diff`
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    89
        ordmap_union_with_merge_by_diff(left, right, merge)
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    90
    }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    91
}
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    92
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    93
/// Efficient if `right` is much smaller than `left`
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    94
fn ordmap_union_with_merge_by_iter<K, V>(
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    95
    mut left: OrdMap<K, V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    96
    right: OrdMap<K, V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    97
    mut merge: impl FnMut(&K, &V, &V) -> MergeResult<V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    98
) -> OrdMap<K, V>
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
    99
where
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   100
    K: Clone + Ord,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   101
    V: Clone,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   102
{
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   103
    for (key, right_value) in right {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   104
        match left.get(&key) {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   105
            None => {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   106
                left.insert(key, right_value);
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   107
            }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   108
            Some(left_value) => match merge(&key, left_value, &right_value) {
49934
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
   109
                MergeResult::Left => {}
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
   110
                MergeResult::Right => {
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   111
                    left.insert(key, right_value);
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   112
                }
49934
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
   113
                MergeResult::New(new_value) => {
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   114
                    left.insert(key, new_value);
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   115
                }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   116
            },
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   117
        }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   118
    }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   119
    left
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   120
}
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   121
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   122
/// Fallback when both maps are of similar size
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   123
fn ordmap_union_with_merge_by_diff<K, V>(
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   124
    mut left: OrdMap<K, V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   125
    mut right: OrdMap<K, V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   126
    mut merge: impl FnMut(&K, &V, &V) -> MergeResult<V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   127
) -> OrdMap<K, V>
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   128
where
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   129
    K: Clone + Ord,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   130
    V: Clone + PartialEq,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   131
{
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   132
    // (key, value) pairs that would need to be inserted in either map
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   133
    // in order to turn it into the union.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   134
    //
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   135
    // TODO: if/when https://github.com/bodil/im-rs/pull/168 is accepted,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   136
    // change these from `Vec<(K, V)>` to `Vec<(&K, Cow<V>)>`
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   137
    // with `left_updates` only borrowing from `right` and `right_updates` from
49934
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
   138
    // `left`, and with `Cow::Owned` used for `MergeResult::New`.
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   139
    //
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   140
    // This would allow moving all `.clone()` calls to after we’ve decided
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   141
    // which of `right_updates` or `left_updates` to use
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   142
    // (value ones becoming `Cow::into_owned`),
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   143
    // and avoid making clones we don’t end up using.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   144
    let mut left_updates = Vec::new();
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   145
    let mut right_updates = Vec::new();
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   146
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   147
    for difference in left.diff(&right) {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   148
        match difference {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   149
            DiffItem::Add(key, value) => {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   150
                left_updates.push((key.clone(), value.clone()))
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   151
            }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   152
            DiffItem::Remove(key, value) => {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   153
                right_updates.push((key.clone(), value.clone()))
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   154
            }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   155
            DiffItem::Update {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   156
                old: (key, left_value),
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   157
                new: (_, right_value),
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   158
            } => match merge(key, left_value, right_value) {
49934
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
   159
                MergeResult::Left => {
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   160
                    right_updates.push((key.clone(), left_value.clone()))
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   161
                }
49934
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
   162
                MergeResult::Right => {
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   163
                    left_updates.push((key.clone(), right_value.clone()))
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   164
                }
49934
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
   165
                MergeResult::New(new_value) => {
46586
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   166
                    left_updates.push((key.clone(), new_value.clone()));
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   167
                    right_updates.push((key.clone(), new_value))
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   168
                }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   169
            },
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   170
        }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   171
    }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   172
    if left_updates.len() < right_updates.len() {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   173
        for (key, value) in left_updates {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   174
            left.insert(key, value);
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   175
        }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   176
        left
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   177
    } else {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   178
        for (key, value) in right_updates {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   179
            right.insert(key, value);
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   180
        }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   181
        right
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   182
    }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46505
diff changeset
   183
}
46614
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46601
diff changeset
   184
49979
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   185
/// Like `Iterator::filter_map`, but over a fallible iterator of `Result`s.
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   186
///
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   187
/// The callback is only called for incoming `Ok` values. Errors are passed
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   188
/// through as-is. In order to let it use the `?` operator the callback is
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   189
/// expected to return a `Result` of `Option`, instead of an `Option` of
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   190
/// `Result`.
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   191
pub fn filter_map_results<'a, I, F, A, B, E>(
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   192
    iter: I,
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   193
    f: F,
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   194
) -> impl Iterator<Item = Result<B, E>> + 'a
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   195
where
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   196
    I: Iterator<Item = Result<A, E>> + 'a,
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   197
    F: Fn(A) -> Result<Option<B>, E> + 'a,
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   198
{
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   199
    iter.filter_map(move |result| match result {
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   200
        Ok(node) => f(node).transpose(),
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   201
        Err(e) => Some(Err(e)),
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   202
    })
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49934
diff changeset
   203
}
50321
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   204
51151
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   205
/// Like `itertools::merge_join_by`, but merges fallible iterators.
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   206
///
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   207
/// The callback is only used for Ok values. Errors are passed through as-is.
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   208
/// Errors compare less than Ok values, which makes the error handling
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   209
/// conservative.
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   210
pub fn merge_join_results_by<'a, I1, I2, F, A, B, E>(
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   211
    iter1: I1,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   212
    iter2: I2,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   213
    f: F,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   214
) -> impl Iterator<Item = Result<EitherOrBoth<A, B>, E>> + 'a
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   215
where
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   216
    I1: Iterator<Item = Result<A, E>> + 'a,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   217
    I2: Iterator<Item = Result<B, E>> + 'a,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   218
    F: FnMut(&A, &B) -> Ordering + 'a,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   219
{
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   220
    let mut g = f;
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   221
    iter1
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   222
        .merge_join_by(iter2, move |i1, i2| match i1 {
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   223
            Err(_) => Ordering::Less,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   224
            Ok(i1) => match i2 {
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   225
                Err(_) => Ordering::Greater,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   226
                Ok(i2) => g(i1, i2),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   227
            },
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   228
        })
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   229
        .map(|result| match result {
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   230
            EitherOrBoth::Left(Err(e)) => Err(e),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   231
            EitherOrBoth::Right(Err(e)) => Err(e),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   232
            EitherOrBoth::Both(Err(e), _) => Err(e),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   233
            EitherOrBoth::Both(_, Err(e)) => Err(e),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   234
            EitherOrBoth::Left(Ok(v)) => Ok(EitherOrBoth::Left(v)),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   235
            EitherOrBoth::Right(Ok(v)) => Ok(EitherOrBoth::Right(v)),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   236
            EitherOrBoth::Both(Ok(v1), Ok(v2)) => {
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   237
                Ok(EitherOrBoth::Both(v1, v2))
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   238
            }
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   239
        })
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   240
}
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50412
diff changeset
   241
50321
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   242
/// Force the global rayon threadpool to not exceed 16 concurrent threads
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   243
/// unless the user has specified a value.
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   244
/// This is a stop-gap measure until we figure out why using more than 16
52186
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51151
diff changeset
   245
/// threads makes `status` and `update` slower for each additional thread.
50321
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   246
///
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   247
/// TODO find the underlying cause and fix it, then remove this.
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   248
///
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   249
/// # Errors
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   250
///
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   251
/// Returns an error if the global threadpool has already been initialized if
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   252
/// we try to initialize it.
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   253
pub fn cap_default_rayon_threads() -> Result<(), rayon::ThreadPoolBuildError> {
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   254
    const THREAD_CAP: usize = 16;
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   255
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   256
    if std::env::var("RAYON_NUM_THREADS").is_err() {
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   257
        let available_parallelism = std::thread::available_parallelism()
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   258
            .map(usize::from)
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   259
            .unwrap_or(1);
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   260
        let new_thread_count = THREAD_CAP.min(available_parallelism);
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   261
        let res = rayon::ThreadPoolBuilder::new()
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   262
            .num_threads(new_thread_count)
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   263
            .build_global();
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   264
        if res.is_ok() {
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   265
            log::trace!(
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   266
                "Capped the rayon threadpool to {new_thread_count} threads",
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   267
            );
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   268
        }
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   269
        return res;
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   270
    }
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   271
    Ok(())
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
   272
}