Bug 1785002 - Force update hashbrown to 0.12.3. r=emilio,supply-chain-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D154762
This commit is contained in:
Mike Hommey 2022-08-16 21:47:43 +00:00
Родитель e629e09f6d
Коммит 790d70c82e
29 изменённых файлов: 5054 добавлений и 692 удалений

19
Cargo.lock сгенерированный
Просмотреть файл

@ -1579,7 +1579,7 @@ version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52db5973b6a19247baf19b30f41c23a1bfffc2e9ce0a5db2f60e3cd5dc8895f7"
dependencies = [
"hashbrown",
"hashbrown 0.11.999",
]
[[package]]
@ -2374,7 +2374,7 @@ checksum = "a538f217be4d405ff4719a283ca68323cc2384003eca5baaa87501e821c81dda"
dependencies = [
"bitflags",
"gpu-descriptor-types",
"hashbrown",
"hashbrown 0.11.999",
]
[[package]]
@ -2417,9 +2417,16 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.11.2"
version = "0.11.999"
dependencies = [
"hashbrown 0.12.3",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
dependencies = [
"ahash",
]
@ -2430,7 +2437,7 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf"
dependencies = [
"hashbrown",
"hashbrown 0.11.999",
]
[[package]]
@ -2600,7 +2607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a"
dependencies = [
"autocfg",
"hashbrown",
"hashbrown 0.11.999",
"serde",
]

Просмотреть файл

@ -125,6 +125,9 @@ tinyvec = { path = "build/rust/tinyvec" }
# Patch wasi 0.10 to 0.11
wasi = { path = "build/rust/wasi" }
# Patch hashbrown 0.11 to 0.12
hashbrown = { path = "build/rust/hashbrown" }
# Patch autocfg to hide rustc output. Workaround for https://github.com/cuviper/autocfg/issues/30
autocfg = { path = "third_party/rust/autocfg" }

Просмотреть файл

@ -0,0 +1,21 @@
[package]
name = "hashbrown"
version = "0.11.999"
edition = "2018"
license = "MPL-2.0"
[lib]
path = "lib.rs"
[dependencies.hashbrown]
version = "0.12"
default-features = false
[features]
ahash-compile-time-rng = ["hashbrown/ahash-compile-time-rng"]
default = ["hashbrown/default"]
inline-more = ["hashbrown/inline-more"]
nightly = ["hashbrown/nightly"]
raw = ["hashbrown/raw"]
rustc-dep-of-std = ["hashbrown/rustc-dep-of-std"]
rustc-internal-api = ["hashbrown/rustc-internal-api"]

Просмотреть файл

@ -0,0 +1,5 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
pub use hashbrown::*;

Просмотреть файл

@ -368,6 +368,12 @@ the usage is pretty straightforward and while it's technically UB, it seems no
more likely to lead to miscompilation than any other use of mem::uninitialized.
"""
[[audits.hashbrown]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
version = "0.12.3"
notes = "This version is used in rust's libstd, so effectively we're already trusting it"
[[audits.hyper]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-run"

Просмотреть файл

@ -737,10 +737,6 @@ criteria = "safe-to-deploy"
version = "0.3.13"
criteria = "safe-to-run"
[[exemptions.hashbrown]]
version = "0.11.2"
criteria = "safe-to-deploy"
[[exemptions.hashlink]]
version = "0.7.0"
criteria = "safe-to-deploy"

Просмотреть файл

@ -1 +1 @@
{"files":{"CHANGELOG.md":"24ff18c978b40b166f5b3fd1090c3526d1958e79137dd9d765b571fed1c59fc2","Cargo.toml":"98ca6560469b01c01771f3c22c6182497d2239463cb4f63395d8207002d9a9ad","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"ff8f68cb076caf8cefe7a6430d4ac086ce6af2ca8ce2c4e5a2004d4552ef52a2","README.md":"742ce1a4c92dada5f73ce594b224b646ff4aefe702768ec2eb39bd937a5a8fd3","benches/bench.rs":"43546a3d5aed2dd8f71f5d236f4df63d82a3767aec90d86f4ab1d1496619b45d","clippy.toml":"7535949f908c6d9aea4f9a9f3a7625552c93fc29e963d059d40f4def9d77ea7b","src/external_trait_impls/mod.rs":"d69528827794524cfd9acbeacc1ac4f6131e3c7574311e6d919f818f65fbff07","src/external_trait_impls/rayon/helpers.rs":"d4fbca4db924925548f8dab8eb94cf4a3955a53c5e1ff15f59c460546c394034","src/external_trait_impls/rayon/map.rs":"eee6371f2875085b286e950a32d13c3eff3c7280e7ea6ad346d322e7a00e7b7b","src/external_trait_impls/rayon/mod.rs":"156de9c1ad0123334ea3b7e5a17444faf1b8bf971aa88a1f23e2f2d1c3021141","src/external_trait_impls/rayon/raw.rs":"ddf349051bada9a9ebd027686e03ac2f12d74dd1b3f98a36aac257e13bac57fa","src/external_trait_impls/rayon/set.rs":"c4c44d44e56c2f59e9e1355662e29d8744ac96645ca4414127a359fb46cb0fbf","src/external_trait_impls/serde.rs":"9306fb6e0e339398dc23ba9e7400a9a28d713df248e8b260e3d4dc44f799e101","src/lib.rs":"45cd368e35bdb00232bcf2f5430ee516bb448a88724ab738424ae2e1d3c1f22e","src/macros.rs":"0b1e9a55e8f5232b82f7e56f352a98904b35ddfca015377cf71daa31939baabf","src/map.rs":"f3d43769100c59b04a978c9756e1b32f88cf7a84b9bda0e050a4adf5afb95572","src/raw/alloc.rs":"893da7047ff4eb3291a3dee62c954f489c8b7666aa01ef6aeda8adf2549869c0","src/raw/bitmask.rs":"05e72c64957af7383001ca43a827cc5b3a8a39d00fac332ecea2fd7d2704099c","src/raw/generic.rs":"b31590616e76dfcca635e3aa9a8a0059b3af9a5afe6b0c5ebc98a7d96d63e8ed","src/raw/mod.rs":"a0d0b0508d41e08bfc16e5db1dd4f80cd29ca26e656a803821d1eb56a1f249b3","src/raw/sse2.rs":"a775ddd8830593bb10e2a4a11b2ce16d900a68e0b3763f24715f8f7fa9c2f69d","src/rustc_entry.rs":"148fae9e8bf4893820648c3c80b24c7161c828d103f3b2a2d7bbc32fe6605eb1","src/scopeguard.rs":"808655b3e98512fdcee5a4597e7763a6be99582ba8d77e5ba5ca130d85a97211","src/set.rs":"d64fbadd0e6a5749cb5838f869004ea8cd46cec4b948615f810abb9e0a892d72","tests/hasher.rs":"9a8fdf67e4415618e16729969c386eefe71408cded5d46cf7b67d969276a3452","tests/rayon.rs":"2286707a87b139f41902c82488c355b9fb402a3e734f392f3a73e87b9b932795","tests/serde.rs":"6bac8054db722dd049901b37a6e006535bac30f425eb5cd91af19b5bc1dfe78e","tests/set.rs":"374bd312c01a01cf8953bbbc9494f431b260c2657d7c79cc250e977b869a76ad"},"package":"ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"}
{"files":{"CHANGELOG.md":"ade49a29d368e16ce508aee91b477ecbad7e2e52eb6fee7b4c1fc86199963f0e","Cargo.toml":"421b3a71d97faf0a7e52c3b2bfbe0f1c036b9dbf6232b4e5b41221bb54358f5a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"ff8f68cb076caf8cefe7a6430d4ac086ce6af2ca8ce2c4e5a2004d4552ef52a2","README.md":"a536b3bb3f3521e59836080f05a4783150fa8484f759a31468ce3b6dba1f33eb","benches/bench.rs":"aadc39d815eadf094ed9357d946319df2d93194203bbccb7c33cea6951d654df","benches/insert_unique_unchecked.rs":"cb84275f22d5f95a5ac995ac6b2df74ffcf342765b401d27c95f2955c7b7cb9f","clippy.toml":"7535949f908c6d9aea4f9a9f3a7625552c93fc29e963d059d40f4def9d77ea7b","src/external_trait_impls/mod.rs":"d69528827794524cfd9acbeacc1ac4f6131e3c7574311e6d919f818f65fbff07","src/external_trait_impls/rayon/helpers.rs":"ba105bf0853ebc45157f22116ad0f55d3bdab75e721d8e7a677c7b912d0c0c6d","src/external_trait_impls/rayon/map.rs":"2809e2a0071db8101c38789deb955f3830c5c3455eb1794ff64a0cf2ceb53fc7","src/external_trait_impls/rayon/mod.rs":"156de9c1ad0123334ea3b7e5a17444faf1b8bf971aa88a1f23e2f2d1c3021141","src/external_trait_impls/rayon/raw.rs":"e62c5f3ca5fffea47357e64b6f8c34cec94af62d9bd28a2b87934da46c22b66e","src/external_trait_impls/rayon/set.rs":"c4c44d44e56c2f59e9e1355662e29d8744ac96645ca4414127a359fb46cb0fbf","src/external_trait_impls/serde.rs":"0bc1a1f218d1ae7a5262557a5e3737b9334caf7d50c136dbdc75ff75680c223b","src/lib.rs":"c82fbee9684bfff40ef55d5f0c9f855c11f71f9fd1720fb084ef8331bdbc41d8","src/macros.rs":"36fe532656879c80f7753d13354b889f5b45caef451a1bb3a27dbc32d74c9878","src/map.rs":"df39edae67c569378dea9a4d928685cb4d06569712c6ac36a54df76fb5d87fe3","src/raw/alloc.rs":"184a0345bc2c7544b65c28724063be26b1f2b28dbaaa028a0b01192ccac25557","src/raw/bitmask.rs":"820d90b19b7e3433a1048ace008c9526331cd53a576cb0cfc1ff9960b6fe52f8","src/raw/generic.rs":"f5013a50d6d82d5cc8bad8b8c26c24d00fa810197f9f123256c58ac92e0d98f9","src/raw/mod.rs":"fa38247c6b3bd70636be50400debb9966a3446d49ee13e4f4e2dfe4ceed1b201","src/raw/sse2.rs":"838cfdb1daa1e70951ed25f985283b8b7ab4b46fa130f92eda152047ce6086f6","src/rustc_entry.rs":"cdd70972cba5b79ca1cad79869cb5e184d6dc4798ef90822e966ef89679ba011","src/scopeguard.rs":"d13de1b12897add7fe1c3eba6f906c9cc09d86509b6cfe06b95d63803fe9265c","src/set.rs":"6877d4a42eeadd681e3b8881528e4b20f14cfedbc11e9318bfcf425ef96d1546","tests/hasher.rs":"9a8fdf67e4415618e16729969c386eefe71408cded5d46cf7b67d969276a3452","tests/rayon.rs":"83d5289771542203f539a41cccb889fbe7ce70f5adf5b903ac9f051e3ba13cfa","tests/serde.rs":"6bac8054db722dd049901b37a6e006535bac30f425eb5cd91af19b5bc1dfe78e","tests/set.rs":"01cf39efb04646ef4c63a809ebb96dfa63cfec472bf8bdb6c121f6526d40c40e"},"package":"8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"}

66
third_party/rust/hashbrown/CHANGELOG.md поставляемый
Просмотреть файл

@ -2,11 +2,67 @@
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
The format is based on [Keep a Changelog](https://keepachangelog.com/)
and this project adheres to [Semantic Versioning](https://semver.org/).
## [Unreleased]
## [v0.12.3] - 2022-07-17
## Fixed
- Fixed double-drop in `RawTable::clone_from`. (#348)
## [v0.12.2] - 2022-07-09
## Added
- Added `Entry` API for `HashSet`. (#342)
- Added `Extend<&'a (K, V)> for HashMap<K, V, S, A>`. (#340)
- Added length-based short-circuiting for hash table iteration. (#338)
- Added a function to access the `RawTable` of a `HashMap`. (#335)
## Changed
- Edited `do_alloc` to reduce LLVM IR generated. (#341)
## [v0.12.1] - 2022-05-02
## Fixed
- Fixed underflow in `RawIterRange::size_hint`. (#325)
- Fixed the implementation of `Debug` for `ValuesMut` and `IntoValues`. (#325)
## [v0.12.0] - 2022-01-17
## Added
- Added `From<[T; N]>` and `From<[(K, V); N]>` for `HashSet` and `HashMap` respectively. (#297)
- Added an `allocator()` getter to HashMap and HashSet. (#257)
- Added `insert_unique_unchecked` to `HashMap` and `HashSet`. (#293)
- Added `into_keys` and `into_values` to HashMap. (#295)
- Implement `From<array>` on `HashSet` and `HashMap`. (#298)
- Added `entry_ref` API to `HashMap`. (#201)
## Changed
- Bumped minimum Rust version to 1.56.1 and edition to 2021.
- Use u64 for the GroupWord on WebAssembly. (#271)
- Optimized `find`. (#279)
- Made rehashing and resizing less generic to reduce compilation time. (#282)
- Inlined small functions. (#283)
- Use `BuildHasher::hash_one` when `feature = "nightly"` is enabled. (#292)
- Relaxed the bounds on `Debug` for `HashSet`. (#296)
- Rename `get_each_mut` to `get_many_mut` and align API with the stdlib. (#291)
- Don't hash the key when searching in an empty table. (#305)
## Fixed
- Guard against allocations exceeding isize::MAX. (#268)
- Made `RawTable::insert_no_grow` unsafe. (#254)
- Inline `static_empty`. (#280)
- Fixed trait bounds on Send/Sync impls. (#303)
## [v0.11.2] - 2021-03-25
## Fixed
@ -307,7 +363,11 @@ This release was _yanked_ due to a breaking change for users of `no-default-feat
- Initial release
[Unreleased]: https://github.com/rust-lang/hashbrown/compare/v0.11.2...HEAD
[Unreleased]: https://github.com/rust-lang/hashbrown/compare/v0.12.3...HEAD
[v0.12.3]: https://github.com/rust-lang/hashbrown/compare/v0.12.2...v0.12.3
[v0.12.2]: https://github.com/rust-lang/hashbrown/compare/v0.12.1...v0.12.2
[v0.12.1]: https://github.com/rust-lang/hashbrown/compare/v0.12.0...v0.12.1
[v0.12.0]: https://github.com/rust-lang/hashbrown/compare/v0.11.2...v0.12.0
[v0.11.2]: https://github.com/rust-lang/hashbrown/compare/v0.11.1...v0.11.2
[v0.11.1]: https://github.com/rust-lang/hashbrown/compare/v0.11.0...v0.11.1
[v0.11.0]: https://github.com/rust-lang/hashbrown/compare/v0.10.0...v0.11.0

59
third_party/rust/hashbrown/Cargo.toml поставляемый
Просмотреть файл

@ -3,27 +3,46 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
edition = "2021"
rust-version = "1.56.0"
name = "hashbrown"
version = "0.11.2"
version = "0.12.3"
authors = ["Amanieu d'Antras <amanieu@gmail.com>"]
exclude = [".travis.yml", "bors.toml", "/ci/*"]
exclude = [
".github",
"/ci/*",
]
description = "A Rust port of Google's SwissTable hash map"
readme = "README.md"
keywords = ["hash", "no_std", "hashmap", "swisstable"]
categories = ["data-structures", "no-std"]
license = "Apache-2.0/MIT"
keywords = [
"hash",
"no_std",
"hashmap",
"swisstable",
]
categories = [
"data-structures",
"no-std",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/hashbrown"
resolver = "2"
[package.metadata.docs.rs]
features = ["nightly", "rayon", "serde", "raw"]
features = [
"nightly",
"rayon",
"serde",
"raw",
]
[dependencies.ahash]
version = "0.7.0"
optional = true
@ -55,6 +74,7 @@ optional = true
version = "1.0.25"
optional = true
default-features = false
[dev-dependencies.doc-comment]
version = "0.3.1"
@ -65,7 +85,7 @@ version = "1.0.7"
version = "1.4"
[dev-dependencies.rand]
version = "0.7.3"
version = "0.8.3"
features = ["small_rng"]
[dev-dependencies.rayon]
@ -76,9 +96,18 @@ version = "1.0"
[features]
ahash-compile-time-rng = ["ahash/compile-time-rng"]
default = ["ahash", "inline-more"]
default = [
"ahash",
"inline-more",
]
inline-more = []
nightly = []
raw = []
rustc-dep-of-std = ["nightly", "core", "compiler_builtins", "alloc", "rustc-internal-api"]
rustc-dep-of-std = [
"nightly",
"core",
"compiler_builtins",
"alloc",
"rustc-internal-api",
]
rustc-internal-api = []

10
third_party/rust/hashbrown/README.md поставляемый
Просмотреть файл

@ -1,10 +1,10 @@
hashbrown
=========
[![Build Status](https://travis-ci.com/rust-lang/hashbrown.svg?branch=master)](https://travis-ci.com/rust-lang/hashbrown)
[![Build Status](https://github.com/rust-lang/hashbrown/actions/workflows/rust.yml/badge.svg)](https://github.com/rust-lang/hashbrown/actions)
[![Crates.io](https://img.shields.io/crates/v/hashbrown.svg)](https://crates.io/crates/hashbrown)
[![Documentation](https://docs.rs/hashbrown/badge.svg)](https://docs.rs/hashbrown)
[![Rust](https://img.shields.io/badge/rust-1.49.0%2B-blue.svg?maxAge=3600)](https://github.com/rust-lang/hashbrown)
[![Rust](https://img.shields.io/badge/rust-1.56.1%2B-blue.svg?maxAge=3600)](https://github.com/rust-lang/hashbrown)
This crate is a Rust port of Google's high-performance [SwissTable] hash
map, adapted to make it a drop-in replacement for Rust's standard `HashMap`
@ -85,7 +85,7 @@ Add this to your `Cargo.toml`:
```toml
[dependencies]
hashbrown = "0.11"
hashbrown = "0.12"
```
Then:
@ -114,8 +114,8 @@ this pre-generates seeds at compile time and embeds them as constants. See [aHas
Licensed under either of:
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
at your option.

2
third_party/rust/hashbrown/benches/bench.rs поставляемый
Просмотреть файл

@ -38,7 +38,7 @@ impl Iterator for RandomKeys {
type Item = usize;
fn next(&mut self) -> Option<usize> {
// Add 1 then multiply by some 32 bit prime.
self.state = self.state.wrapping_add(1).wrapping_mul(3787392781);
self.state = self.state.wrapping_add(1).wrapping_mul(3_787_392_781);
Some(self.state)
}
}

32
third_party/rust/hashbrown/benches/insert_unique_unchecked.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,32 @@
//! Compare `insert` and `insert_unique_unchecked` operations performance.
#![feature(test)]
extern crate test;
use hashbrown::HashMap;
use test::Bencher;
#[bench]
fn insert(b: &mut Bencher) {
let keys: Vec<String> = (0..1000).map(|i| format!("xxxx{}yyyy", i)).collect();
b.iter(|| {
let mut m = HashMap::with_capacity(1000);
for k in &keys {
m.insert(k, k);
}
m
});
}
#[bench]
fn insert_unique_unchecked(b: &mut Bencher) {
let keys: Vec<String> = (0..1000).map(|i| format!("xxxx{}yyyy", i)).collect();
b.iter(|| {
let mut m = HashMap::with_capacity(1000);
for k in &keys {
m.insert_unique_unchecked(k, k);
}
m
});
}

Просмотреть файл

@ -4,6 +4,7 @@ use alloc::vec::Vec;
use rayon::iter::{IntoParallelIterator, ParallelIterator};
/// Helper for collecting parallel iterators to an intermediary
#[allow(clippy::linkedlist)] // yes, we need linked list here for efficient appending!
pub(super) fn collect<I: IntoParallelIterator>(iter: I) -> (LinkedList<Vec<I::Item>>, usize) {
let list = iter
.into_par_iter()

Просмотреть файл

@ -512,7 +512,7 @@ mod test_par_map {
where
H: Hasher,
{
self.k.hash(state)
self.k.hash(state);
}
}
@ -679,7 +679,7 @@ mod test_par_map {
fn test_values_mut() {
let vec = vec![(1, 1), (2, 2), (3, 3)];
let mut map: HashMap<_, _> = vec.into_par_iter().collect();
map.par_values_mut().for_each(|value| *value = (*value) * 2);
map.par_values_mut().for_each(|value| *value *= 2);
let values: Vec<_> = map.par_values().cloned().collect();
assert_eq!(values.len(), 3);
assert!(values.contains(&2));

Просмотреть файл

@ -87,7 +87,7 @@ impl<T, A: Allocator + Clone> RawIntoParIter<T, A> {
}
}
impl<T: Send, A: Allocator + Clone> ParallelIterator for RawIntoParIter<T, A> {
impl<T: Send, A: Allocator + Clone + Send> ParallelIterator for RawIntoParIter<T, A> {
type Item = T;
#[cfg_attr(feature = "inline-more", inline)]
@ -116,7 +116,7 @@ pub struct RawParDrain<'a, T, A: Allocator + Clone = Global> {
marker: PhantomData<&'a RawTable<T, A>>,
}
unsafe impl<T, A: Allocator + Clone> Send for RawParDrain<'_, T, A> {}
unsafe impl<T: Send, A: Allocator + Clone> Send for RawParDrain<'_, T, A> {}
impl<T, A: Allocator + Clone> RawParDrain<'_, T, A> {
#[cfg_attr(feature = "inline-more", inline)]
@ -134,7 +134,7 @@ impl<T: Send, A: Allocator + Clone> ParallelIterator for RawParDrain<'_, T, A> {
C: UnindexedConsumer<Self::Item>,
{
let _guard = guard(self.table, |table| unsafe {
table.as_mut().clear_no_drop()
table.as_mut().clear_no_drop();
});
let iter = unsafe { self.table.as_ref().iter().iter };
mem::forget(self);
@ -146,7 +146,9 @@ impl<T: Send, A: Allocator + Clone> ParallelIterator for RawParDrain<'_, T, A> {
impl<T, A: Allocator + Clone> Drop for RawParDrain<'_, T, A> {
fn drop(&mut self) {
// If drive_unindexed is not called then simply clear the table.
unsafe { self.table.as_mut().clear() }
unsafe {
self.table.as_mut().clear();
}
}
}
@ -175,7 +177,7 @@ impl<T: Send> UnindexedProducer for ParDrainProducer<T> {
{
// Make sure to modify the iterator in-place so that any remaining
// elements are processed in our Drop impl.
while let Some(item) = self.iter.next() {
for item in &mut self.iter {
folder = folder.consume(unsafe { item.read() });
if folder.full() {
return folder;
@ -193,7 +195,7 @@ impl<T> Drop for ParDrainProducer<T> {
fn drop(&mut self) {
// Drop all remaining elements
if mem::needs_drop::<T>() {
while let Some(item) = self.iter.next() {
for item in &mut self.iter {
unsafe {
item.drop();
}

Просмотреть файл

@ -161,6 +161,7 @@ mod set {
deserializer.deserialize_seq(visitor)
}
#[allow(clippy::missing_errors_doc)]
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
where
D: Deserializer<'de>,

21
third_party/rust/hashbrown/src/lib.rs поставляемый
Просмотреть файл

@ -21,7 +21,8 @@
allocator_api,
slice_ptr_get,
nonnull_slice_from_raw_parts,
maybe_uninit_array_assume_init
maybe_uninit_array_assume_init,
build_hasher_simple_hash_one
)
)]
#![allow(
@ -30,7 +31,9 @@
clippy::must_use_candidate,
clippy::option_if_let_else,
clippy::redundant_else,
clippy::manual_map
clippy::manual_map,
clippy::missing_safety_doc,
clippy::missing_errors_doc
)]
#![warn(missing_docs)]
#![warn(rust_2018_idioms)]
@ -128,20 +131,6 @@ pub enum TryReserveError {
},
}
/// The error type for [`RawTable::get_each_mut`](crate::raw::RawTable::get_each_mut),
/// [`HashMap::get_each_mut`], and [`HashMap::get_each_key_value_mut`].
#[cfg(feature = "nightly")]
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum UnavailableMutError {
/// The requested entry is not present in the table.
Absent,
/// The requested entry is present, but a mutable reference to it was already created and
/// returned from this call to `get_each_mut` or `get_each_key_value_mut`.
///
/// Includes the index of the existing mutable reference in the returned array.
Duplicate(usize),
}
/// Wrapper around `Bump` which allows it to be used as an allocator for
/// `HashMap`, `HashSet` and `RawTable`.
///

5
third_party/rust/hashbrown/src/macros.rs поставляемый
Просмотреть файл

@ -1,4 +1,5 @@
// See the cfg-if crate.
#[allow(unused_macro_rules)]
macro_rules! cfg_if {
// match if/else chains with a final `else`
($(
@ -57,8 +58,8 @@ macro_rules! cfg_if {
// default fn syntax for specialization changes in the future.
#[cfg(feature = "nightly")]
macro_rules! default_fn {
($($tt:tt)*) => {
default $($tt)*
(#[$($a:tt)*] $($tt:tt)*) => {
#[$($a)*] default $($tt)*
}
}
#[cfg(not(feature = "nightly"))]

3930
third_party/rust/hashbrown/src/map.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

11
third_party/rust/hashbrown/src/raw/alloc.rs поставляемый
Просмотреть файл

@ -8,10 +8,10 @@ mod inner {
#[allow(clippy::map_err_ignore)]
pub fn do_alloc<A: Allocator>(alloc: &A, layout: Layout) -> Result<NonNull<u8>, ()> {
alloc
.allocate(layout)
.map(|ptr| ptr.as_non_null_ptr())
.map_err(|_| ())
match alloc.allocate(layout) {
Ok(ptr) => Ok(ptr.as_non_null_ptr()),
Err(_) => Err(()),
}
}
#[cfg(feature = "bumpalo")]
@ -33,6 +33,7 @@ mod inner {
use crate::alloc::alloc::{alloc, dealloc, Layout};
use core::ptr::NonNull;
#[allow(clippy::missing_safety_doc)] // not exposed outside of this crate
pub unsafe trait Allocator {
fn allocate(&self, layout: Layout) -> Result<NonNull<u8>, ()>;
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout);
@ -47,7 +48,7 @@ mod inner {
}
#[inline]
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
dealloc(ptr.as_ptr(), layout)
dealloc(ptr.as_ptr(), layout);
}
}
impl Default for Global {

Просмотреть файл

@ -106,7 +106,7 @@ impl IntoIterator for BitMask {
}
}
/// Iterator over the contents of a `BitMask`, returning the indicies of set
/// Iterator over the contents of a `BitMask`, returning the indices of set
/// bits.
pub struct BitMaskIter(BitMask);

Просмотреть файл

@ -9,12 +9,14 @@ use core::{mem, ptr};
target_pointer_width = "64",
target_arch = "aarch64",
target_arch = "x86_64",
target_arch = "wasm32",
))]
type GroupWord = u64;
#[cfg(all(
target_pointer_width = "32",
not(target_arch = "aarch64"),
not(target_arch = "x86_64"),
not(target_arch = "wasm32"),
))]
type GroupWord = u32;
@ -37,7 +39,7 @@ fn repeat(byte: u8) -> GroupWord {
#[derive(Copy, Clone)]
pub struct Group(GroupWord);
// We perform all operations in the native endianess, and convert to
// We perform all operations in the native endianness, and convert to
// little-endian just before creating a BitMask. The can potentially
// enable the compiler to eliminate unnecessary byte swaps if we are
// only checking whether a BitMask is empty.
@ -50,6 +52,7 @@ impl Group {
/// value for an empty hash table.
///
/// This is guaranteed to be aligned to the group size.
#[inline]
pub const fn static_empty() -> &'static [u8; Group::WIDTH] {
#[repr(C)]
struct AlignedBytes {
@ -103,7 +106,7 @@ impl Group {
#[inline]
pub fn match_byte(self, byte: u8) -> BitMask {
// This algorithm is derived from
// http://graphics.stanford.edu/~seander/bithacks.html##ValueInWord
// https://graphics.stanford.edu/~seander/bithacks.html##ValueInWord
let cmp = self.0 ^ repeat(byte);
BitMask((cmp.wrapping_sub(repeat(0x01)) & !cmp & repeat(0x80)).to_le())
}

800
third_party/rust/hashbrown/src/raw/mod.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

1
third_party/rust/hashbrown/src/raw/sse2.rs поставляемый
Просмотреть файл

@ -28,6 +28,7 @@ impl Group {
/// value for an empty hash table.
///
/// This is guaranteed to be aligned to the group size.
#[inline]
#[allow(clippy::items_after_statements)]
pub const fn static_empty() -> &'static [u8; Group::WIDTH] {
#[repr(C)]

18
third_party/rust/hashbrown/src/rustc_entry.rs поставляемый
Просмотреть файл

@ -56,10 +56,10 @@ where
/// A view into a single entry in a map, which may either be vacant or occupied.
///
/// This `enum` is constructed from the [`entry`] method on [`HashMap`].
/// This `enum` is constructed from the [`rustc_entry`] method on [`HashMap`].
///
/// [`HashMap`]: struct.HashMap.html
/// [`entry`]: struct.HashMap.html#method.rustc_entry
/// [`rustc_entry`]: struct.HashMap.html#method.rustc_entry
pub enum RustcEntry<'a, K, V, A = Global>
where
A: Allocator + Clone,
@ -145,7 +145,7 @@ impl<'a, K, V, A: Allocator + Clone> RustcEntry<'a, K, V, A> {
/// use hashbrown::HashMap;
///
/// let mut map: HashMap<&str, u32> = HashMap::new();
/// let entry = map.entry("horseyland").insert(37);
/// let entry = map.rustc_entry("horseyland").insert(37);
///
/// assert_eq!(entry.key(), &"horseyland");
/// ```
@ -431,10 +431,8 @@ impl<'a, K, V, A: Allocator + Clone> RustcOccupiedEntry<'a, K, V, A> {
/// assert_eq!(map["poneyland"], 15);
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn insert(&mut self, mut value: V) -> V {
let old_value = self.get_mut();
mem::swap(&mut value, old_value);
value
pub fn insert(&mut self, value: V) -> V {
mem::replace(self.get_mut(), value)
}
/// Takes the value out of the entry, and returns it.
@ -574,8 +572,10 @@ impl<'a, K, V, A: Allocator + Clone> RustcVacantEntry<'a, K, V, A> {
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn insert(self, value: V) -> &'a mut V {
unsafe {
let bucket = self.table.insert_no_grow(self.hash, (self.key, value));
unsafe { &mut bucket.as_mut().1 }
&mut bucket.as_mut().1
}
}
/// Sets the value of the entry with the RustcVacantEntry's key,
@ -596,7 +596,7 @@ impl<'a, K, V, A: Allocator + Clone> RustcVacantEntry<'a, K, V, A> {
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn insert_entry(self, value: V) -> RustcOccupiedEntry<'a, K, V, A> {
let bucket = self.table.insert_no_grow(self.hash, (self.key, value));
let bucket = unsafe { self.table.insert_no_grow(self.hash, (self.key, value)) };
RustcOccupiedEntry {
key: None,
elem: bucket,

29
third_party/rust/hashbrown/src/scopeguard.rs поставляемый
Просмотреть файл

@ -1,5 +1,9 @@
// Extracted from the scopeguard crate
use core::ops::{Deref, DerefMut};
use core::{
mem,
ops::{Deref, DerefMut},
ptr,
};
pub struct ScopeGuard<T, F>
where
@ -17,6 +21,27 @@ where
ScopeGuard { dropfn, value }
}
impl<T, F> ScopeGuard<T, F>
where
F: FnMut(&mut T),
{
#[inline]
pub fn into_inner(guard: Self) -> T {
// Cannot move out of Drop-implementing types, so
// ptr::read the value and forget the guard.
unsafe {
let value = ptr::read(&guard.value);
// read the closure so that it is dropped, and assign it to a local
// variable to ensure that it is only dropped after the guard has
// been forgotten. (In case the Drop impl of the closure, or that
// of any consumed captured variable, panics).
let _dropfn = ptr::read(&guard.dropfn);
mem::forget(guard);
value
}
}
}
impl<T, F> Deref for ScopeGuard<T, F>
where
F: FnMut(&mut T),
@ -44,6 +69,6 @@ where
{
#[inline]
fn drop(&mut self) {
(self.dropfn)(&mut self.value)
(self.dropfn)(&mut self.value);
}
}

519
third_party/rust/hashbrown/src/set.rs поставляемый
Просмотреть файл

@ -378,7 +378,7 @@ impl<T, S, A: Allocator + Clone> HashSet<T, S, A> {
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn clear(&mut self) {
self.map.clear()
self.map.clear();
}
}
@ -454,6 +454,12 @@ impl<T, S, A> HashSet<T, S, A>
where
A: Allocator + Clone,
{
/// Returns a reference to the underlying allocator.
#[inline]
pub fn allocator(&self) -> &A {
self.map.allocator()
}
/// Creates a new empty hash set which will use the given hasher to hash
/// keys.
///
@ -553,7 +559,7 @@ where
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn reserve(&mut self, additional: usize) {
self.map.reserve(additional)
self.map.reserve(additional);
}
/// Tries to reserve capacity for at least `additional` more elements to be inserted
@ -595,7 +601,7 @@ where
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn shrink_to_fit(&mut self) {
self.map.shrink_to_fit()
self.map.shrink_to_fit();
}
/// Shrinks the capacity of the set with a lower limit. It will drop
@ -621,7 +627,7 @@ where
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn shrink_to(&mut self, min_capacity: usize) {
self.map.shrink_to(min_capacity)
self.map.shrink_to(min_capacity);
}
/// Visits the values representing the difference,
@ -896,6 +902,47 @@ where
.0
}
/// Gets the given value's corresponding entry in the set for in-place manipulation.
///
/// # Examples
///
/// ```
/// use hashbrown::HashSet;
/// use hashbrown::hash_set::Entry::*;
///
/// let mut singles = HashSet::new();
/// let mut dupes = HashSet::new();
///
/// for ch in "a short treatise on fungi".chars() {
/// if let Vacant(dupe_entry) = dupes.entry(ch) {
/// // We haven't already seen a duplicate, so
/// // check if we've at least seen it once.
/// match singles.entry(ch) {
/// Vacant(single_entry) => {
/// // We found a new character for the first time.
/// single_entry.insert()
/// }
/// Occupied(single_entry) => {
/// // We've already seen this once, "move" it to dupes.
/// single_entry.remove();
/// dupe_entry.insert();
/// }
/// }
/// }
/// }
///
/// assert!(!singles.contains(&'t') && dupes.contains(&'t'));
/// assert!(singles.contains(&'u') && !dupes.contains(&'u'));
/// assert!(!singles.contains(&'v') && !dupes.contains(&'v'));
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn entry(&mut self, value: T) -> Entry<'_, T, S, A> {
match self.map.entry(value) {
map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { inner: entry }),
map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { inner: entry }),
}
}
/// Returns `true` if `self` has no elements in common with `other`.
/// This is equivalent to checking for an empty intersection.
///
@ -985,6 +1032,30 @@ where
self.map.insert(value, ()).is_none()
}
/// Insert a value the set without checking if the value already exists in the set.
///
/// Returns a reference to the value just inserted.
///
/// This operation is safe if a value does not exist in the set.
///
/// However, if a value exists in the set already, the behavior is unspecified:
/// this operation may panic, loop forever, or any following operation with the set
/// may panic, loop forever or return arbitrary result.
///
/// That said, this operation (and following operations) are guaranteed to
/// not violate memory safety.
///
/// This operation is faster than regular insert, because it does not perform
/// lookup before insertion.
///
/// This operation is useful during initial population of the set.
/// For example, when constructing a set from another set, we know
/// that values are unique.
#[cfg_attr(feature = "inline-more", inline)]
pub fn insert_unique_unchecked(&mut self, value: T) -> &T {
self.map.insert_unique_unchecked(value, ()).0
}
/// Adds a value to the set, replacing the existing value, if any, that is equal to the given
/// one. Returns the replaced value.
///
@ -1098,8 +1169,7 @@ where
impl<T, S, A> fmt::Debug for HashSet<T, S, A>
where
T: Eq + Hash + fmt::Debug,
S: BuildHasher,
T: fmt::Debug,
A: Allocator + Clone,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@ -1130,6 +1200,27 @@ where
}
}
// The default hasher is used to match the std implementation signature
#[cfg(feature = "ahash")]
impl<T, A, const N: usize> From<[T; N]> for HashSet<T, DefaultHashBuilder, A>
where
T: Eq + Hash,
A: Default + Allocator + Clone,
{
/// # Examples
///
/// ```
/// use hashbrown::HashSet;
///
/// let set1 = HashSet::from([1, 2, 3, 4]);
/// let set2: HashSet<_> = [1, 2, 3, 4].into();
/// assert_eq!(set1, set2);
/// ```
fn from(arr: [T; N]) -> Self {
arr.into_iter().collect()
}
}
impl<T, S, A> Extend<T> for HashSet<T, S, A>
where
T: Eq + Hash,
@ -1162,7 +1253,7 @@ where
{
#[cfg_attr(feature = "inline-more", inline)]
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.extend(iter.into_iter().cloned());
self.extend(iter.into_iter().copied());
}
#[inline]
@ -1796,6 +1887,406 @@ where
}
}
/// A view into a single entry in a set, which may either be vacant or occupied.
///
/// This `enum` is constructed from the [`entry`] method on [`HashSet`].
///
/// [`HashSet`]: struct.HashSet.html
/// [`entry`]: struct.HashSet.html#method.entry
///
/// # Examples
///
/// ```
/// use hashbrown::hash_set::{Entry, HashSet, OccupiedEntry};
///
/// let mut set = HashSet::new();
/// set.extend(["a", "b", "c"]);
/// assert_eq!(set.len(), 3);
///
/// // Existing value (insert)
/// let entry: Entry<_, _> = set.entry("a");
/// let _raw_o: OccupiedEntry<_, _> = entry.insert();
/// assert_eq!(set.len(), 3);
/// // Nonexistent value (insert)
/// set.entry("d").insert();
///
/// // Existing value (or_insert)
/// set.entry("b").or_insert();
/// // Nonexistent value (or_insert)
/// set.entry("e").or_insert();
///
/// println!("Our HashSet: {:?}", set);
///
/// let mut vec: Vec<_> = set.iter().copied().collect();
/// // The `Iter` iterator produces items in arbitrary order, so the
/// // items must be sorted to test them against a sorted array.
/// vec.sort_unstable();
/// assert_eq!(vec, ["a", "b", "c", "d", "e"]);
/// ```
pub enum Entry<'a, T, S, A = Global>
where
A: Allocator + Clone,
{
/// An occupied entry.
///
/// # Examples
///
/// ```
/// use hashbrown::hash_set::{Entry, HashSet};
/// let mut set: HashSet<_> = ["a", "b"].into();
///
/// match set.entry("a") {
/// Entry::Vacant(_) => unreachable!(),
/// Entry::Occupied(_) => { }
/// }
/// ```
Occupied(OccupiedEntry<'a, T, S, A>),
/// A vacant entry.
///
/// # Examples
///
/// ```
/// use hashbrown::hash_set::{Entry, HashSet};
/// let mut set: HashSet<&str> = HashSet::new();
///
/// match set.entry("a") {
/// Entry::Occupied(_) => unreachable!(),
/// Entry::Vacant(_) => { }
/// }
/// ```
Vacant(VacantEntry<'a, T, S, A>),
}
impl<T: fmt::Debug, S, A: Allocator + Clone> fmt::Debug for Entry<'_, T, S, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
}
}
}
/// A view into an occupied entry in a `HashSet`.
/// It is part of the [`Entry`] enum.
///
/// [`Entry`]: enum.Entry.html
///
/// # Examples
///
/// ```
/// use hashbrown::hash_set::{Entry, HashSet, OccupiedEntry};
///
/// let mut set = HashSet::new();
/// set.extend(["a", "b", "c"]);
///
/// let _entry_o: OccupiedEntry<_, _> = set.entry("a").insert();
/// assert_eq!(set.len(), 3);
///
/// // Existing key
/// match set.entry("a") {
/// Entry::Vacant(_) => unreachable!(),
/// Entry::Occupied(view) => {
/// assert_eq!(view.get(), &"a");
/// }
/// }
///
/// assert_eq!(set.len(), 3);
///
/// // Existing key (take)
/// match set.entry("c") {
/// Entry::Vacant(_) => unreachable!(),
/// Entry::Occupied(view) => {
/// assert_eq!(view.remove(), "c");
/// }
/// }
/// assert_eq!(set.get(&"c"), None);
/// assert_eq!(set.len(), 2);
/// ```
pub struct OccupiedEntry<'a, T, S, A: Allocator + Clone = Global> {
inner: map::OccupiedEntry<'a, T, (), S, A>,
}
impl<T: fmt::Debug, S, A: Allocator + Clone> fmt::Debug for OccupiedEntry<'_, T, S, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OccupiedEntry")
.field("value", self.get())
.finish()
}
}
/// A view into a vacant entry in a `HashSet`.
/// It is part of the [`Entry`] enum.
///
/// [`Entry`]: enum.Entry.html
///
/// # Examples
///
/// ```
/// use hashbrown::hash_set::{Entry, HashSet, VacantEntry};
///
/// let mut set = HashSet::<&str>::new();
///
/// let entry_v: VacantEntry<_, _> = match set.entry("a") {
/// Entry::Vacant(view) => view,
/// Entry::Occupied(_) => unreachable!(),
/// };
/// entry_v.insert();
/// assert!(set.contains("a") && set.len() == 1);
///
/// // Nonexistent key (insert)
/// match set.entry("b") {
/// Entry::Vacant(view) => view.insert(),
/// Entry::Occupied(_) => unreachable!(),
/// }
/// assert!(set.contains("b") && set.len() == 2);
/// ```
pub struct VacantEntry<'a, T, S, A: Allocator + Clone = Global> {
inner: map::VacantEntry<'a, T, (), S, A>,
}
impl<T: fmt::Debug, S, A: Allocator + Clone> fmt::Debug for VacantEntry<'_, T, S, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("VacantEntry").field(self.get()).finish()
}
}
impl<'a, T, S, A: Allocator + Clone> Entry<'a, T, S, A> {
/// Sets the value of the entry, and returns an OccupiedEntry.
///
/// # Examples
///
/// ```
/// use hashbrown::HashSet;
///
/// let mut set: HashSet<&str> = HashSet::new();
/// let entry = set.entry("horseyland").insert();
///
/// assert_eq!(entry.get(), &"horseyland");
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn insert(self) -> OccupiedEntry<'a, T, S, A>
where
T: Hash,
S: BuildHasher,
{
match self {
Entry::Occupied(entry) => entry,
Entry::Vacant(entry) => entry.insert_entry(),
}
}
/// Ensures a value is in the entry by inserting if it was vacant.
///
/// # Examples
///
/// ```
/// use hashbrown::HashSet;
///
/// let mut set: HashSet<&str> = HashSet::new();
///
/// // nonexistent key
/// set.entry("poneyland").or_insert();
/// assert!(set.contains("poneyland"));
///
/// // existing key
/// set.entry("poneyland").or_insert();
/// assert!(set.contains("poneyland"));
/// assert_eq!(set.len(), 1);
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn or_insert(self)
where
T: Hash,
S: BuildHasher,
{
if let Entry::Vacant(entry) = self {
entry.insert();
}
}
/// Returns a reference to this entry's value.
///
/// # Examples
///
/// ```
/// use hashbrown::HashSet;
///
/// let mut set: HashSet<&str> = HashSet::new();
/// set.entry("poneyland").or_insert();
/// // existing key
/// assert_eq!(set.entry("poneyland").get(), &"poneyland");
/// // nonexistent key
/// assert_eq!(set.entry("horseland").get(), &"horseland");
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn get(&self) -> &T {
match *self {
Entry::Occupied(ref entry) => entry.get(),
Entry::Vacant(ref entry) => entry.get(),
}
}
}
impl<T, S, A: Allocator + Clone> OccupiedEntry<'_, T, S, A> {
/// Gets a reference to the value in the entry.
///
/// # Examples
///
/// ```
/// use hashbrown::hash_set::{Entry, HashSet};
///
/// let mut set: HashSet<&str> = HashSet::new();
/// set.entry("poneyland").or_insert();
///
/// match set.entry("poneyland") {
/// Entry::Vacant(_) => panic!(),
/// Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
/// }
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn get(&self) -> &T {
self.inner.key()
}
/// Takes the value out of the entry, and returns it.
/// Keeps the allocated memory for reuse.
///
/// # Examples
///
/// ```
/// use hashbrown::HashSet;
/// use hashbrown::hash_set::Entry;
///
/// let mut set: HashSet<&str> = HashSet::new();
/// // The set is empty
/// assert!(set.is_empty() && set.capacity() == 0);
///
/// set.entry("poneyland").or_insert();
/// let capacity_before_remove = set.capacity();
///
/// if let Entry::Occupied(o) = set.entry("poneyland") {
/// assert_eq!(o.remove(), "poneyland");
/// }
///
/// assert_eq!(set.contains("poneyland"), false);
/// // Now set hold none elements but capacity is equal to the old one
/// assert!(set.len() == 0 && set.capacity() == capacity_before_remove);
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn remove(self) -> T {
self.inner.remove_entry().0
}
/// Replaces the entry, returning the old value. The new value in the hash map will be
/// the value used to create this entry.
///
/// # Panics
///
/// Will panic if this OccupiedEntry was created through [`Entry::insert`].
///
/// # Examples
///
/// ```
/// use hashbrown::hash_set::{Entry, HashSet};
/// use std::rc::Rc;
///
/// let mut set: HashSet<Rc<String>> = HashSet::new();
/// let key_one = Rc::new("Stringthing".to_string());
/// let key_two = Rc::new("Stringthing".to_string());
///
/// set.insert(key_one.clone());
/// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
///
/// match set.entry(key_two.clone()) {
/// Entry::Occupied(entry) => {
/// let old_key: Rc<String> = entry.replace();
/// assert!(Rc::ptr_eq(&key_one, &old_key));
/// }
/// Entry::Vacant(_) => panic!(),
/// }
///
/// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
/// assert!(set.contains(&"Stringthing".to_owned()));
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn replace(self) -> T {
self.inner.replace_key()
}
}
impl<'a, T, S, A: Allocator + Clone> VacantEntry<'a, T, S, A> {
/// Gets a reference to the value that would be used when inserting
/// through the `VacantEntry`.
///
/// # Examples
///
/// ```
/// use hashbrown::HashSet;
///
/// let mut set: HashSet<&str> = HashSet::new();
/// assert_eq!(set.entry("poneyland").get(), &"poneyland");
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn get(&self) -> &T {
self.inner.key()
}
/// Take ownership of the value.
///
/// # Examples
///
/// ```
/// use hashbrown::hash_set::{Entry, HashSet};
///
/// let mut set: HashSet<&str> = HashSet::new();
///
/// match set.entry("poneyland") {
/// Entry::Occupied(_) => panic!(),
/// Entry::Vacant(v) => assert_eq!(v.into_value(), "poneyland"),
/// }
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn into_value(self) -> T {
self.inner.into_key()
}
/// Sets the value of the entry with the VacantEntry's value.
///
/// # Examples
///
/// ```
/// use hashbrown::HashSet;
/// use hashbrown::hash_set::Entry;
///
/// let mut set: HashSet<&str> = HashSet::new();
///
/// if let Entry::Vacant(o) = set.entry("poneyland") {
/// o.insert();
/// }
/// assert!(set.contains("poneyland"));
/// ```
#[cfg_attr(feature = "inline-more", inline)]
pub fn insert(self)
where
T: Hash,
S: BuildHasher,
{
self.inner.insert(());
}
#[cfg_attr(feature = "inline-more", inline)]
fn insert_entry(self) -> OccupiedEntry<'a, T, S, A>
where
T: Hash,
S: BuildHasher,
{
OccupiedEntry {
inner: self.inner.insert_entry(()),
}
}
}
#[allow(dead_code)]
fn assert_covariance() {
fn set<'new>(v: HashSet<&'static str>) -> HashSet<&'new str> {
@ -1963,7 +2454,7 @@ mod test_set {
let expected = [3, 5, 11, 77];
for x in a.intersection(&b) {
assert!(expected.contains(x));
i += 1
i += 1;
}
assert_eq!(i, expected.len());
}
@ -1986,7 +2477,7 @@ mod test_set {
let expected = [1, 5, 11];
for x in a.difference(&b) {
assert!(expected.contains(x));
i += 1
i += 1;
}
assert_eq!(i, expected.len());
}
@ -2012,7 +2503,7 @@ mod test_set {
let expected = [-2, 1, 5, 11, 14, 22];
for x in a.symmetric_difference(&b) {
assert!(expected.contains(x));
i += 1
i += 1;
}
assert_eq!(i, expected.len());
}
@ -2042,7 +2533,7 @@ mod test_set {
let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
for x in a.union(&b) {
assert!(expected.contains(x));
i += 1
i += 1;
}
assert_eq!(i, expected.len());
}
@ -2068,7 +2559,7 @@ mod test_set {
fn test_from_iter() {
let xs = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9];
let set: HashSet<_> = xs.iter().cloned().collect();
let set: HashSet<_> = xs.iter().copied().collect();
for x in &xs {
assert!(set.contains(x));
@ -2230,7 +2721,7 @@ mod test_set {
#[test]
fn test_retain() {
let xs = [1, 2, 3, 4, 5, 6];
let mut set: HashSet<i32> = xs.iter().cloned().collect();
let mut set: HashSet<i32> = xs.iter().copied().collect();
set.retain(|&k| k % 2 == 0);
assert_eq!(set.len(), 3);
assert!(set.contains(&2));
@ -2272,7 +2763,7 @@ mod test_set {
const EMPTY_SET: HashSet<u32, MyHasher> = HashSet::with_hasher(MyHasher);
let mut set = EMPTY_SET.clone();
let mut set = EMPTY_SET;
set.insert(19);
assert!(set.contains(&19));
}

70
third_party/rust/hashbrown/tests/rayon.rs поставляемый
Просмотреть файл

@ -269,20 +269,20 @@ fn map_seq_par_equivalence_existing_empty_extend_empty() {
let mut map_seq = MAP_EXISTING_EMPTY.clone();
let mut map_par = MAP_EXISTING_EMPTY.clone();
map_seq.extend(MAP_EXTENSION_EMPTY.iter().cloned());
map_par.par_extend(MAP_EXTENSION_EMPTY.par_iter().cloned());
map_seq.extend(MAP_EXTENSION_EMPTY.iter().copied());
map_par.par_extend(MAP_EXTENSION_EMPTY.par_iter().copied());
assert_eq3!(map_seq, map_par, expected);
}
#[test]
fn map_seq_par_equivalence_existing_empty_extend() {
let expected = MAP_EXTENSION.iter().cloned().collect::<HashMap<_, _>>();
let expected = MAP_EXTENSION.iter().copied().collect::<HashMap<_, _>>();
let mut map_seq = MAP_EXISTING_EMPTY.clone();
let mut map_par = MAP_EXISTING_EMPTY.clone();
map_seq.extend(MAP_EXTENSION.iter().cloned());
map_par.par_extend(MAP_EXTENSION.par_iter().cloned());
map_seq.extend(MAP_EXTENSION.iter().copied());
map_par.par_extend(MAP_EXTENSION.par_iter().copied());
assert_eq3!(map_seq, map_par, expected);
}
@ -293,8 +293,8 @@ fn map_seq_par_equivalence_existing_extend_empty() {
let mut map_seq = MAP_EXISTING.clone();
let mut map_par = MAP_EXISTING.clone();
map_seq.extend(MAP_EXTENSION_EMPTY.iter().cloned());
map_par.par_extend(MAP_EXTENSION_EMPTY.par_iter().cloned());
map_seq.extend(MAP_EXTENSION_EMPTY.iter().copied());
map_par.par_extend(MAP_EXTENSION_EMPTY.par_iter().copied());
assert_eq3!(map_seq, map_par, expected);
}
@ -305,8 +305,8 @@ fn map_seq_par_equivalence_existing_extend() {
let mut map_seq = MAP_EXISTING.clone();
let mut map_par = MAP_EXISTING.clone();
map_seq.extend(MAP_EXTENSION.iter().cloned());
map_par.par_extend(MAP_EXTENSION.par_iter().cloned());
map_seq.extend(MAP_EXTENSION.iter().copied());
map_par.par_extend(MAP_EXTENSION.par_iter().copied());
assert_eq3!(map_seq, map_par, expected);
}
@ -423,20 +423,20 @@ fn set_seq_par_equivalence_existing_empty_extend_empty() {
let mut set_seq = SET_EXISTING_EMPTY.clone();
let mut set_par = SET_EXISTING_EMPTY.clone();
set_seq.extend(SET_EXTENSION_EMPTY.iter().cloned());
set_par.par_extend(SET_EXTENSION_EMPTY.par_iter().cloned());
set_seq.extend(SET_EXTENSION_EMPTY.iter().copied());
set_par.par_extend(SET_EXTENSION_EMPTY.par_iter().copied());
assert_eq3!(set_seq, set_par, expected);
}
#[test]
fn set_seq_par_equivalence_existing_empty_extend() {
let expected = SET_EXTENSION.iter().cloned().collect::<HashSet<_>>();
let expected = SET_EXTENSION.iter().copied().collect::<HashSet<_>>();
let mut set_seq = SET_EXISTING_EMPTY.clone();
let mut set_par = SET_EXISTING_EMPTY.clone();
set_seq.extend(SET_EXTENSION.iter().cloned());
set_par.par_extend(SET_EXTENSION.par_iter().cloned());
set_seq.extend(SET_EXTENSION.iter().copied());
set_par.par_extend(SET_EXTENSION.par_iter().copied());
assert_eq3!(set_seq, set_par, expected);
}
@ -447,8 +447,8 @@ fn set_seq_par_equivalence_existing_extend_empty() {
let mut set_seq = SET_EXISTING.clone();
let mut set_par = SET_EXISTING.clone();
set_seq.extend(SET_EXTENSION_EMPTY.iter().cloned());
set_par.par_extend(SET_EXTENSION_EMPTY.par_iter().cloned());
set_seq.extend(SET_EXTENSION_EMPTY.iter().copied());
set_par.par_extend(SET_EXTENSION_EMPTY.par_iter().copied());
assert_eq3!(set_seq, set_par, expected);
}
@ -459,37 +459,37 @@ fn set_seq_par_equivalence_existing_extend() {
let mut set_seq = SET_EXISTING.clone();
let mut set_par = SET_EXISTING.clone();
set_seq.extend(SET_EXTENSION.iter().cloned());
set_par.par_extend(SET_EXTENSION.par_iter().cloned());
set_seq.extend(SET_EXTENSION.iter().copied());
set_par.par_extend(SET_EXTENSION.par_iter().copied());
assert_eq3!(set_seq, set_par, expected);
}
lazy_static! {
static ref SET_A: HashSet<char> = ['a', 'b', 'c', 'd'].iter().cloned().collect();
static ref SET_B: HashSet<char> = ['a', 'b', 'e', 'f'].iter().cloned().collect();
static ref SET_DIFF_AB: HashSet<char> = ['c', 'd'].iter().cloned().collect();
static ref SET_DIFF_BA: HashSet<char> = ['e', 'f'].iter().cloned().collect();
static ref SET_SYMM_DIFF_AB: HashSet<char> = ['c', 'd', 'e', 'f'].iter().cloned().collect();
static ref SET_INTERSECTION_AB: HashSet<char> = ['a', 'b'].iter().cloned().collect();
static ref SET_A: HashSet<char> = ['a', 'b', 'c', 'd'].iter().copied().collect();
static ref SET_B: HashSet<char> = ['a', 'b', 'e', 'f'].iter().copied().collect();
static ref SET_DIFF_AB: HashSet<char> = ['c', 'd'].iter().copied().collect();
static ref SET_DIFF_BA: HashSet<char> = ['e', 'f'].iter().copied().collect();
static ref SET_SYMM_DIFF_AB: HashSet<char> = ['c', 'd', 'e', 'f'].iter().copied().collect();
static ref SET_INTERSECTION_AB: HashSet<char> = ['a', 'b'].iter().copied().collect();
static ref SET_UNION_AB: HashSet<char> =
['a', 'b', 'c', 'd', 'e', 'f'].iter().cloned().collect();
['a', 'b', 'c', 'd', 'e', 'f'].iter().copied().collect();
}
#[test]
fn set_seq_par_equivalence_difference() {
let diff_ab_seq = SET_A.difference(&*SET_B).cloned().collect::<HashSet<_>>();
let diff_ab_seq = SET_A.difference(&*SET_B).copied().collect::<HashSet<_>>();
let diff_ab_par = SET_A
.par_difference(&*SET_B)
.cloned()
.copied()
.collect::<HashSet<_>>();
assert_eq3!(diff_ab_seq, diff_ab_par, *SET_DIFF_AB);
let diff_ba_seq = SET_B.difference(&*SET_A).cloned().collect::<HashSet<_>>();
let diff_ba_seq = SET_B.difference(&*SET_A).copied().collect::<HashSet<_>>();
let diff_ba_par = SET_B
.par_difference(&*SET_A)
.cloned()
.copied()
.collect::<HashSet<_>>();
assert_eq3!(diff_ba_seq, diff_ba_par, *SET_DIFF_BA);
@ -499,11 +499,11 @@ fn set_seq_par_equivalence_difference() {
fn set_seq_par_equivalence_symmetric_difference() {
let symm_diff_ab_seq = SET_A
.symmetric_difference(&*SET_B)
.cloned()
.copied()
.collect::<HashSet<_>>();
let symm_diff_ab_par = SET_A
.par_symmetric_difference(&*SET_B)
.cloned()
.copied()
.collect::<HashSet<_>>();
assert_eq3!(symm_diff_ab_seq, symm_diff_ab_par, *SET_SYMM_DIFF_AB);
@ -511,10 +511,10 @@ fn set_seq_par_equivalence_symmetric_difference() {
#[test]
fn set_seq_par_equivalence_intersection() {
let intersection_ab_seq = SET_A.intersection(&*SET_B).cloned().collect::<HashSet<_>>();
let intersection_ab_seq = SET_A.intersection(&*SET_B).copied().collect::<HashSet<_>>();
let intersection_ab_par = SET_A
.par_intersection(&*SET_B)
.cloned()
.copied()
.collect::<HashSet<_>>();
assert_eq3!(
@ -526,8 +526,8 @@ fn set_seq_par_equivalence_intersection() {
#[test]
fn set_seq_par_equivalence_union() {
let union_ab_seq = SET_A.union(&*SET_B).cloned().collect::<HashSet<_>>();
let union_ab_par = SET_A.par_union(&*SET_B).cloned().collect::<HashSet<_>>();
let union_ab_seq = SET_A.union(&*SET_B).copied().collect::<HashSet<_>>();
let union_ab_par = SET_A.par_union(&*SET_B).copied().collect::<HashSet<_>>();
assert_eq3!(union_ab_seq, union_ab_par, *SET_UNION_AB);
}

32
third_party/rust/hashbrown/tests/set.rs поставляемый
Просмотреть файл

@ -2,29 +2,33 @@
use hashbrown::HashSet;
use rand::{distributions::Alphanumeric, rngs::SmallRng, Rng, SeedableRng};
use std::iter;
#[test]
fn test_hashset_insert_remove() {
let mut m: HashSet<Vec<char>> = HashSet::new();
//let num: u32 = 4096;
//let tx: Vec<Vec<u8>> = (0..num).map(|i| (i..(16 + i)).collect()).collect();
let seed: [u8; 16] = [
130, 220, 246, 217, 111, 124, 221, 189, 190, 234, 121, 93, 67, 95, 100, 43,
];
let seed = u64::from_le_bytes(*b"testseed");
let rng = &mut SmallRng::from_seed(seed);
let tx: Vec<Vec<char>> = (0..4096)
.map(|_| (rng.sample_iter(&Alphanumeric).take(32).collect()))
let rng = &mut SmallRng::seed_from_u64(seed);
let tx: Vec<Vec<char>> = iter::repeat_with(|| {
rng.sample_iter(&Alphanumeric)
.take(32)
.map(char::from)
.collect()
})
.take(4096)
.collect();
// more readable with explicit `true` / `false`
#[allow(clippy::bool_assert_comparison)]
for _ in 0..32 {
for i in 0..4096 {
assert_eq!(m.contains(&tx[i].clone()), false);
assert_eq!(m.insert(tx[i].clone()), true);
for x in &tx {
assert_eq!(m.contains(x), false);
assert_eq!(m.insert(x.clone()), true);
}
for i in 0..4096 {
println!("removing {} {:?}", i, tx[i]);
assert_eq!(m.remove(&tx[i]), true);
for (i, x) in tx.iter().enumerate() {
println!("removing {} {:?}", i, x);
assert_eq!(m.remove(x), true);
}
}
}