├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src ├── fnv.rs ├── lib.rs ├── map.rs ├── set.rs └── table.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | **/*.rs.bk 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | sudo: false 3 | 4 | rust: 5 | - nightly 6 | 7 | before_script: 8 | - | 9 | pip install 'travis-cargo<0.2' --user && 10 | export PATH=$HOME/.local/bin:$PATH 11 | 12 | script: 13 | - travis-cargo build 14 | - travis-cargo doc -- --no-deps 15 | 16 | env: 17 | global: 18 | - TRAVIS_CARGO_NIGHTLY_FEATURE="" 19 | 20 | notifications: 21 | email: false 22 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hashmap_core" 3 | version = "0.1.11" 4 | authors = ["Amanieu d'Antras "] 5 | description = "Implementation of HashMap and HashSet for no_std environments." 6 | documentation = "https://docs.rs/hashmap_core/" 7 | license = "Apache-2.0/MIT" 8 | repository = "https://github.com/Amanieu/hashmap_core" 9 | readme = "README.md" 10 | keywords = ["hashmap", "hashset", "no_std", "hash", "fnv"] 11 | 12 | [features] 13 | # workaround for some cargo deficiency 14 | disable = [] 15 | 16 | [dependencies] 17 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## This crate is deprecated, use [hashbrown](https://github.com/rust-lang/hashbrown) instead. 2 | 3 | hashmap_core 4 | ========= 5 | 6 | [![Build Status](https://travis-ci.org/Amanieu/hashmap_core.svg?branch=master)](https://travis-ci.org/Amanieu/hashmap_core) [![Crates.io](https://img.shields.io/crates/v/hashmap_core.svg)](https://crates.io/crates/hashmap_core) 7 | 8 | This crate provides an implementation of `HashMap` and `HashSet` which do not depend on the standard library and are suitable for `no_std` environments. 9 | 10 | This crate uses the FNV instead of SipHash for the default hasher, because the latter requires a source of random numbers which may not be available in `no_std` environments. 11 | 12 | This crate is nightly-only for now since it uses the `alloc` crate, which is unstable. 13 | 14 | ### Documentation 15 | 16 | [https://docs.rs/hashmap_core](https://docs.rs/hashmap_core) 17 | 18 | ## License 19 | 20 | Licensed under either of 21 | 22 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 23 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 24 | 25 | at your option. 26 | 27 | ### Contribution 28 | 29 | Unless you explicitly state otherwise, any contribution intentionally submitted 30 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any 31 | additional terms or conditions. 32 | -------------------------------------------------------------------------------- /src/fnv.rs: -------------------------------------------------------------------------------- 1 | //! An implementation of the [Fowler–Noll–Vo hash function][chongo]. 2 | //! 3 | //! ## About 4 | //! 5 | //! The FNV hash function is a custom `Hasher` implementation that is more 6 | //! efficient for smaller hash keys. 7 | //! 8 | //! [The Rust FAQ states that][faq] while the default `Hasher` implementation, 9 | //! SipHash, is good in many cases, it is notably slower than other algorithms 10 | //! with short keys, such as when you have a map of integers to other values. 11 | //! In cases like these, [FNV is demonstrably faster][graphs]. 12 | //! 13 | //! Its disadvantages are that it performs badly on larger inputs, and 14 | //! provides no protection against collision attacks, where a malicious user 15 | //! can craft specific keys designed to slow a hasher down. Thus, it is 16 | //! important to profile your program to ensure that you are using small hash 17 | //! keys, and be certain that your program could not be exposed to malicious 18 | //! inputs (including being a networked server). 19 | //! 20 | //! The Rust compiler itself uses FNV, as it is not worried about 21 | //! denial-of-service attacks, and can assume that its inputs are going to be 22 | //! small—a perfect use case for FNV. 23 | //! 24 | //! 25 | //! ## Using FNV in a `HashMap` 26 | //! 27 | //! The `FnvHashMap` type alias is the easiest way to use the standard library’s 28 | //! `HashMap` with FNV. 29 | //! 30 | //! ```rust 31 | //! use hashmap_core::fnv::FnvHashMap; 32 | //! 33 | //! let mut map = FnvHashMap::default(); 34 | //! map.insert(1, "one"); 35 | //! map.insert(2, "two"); 36 | //! 37 | //! map = FnvHashMap::with_capacity_and_hasher(10, Default::default()); 38 | //! map.insert(1, "one"); 39 | //! map.insert(2, "two"); 40 | //! ``` 41 | //! 42 | //! Note, the standard library’s `HashMap::new` and `HashMap::with_capacity` 43 | //! are only implemented for the `RandomState` hasher, so using `Default` to 44 | //! get the hasher is the next best option. 45 | //! 46 | //! ## Using FNV in a `HashSet` 47 | //! 48 | //! Similarly, `FnvHashSet` is a type alias for the standard library’s `HashSet` 49 | //! with FNV. 50 | //! 51 | //! ```rust 52 | //! use hashmap_core::fnv::FnvHashSet; 53 | //! 54 | //! let mut set = FnvHashSet::default(); 55 | //! set.insert(1); 56 | //! set.insert(2); 57 | //! 58 | //! set = FnvHashSet::with_capacity_and_hasher(10, Default::default()); 59 | //! set.insert(1); 60 | //! set.insert(2); 61 | //! ``` 62 | //! 63 | //! [chongo]: http://www.isthe.com/chongo/tech/comp/fnv/index.html 64 | //! [faq]: https://www.rust-lang.org/faq.html#why-are-rusts-hashmaps-slow 65 | //! [graphs]: http://cglab.ca/~abeinges/blah/hash-rs/ 66 | 67 | use core::default::Default; 68 | use core::hash::{BuildHasherDefault, Hasher}; 69 | use {HashMap, HashSet}; 70 | 71 | /// An implementation of the Fowler–Noll–Vo hash function. 72 | /// 73 | /// See the [crate documentation](index.html) for more details. 74 | #[allow(missing_copy_implementations)] 75 | pub struct FnvHasher(u64); 76 | 77 | impl Default for FnvHasher { 78 | #[inline] 79 | fn default() -> FnvHasher { 80 | FnvHasher(0xcbf29ce484222325) 81 | } 82 | } 83 | 84 | impl FnvHasher { 85 | /// Create an FNV hasher starting with a state corresponding 86 | /// to the hash `key`. 87 | #[inline] 88 | pub fn with_key(key: u64) -> FnvHasher { 89 | FnvHasher(key) 90 | } 91 | } 92 | 93 | impl Hasher for FnvHasher { 94 | #[inline] 95 | fn finish(&self) -> u64 { 96 | self.0 97 | } 98 | 99 | #[inline] 100 | fn write(&mut self, bytes: &[u8]) { 101 | let FnvHasher(mut hash) = *self; 102 | 103 | for byte in bytes.iter() { 104 | hash = hash ^ (*byte as u64); 105 | hash = hash.wrapping_mul(0x100000001b3); 106 | } 107 | 108 | *self = FnvHasher(hash); 109 | } 110 | } 111 | 112 | /// A builder for default FNV hashers. 113 | pub type FnvBuildHasher = BuildHasherDefault; 114 | 115 | /// A `HashMap` using a default FNV hasher. 116 | pub type FnvHashMap = HashMap; 117 | 118 | /// A `HashSet` using a default FNV hasher. 119 | pub type FnvHashSet = HashSet; 120 | 121 | #[cfg(test)] 122 | mod test { 123 | use super::*; 124 | use alloc::Vec; 125 | use core::hash::Hasher; 126 | 127 | fn fnv1a(bytes: &[u8]) -> u64 { 128 | let mut hasher = FnvHasher::default(); 129 | hasher.write(bytes); 130 | hasher.finish() 131 | } 132 | 133 | fn repeat_10(bytes: &[u8]) -> Vec { 134 | (0..10).flat_map(|_| bytes.iter().cloned()).collect() 135 | } 136 | 137 | fn repeat_500(bytes: &[u8]) -> Vec { 138 | (0..500).flat_map(|_| bytes.iter().cloned()).collect() 139 | } 140 | 141 | #[test] 142 | fn basic_tests() { 143 | assert_eq!(fnv1a(b""), 0xcbf29ce484222325); 144 | assert_eq!(fnv1a(b"a"), 0xaf63dc4c8601ec8c); 145 | assert_eq!(fnv1a(b"b"), 0xaf63df4c8601f1a5); 146 | assert_eq!(fnv1a(b"c"), 0xaf63de4c8601eff2); 147 | assert_eq!(fnv1a(b"d"), 0xaf63d94c8601e773); 148 | assert_eq!(fnv1a(b"e"), 0xaf63d84c8601e5c0); 149 | assert_eq!(fnv1a(b"f"), 0xaf63db4c8601ead9); 150 | assert_eq!(fnv1a(b"fo"), 0x08985907b541d342); 151 | assert_eq!(fnv1a(b"foo"), 0xdcb27518fed9d577); 152 | assert_eq!(fnv1a(b"foob"), 0xdd120e790c2512af); 153 | assert_eq!(fnv1a(b"fooba"), 0xcac165afa2fef40a); 154 | assert_eq!(fnv1a(b"foobar"), 0x85944171f73967e8); 155 | assert_eq!(fnv1a(b"\0"), 0xaf63bd4c8601b7df); 156 | assert_eq!(fnv1a(b"a\0"), 0x089be207b544f1e4); 157 | assert_eq!(fnv1a(b"b\0"), 0x08a61407b54d9b5f); 158 | assert_eq!(fnv1a(b"c\0"), 0x08a2ae07b54ab836); 159 | assert_eq!(fnv1a(b"d\0"), 0x0891b007b53c4869); 160 | assert_eq!(fnv1a(b"e\0"), 0x088e4a07b5396540); 161 | assert_eq!(fnv1a(b"f\0"), 0x08987c07b5420ebb); 162 | assert_eq!(fnv1a(b"fo\0"), 0xdcb28a18fed9f926); 163 | assert_eq!(fnv1a(b"foo\0"), 0xdd1270790c25b935); 164 | assert_eq!(fnv1a(b"foob\0"), 0xcac146afa2febf5d); 165 | assert_eq!(fnv1a(b"fooba\0"), 0x8593d371f738acfe); 166 | assert_eq!(fnv1a(b"foobar\0"), 0x34531ca7168b8f38); 167 | assert_eq!(fnv1a(b"ch"), 0x08a25607b54a22ae); 168 | assert_eq!(fnv1a(b"cho"), 0xf5faf0190cf90df3); 169 | assert_eq!(fnv1a(b"chon"), 0xf27397910b3221c7); 170 | assert_eq!(fnv1a(b"chong"), 0x2c8c2b76062f22e0); 171 | assert_eq!(fnv1a(b"chongo"), 0xe150688c8217b8fd); 172 | assert_eq!(fnv1a(b"chongo "), 0xf35a83c10e4f1f87); 173 | assert_eq!(fnv1a(b"chongo w"), 0xd1edd10b507344d0); 174 | assert_eq!(fnv1a(b"chongo wa"), 0x2a5ee739b3ddb8c3); 175 | assert_eq!(fnv1a(b"chongo was"), 0xdcfb970ca1c0d310); 176 | assert_eq!(fnv1a(b"chongo was "), 0x4054da76daa6da90); 177 | assert_eq!(fnv1a(b"chongo was h"), 0xf70a2ff589861368); 178 | assert_eq!(fnv1a(b"chongo was he"), 0x4c628b38aed25f17); 179 | assert_eq!(fnv1a(b"chongo was her"), 0x9dd1f6510f78189f); 180 | assert_eq!(fnv1a(b"chongo was here"), 0xa3de85bd491270ce); 181 | assert_eq!(fnv1a(b"chongo was here!"), 0x858e2fa32a55e61d); 182 | assert_eq!(fnv1a(b"chongo was here!\n"), 0x46810940eff5f915); 183 | assert_eq!(fnv1a(b"ch\0"), 0xf5fadd190cf8edaa); 184 | assert_eq!(fnv1a(b"cho\0"), 0xf273ed910b32b3e9); 185 | assert_eq!(fnv1a(b"chon\0"), 0x2c8c5276062f6525); 186 | assert_eq!(fnv1a(b"chong\0"), 0xe150b98c821842a0); 187 | assert_eq!(fnv1a(b"chongo\0"), 0xf35aa3c10e4f55e7); 188 | assert_eq!(fnv1a(b"chongo \0"), 0xd1ed680b50729265); 189 | assert_eq!(fnv1a(b"chongo w\0"), 0x2a5f0639b3dded70); 190 | assert_eq!(fnv1a(b"chongo wa\0"), 0xdcfbaa0ca1c0f359); 191 | assert_eq!(fnv1a(b"chongo was\0"), 0x4054ba76daa6a430); 192 | assert_eq!(fnv1a(b"chongo was \0"), 0xf709c7f5898562b0); 193 | assert_eq!(fnv1a(b"chongo was h\0"), 0x4c62e638aed2f9b8); 194 | assert_eq!(fnv1a(b"chongo was he\0"), 0x9dd1a8510f779415); 195 | assert_eq!(fnv1a(b"chongo was her\0"), 0xa3de2abd4911d62d); 196 | assert_eq!(fnv1a(b"chongo was here\0"), 0x858e0ea32a55ae0a); 197 | assert_eq!(fnv1a(b"chongo was here!\0"), 0x46810f40eff60347); 198 | assert_eq!(fnv1a(b"chongo was here!\n\0"), 0xc33bce57bef63eaf); 199 | assert_eq!(fnv1a(b"cu"), 0x08a24307b54a0265); 200 | assert_eq!(fnv1a(b"cur"), 0xf5b9fd190cc18d15); 201 | assert_eq!(fnv1a(b"curd"), 0x4c968290ace35703); 202 | assert_eq!(fnv1a(b"curds"), 0x07174bd5c64d9350); 203 | assert_eq!(fnv1a(b"curds "), 0x5a294c3ff5d18750); 204 | assert_eq!(fnv1a(b"curds a"), 0x05b3c1aeb308b843); 205 | assert_eq!(fnv1a(b"curds an"), 0xb92a48da37d0f477); 206 | assert_eq!(fnv1a(b"curds and"), 0x73cdddccd80ebc49); 207 | assert_eq!(fnv1a(b"curds and "), 0xd58c4c13210a266b); 208 | assert_eq!(fnv1a(b"curds and w"), 0xe78b6081243ec194); 209 | assert_eq!(fnv1a(b"curds and wh"), 0xb096f77096a39f34); 210 | assert_eq!(fnv1a(b"curds and whe"), 0xb425c54ff807b6a3); 211 | assert_eq!(fnv1a(b"curds and whey"), 0x23e520e2751bb46e); 212 | assert_eq!(fnv1a(b"curds and whey\n"), 0x1a0b44ccfe1385ec); 213 | assert_eq!(fnv1a(b"cu\0"), 0xf5ba4b190cc2119f); 214 | assert_eq!(fnv1a(b"cur\0"), 0x4c962690ace2baaf); 215 | assert_eq!(fnv1a(b"curd\0"), 0x0716ded5c64cda19); 216 | assert_eq!(fnv1a(b"curds\0"), 0x5a292c3ff5d150f0); 217 | assert_eq!(fnv1a(b"curds \0"), 0x05b3e0aeb308ecf0); 218 | assert_eq!(fnv1a(b"curds a\0"), 0xb92a5eda37d119d9); 219 | assert_eq!(fnv1a(b"curds an\0"), 0x73ce41ccd80f6635); 220 | assert_eq!(fnv1a(b"curds and\0"), 0xd58c2c132109f00b); 221 | assert_eq!(fnv1a(b"curds and \0"), 0xe78baf81243f47d1); 222 | assert_eq!(fnv1a(b"curds and w\0"), 0xb0968f7096a2ee7c); 223 | assert_eq!(fnv1a(b"curds and wh\0"), 0xb425a84ff807855c); 224 | assert_eq!(fnv1a(b"curds and whe\0"), 0x23e4e9e2751b56f9); 225 | assert_eq!(fnv1a(b"curds and whey\0"), 0x1a0b4eccfe1396ea); 226 | assert_eq!(fnv1a(b"curds and whey\n\0"), 0x54abd453bb2c9004); 227 | assert_eq!(fnv1a(b"hi"), 0x08ba5f07b55ec3da); 228 | assert_eq!(fnv1a(b"hi\0"), 0x337354193006cb6e); 229 | assert_eq!(fnv1a(b"hello"), 0xa430d84680aabd0b); 230 | assert_eq!(fnv1a(b"hello\0"), 0xa9bc8acca21f39b1); 231 | assert_eq!(fnv1a(b"\xff\x00\x00\x01"), 0x6961196491cc682d); 232 | assert_eq!(fnv1a(b"\x01\x00\x00\xff"), 0xad2bb1774799dfe9); 233 | assert_eq!(fnv1a(b"\xff\x00\x00\x02"), 0x6961166491cc6314); 234 | assert_eq!(fnv1a(b"\x02\x00\x00\xff"), 0x8d1bb3904a3b1236); 235 | assert_eq!(fnv1a(b"\xff\x00\x00\x03"), 0x6961176491cc64c7); 236 | assert_eq!(fnv1a(b"\x03\x00\x00\xff"), 0xed205d87f40434c7); 237 | assert_eq!(fnv1a(b"\xff\x00\x00\x04"), 0x6961146491cc5fae); 238 | assert_eq!(fnv1a(b"\x04\x00\x00\xff"), 0xcd3baf5e44f8ad9c); 239 | assert_eq!(fnv1a(b"\x40\x51\x4e\x44"), 0xe3b36596127cd6d8); 240 | assert_eq!(fnv1a(b"\x44\x4e\x51\x40"), 0xf77f1072c8e8a646); 241 | assert_eq!(fnv1a(b"\x40\x51\x4e\x4a"), 0xe3b36396127cd372); 242 | assert_eq!(fnv1a(b"\x4a\x4e\x51\x40"), 0x6067dce9932ad458); 243 | assert_eq!(fnv1a(b"\x40\x51\x4e\x54"), 0xe3b37596127cf208); 244 | assert_eq!(fnv1a(b"\x54\x4e\x51\x40"), 0x4b7b10fa9fe83936); 245 | assert_eq!(fnv1a(b"127.0.0.1"), 0xaabafe7104d914be); 246 | assert_eq!(fnv1a(b"127.0.0.1\0"), 0xf4d3180b3cde3eda); 247 | assert_eq!(fnv1a(b"127.0.0.2"), 0xaabafd7104d9130b); 248 | assert_eq!(fnv1a(b"127.0.0.2\0"), 0xf4cfb20b3cdb5bb1); 249 | assert_eq!(fnv1a(b"127.0.0.3"), 0xaabafc7104d91158); 250 | assert_eq!(fnv1a(b"127.0.0.3\0"), 0xf4cc4c0b3cd87888); 251 | assert_eq!(fnv1a(b"64.81.78.68"), 0xe729bac5d2a8d3a7); 252 | assert_eq!(fnv1a(b"64.81.78.68\0"), 0x74bc0524f4dfa4c5); 253 | assert_eq!(fnv1a(b"64.81.78.74"), 0xe72630c5d2a5b352); 254 | assert_eq!(fnv1a(b"64.81.78.74\0"), 0x6b983224ef8fb456); 255 | assert_eq!(fnv1a(b"64.81.78.84"), 0xe73042c5d2ae266d); 256 | assert_eq!(fnv1a(b"64.81.78.84\0"), 0x8527e324fdeb4b37); 257 | assert_eq!(fnv1a(b"feedface"), 0x0a83c86fee952abc); 258 | assert_eq!(fnv1a(b"feedface\0"), 0x7318523267779d74); 259 | assert_eq!(fnv1a(b"feedfacedaffdeed"), 0x3e66d3d56b8caca1); 260 | assert_eq!(fnv1a(b"feedfacedaffdeed\0"), 0x956694a5c0095593); 261 | assert_eq!(fnv1a(b"feedfacedeadbeef"), 0xcac54572bb1a6fc8); 262 | assert_eq!(fnv1a(b"feedfacedeadbeef\0"), 0xa7a4c9f3edebf0d8); 263 | assert_eq!(fnv1a(b"line 1\nline 2\nline 3"), 0x7829851fac17b143); 264 | assert_eq!( 265 | fnv1a(b"chongo /\\../\\"), 266 | 0x2c8f4c9af81bcf06 267 | ); 268 | assert_eq!( 269 | fnv1a(b"chongo /\\../\\\0"), 270 | 0xd34e31539740c732 271 | ); 272 | assert_eq!( 273 | fnv1a(b"chongo (Landon Curt Noll) /\\../\\"), 274 | 0x3605a2ac253d2db1 275 | ); 276 | assert_eq!( 277 | fnv1a(b"chongo (Landon Curt Noll) /\\../\\\0"), 278 | 0x08c11b8346f4a3c3 279 | ); 280 | assert_eq!( 281 | fnv1a(b"http://antwrp.gsfc.nasa.gov/apod/astropix.html"), 282 | 0x6be396289ce8a6da 283 | ); 284 | assert_eq!( 285 | fnv1a(b"http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash"), 286 | 0xd9b957fb7fe794c5 287 | ); 288 | assert_eq!(fnv1a(b"http://epod.usra.edu/"), 0x05be33da04560a93); 289 | assert_eq!(fnv1a(b"http://exoplanet.eu/"), 0x0957f1577ba9747c); 290 | assert_eq!(fnv1a(b"http://hvo.wr.usgs.gov/cam3/"), 0xda2cc3acc24fba57); 291 | assert_eq!( 292 | fnv1a(b"http://hvo.wr.usgs.gov/cams/HMcam/"), 293 | 0x74136f185b29e7f0 294 | ); 295 | assert_eq!( 296 | fnv1a(b"http://hvo.wr.usgs.gov/kilauea/update/deformation.html"), 297 | 0xb2f2b4590edb93b2 298 | ); 299 | assert_eq!( 300 | fnv1a(b"http://hvo.wr.usgs.gov/kilauea/update/images.html"), 301 | 0xb3608fce8b86ae04 302 | ); 303 | assert_eq!( 304 | fnv1a(b"http://hvo.wr.usgs.gov/kilauea/update/maps.html"), 305 | 0x4a3a865079359063 306 | ); 307 | assert_eq!( 308 | fnv1a(b"http://hvo.wr.usgs.gov/volcanowatch/current_issue.html"), 309 | 0x5b3a7ef496880a50 310 | ); 311 | assert_eq!(fnv1a(b"http://neo.jpl.nasa.gov/risk/"), 0x48fae3163854c23b); 312 | assert_eq!(fnv1a(b"http://norvig.com/21-days.html"), 0x07aaa640476e0b9a); 313 | assert_eq!( 314 | fnv1a(b"http://primes.utm.edu/curios/home.php"), 315 | 0x2f653656383a687d 316 | ); 317 | assert_eq!(fnv1a(b"http://slashdot.org/"), 0xa1031f8e7599d79c); 318 | assert_eq!( 319 | fnv1a(b"http://tux.wr.usgs.gov/Maps/155.25-19.5.html"), 320 | 0xa31908178ff92477 321 | ); 322 | assert_eq!( 323 | fnv1a(b"http://volcano.wr.usgs.gov/kilaueastatus.php"), 324 | 0x097edf3c14c3fb83 325 | ); 326 | assert_eq!( 327 | fnv1a(b"http://www.avo.alaska.edu/activity/Redoubt.php"), 328 | 0xb51ca83feaa0971b 329 | ); 330 | assert_eq!(fnv1a(b"http://www.dilbert.com/fast/"), 0xdd3c0d96d784f2e9); 331 | assert_eq!( 332 | fnv1a(b"http://www.fourmilab.ch/gravitation/orbits/"), 333 | 0x86cd26a9ea767d78 334 | ); 335 | assert_eq!(fnv1a(b"http://www.fpoa.net/"), 0xe6b215ff54a30c18); 336 | assert_eq!( 337 | fnv1a(b"http://www.ioccc.org/index.html"), 338 | 0xec5b06a1c5531093 339 | ); 340 | assert_eq!( 341 | fnv1a(b"http://www.isthe.com/cgi-bin/number.cgi"), 342 | 0x45665a929f9ec5e5 343 | ); 344 | assert_eq!( 345 | fnv1a(b"http://www.isthe.com/chongo/bio.html"), 346 | 0x8c7609b4a9f10907 347 | ); 348 | assert_eq!( 349 | fnv1a(b"http://www.isthe.com/chongo/index.html"), 350 | 0x89aac3a491f0d729 351 | ); 352 | assert_eq!( 353 | fnv1a(b"http://www.isthe.com/chongo/src/calc/lucas-calc"), 354 | 0x32ce6b26e0f4a403 355 | ); 356 | assert_eq!( 357 | fnv1a(b"http://www.isthe.com/chongo/tech/astro/venus2004.html"), 358 | 0x614ab44e02b53e01 359 | ); 360 | assert_eq!( 361 | fnv1a(b"http://www.isthe.com/chongo/tech/astro/vita.html"), 362 | 0xfa6472eb6eef3290 363 | ); 364 | assert_eq!( 365 | fnv1a(b"http://www.isthe.com/chongo/tech/comp/c/expert.html"), 366 | 0x9e5d75eb1948eb6a 367 | ); 368 | assert_eq!( 369 | fnv1a(b"http://www.isthe.com/chongo/tech/comp/calc/index.html"), 370 | 0xb6d12ad4a8671852 371 | ); 372 | assert_eq!( 373 | fnv1a(b"http://www.isthe.com/chongo/tech/comp/fnv/index.html"), 374 | 0x88826f56eba07af1 375 | ); 376 | assert_eq!( 377 | fnv1a(b"http://www.isthe.com/chongo/tech/math/number/howhigh.html"), 378 | 0x44535bf2645bc0fd 379 | ); 380 | assert_eq!( 381 | fnv1a(b"http://www.isthe.com/chongo/tech/math/number/number.html"), 382 | 0x169388ffc21e3728 383 | ); 384 | assert_eq!( 385 | fnv1a(b"http://www.isthe.com/chongo/tech/math/prime/mersenne.html"), 386 | 0xf68aac9e396d8224 387 | ); 388 | assert_eq!( 389 | fnv1a(b"http://www.isthe.com/chongo/tech/math/prime/mersenne.html#largest"), 390 | 0x8e87d7e7472b3883 391 | ); 392 | assert_eq!( 393 | fnv1a(b"http://www.lavarnd.org/cgi-bin/corpspeak.cgi"), 394 | 0x295c26caa8b423de 395 | ); 396 | assert_eq!( 397 | fnv1a(b"http://www.lavarnd.org/cgi-bin/haiku.cgi"), 398 | 0x322c814292e72176 399 | ); 400 | assert_eq!( 401 | fnv1a(b"http://www.lavarnd.org/cgi-bin/rand-none.cgi"), 402 | 0x8a06550eb8af7268 403 | ); 404 | assert_eq!( 405 | fnv1a(b"http://www.lavarnd.org/cgi-bin/randdist.cgi"), 406 | 0xef86d60e661bcf71 407 | ); 408 | assert_eq!( 409 | fnv1a(b"http://www.lavarnd.org/index.html"), 410 | 0x9e5426c87f30ee54 411 | ); 412 | assert_eq!( 413 | fnv1a(b"http://www.lavarnd.org/what/nist-test.html"), 414 | 0xf1ea8aa826fd047e 415 | ); 416 | assert_eq!(fnv1a(b"http://www.macosxhints.com/"), 0x0babaf9a642cb769); 417 | assert_eq!(fnv1a(b"http://www.mellis.com/"), 0x4b3341d4068d012e); 418 | assert_eq!( 419 | fnv1a(b"http://www.nature.nps.gov/air/webcams/parks/havoso2alert/havoalert.cfm"), 420 | 0xd15605cbc30a335c 421 | ); 422 | assert_eq!( 423 | fnv1a(b"http://www.nature.nps.gov/air/webcams/parks/havoso2alert/timelines_24.cfm"), 424 | 0x5b21060aed8412e5 425 | ); 426 | assert_eq!(fnv1a(b"http://www.paulnoll.com/"), 0x45e2cda1ce6f4227); 427 | assert_eq!(fnv1a(b"http://www.pepysdiary.com/"), 0x50ae3745033ad7d4); 428 | assert_eq!( 429 | fnv1a(b"http://www.sciencenews.org/index/home/activity/view"), 430 | 0xaa4588ced46bf414 431 | ); 432 | assert_eq!( 433 | fnv1a(b"http://www.skyandtelescope.com/"), 434 | 0xc1b0056c4a95467e 435 | ); 436 | assert_eq!( 437 | fnv1a(b"http://www.sput.nl/~rob/sirius.html"), 438 | 0x56576a71de8b4089 439 | ); 440 | assert_eq!(fnv1a(b"http://www.systemexperts.com/"), 0xbf20965fa6dc927e); 441 | assert_eq!( 442 | fnv1a(b"http://www.tq-international.com/phpBB3/index.php"), 443 | 0x569f8383c2040882 444 | ); 445 | assert_eq!( 446 | fnv1a(b"http://www.travelquesttours.com/index.htm"), 447 | 0xe1e772fba08feca0 448 | ); 449 | assert_eq!( 450 | fnv1a(b"http://www.wunderground.com/global/stations/89606.html"), 451 | 0x4ced94af97138ac4 452 | ); 453 | assert_eq!(fnv1a(&repeat_10(b"21701")), 0xc4112ffb337a82fb); 454 | assert_eq!(fnv1a(&repeat_10(b"M21701")), 0xd64a4fd41de38b7d); 455 | assert_eq!(fnv1a(&repeat_10(b"2^21701-1")), 0x4cfc32329edebcbb); 456 | assert_eq!(fnv1a(&repeat_10(b"\x54\xc5")), 0x0803564445050395); 457 | assert_eq!(fnv1a(&repeat_10(b"\xc5\x54")), 0xaa1574ecf4642ffd); 458 | assert_eq!(fnv1a(&repeat_10(b"23209")), 0x694bc4e54cc315f9); 459 | assert_eq!(fnv1a(&repeat_10(b"M23209")), 0xa3d7cb273b011721); 460 | assert_eq!(fnv1a(&repeat_10(b"2^23209-1")), 0x577c2f8b6115bfa5); 461 | assert_eq!(fnv1a(&repeat_10(b"\x5a\xa9")), 0xb7ec8c1a769fb4c1); 462 | assert_eq!(fnv1a(&repeat_10(b"\xa9\x5a")), 0x5d5cfce63359ab19); 463 | assert_eq!(fnv1a(&repeat_10(b"391581216093")), 0x33b96c3cd65b5f71); 464 | assert_eq!(fnv1a(&repeat_10(b"391581*2^216093-1")), 0xd845097780602bb9); 465 | assert_eq!( 466 | fnv1a(&repeat_10(b"\x05\xf9\x9d\x03\x4c\x81")), 467 | 0x84d47645d02da3d5 468 | ); 469 | assert_eq!(fnv1a(&repeat_10(b"FEDCBA9876543210")), 0x83544f33b58773a5); 470 | assert_eq!( 471 | fnv1a(&repeat_10(b"\xfe\xdc\xba\x98\x76\x54\x32\x10")), 472 | 0x9175cbb2160836c5 473 | ); 474 | assert_eq!(fnv1a(&repeat_10(b"EFCDAB8967452301")), 0xc71b3bc175e72bc5); 475 | assert_eq!( 476 | fnv1a(&repeat_10(b"\xef\xcd\xab\x89\x67\x45\x23\x01")), 477 | 0x636806ac222ec985 478 | ); 479 | assert_eq!(fnv1a(&repeat_10(b"0123456789ABCDEF")), 0xb6ef0e6950f52ed5); 480 | assert_eq!( 481 | fnv1a(&repeat_10(b"\x01\x23\x45\x67\x89\xab\xcd\xef")), 482 | 0xead3d8a0f3dfdaa5 483 | ); 484 | assert_eq!(fnv1a(&repeat_10(b"1032547698BADCFE")), 0x922908fe9a861ba5); 485 | assert_eq!( 486 | fnv1a(&repeat_10(b"\x10\x32\x54\x76\x98\xba\xdc\xfe")), 487 | 0x6d4821de275fd5c5 488 | ); 489 | assert_eq!(fnv1a(&repeat_500(b"\x00")), 0x1fe3fce62bd816b5); 490 | assert_eq!(fnv1a(&repeat_500(b"\x07")), 0xc23e9fccd6f70591); 491 | assert_eq!(fnv1a(&repeat_500(b"~")), 0xc1af12bdfe16b5b5); 492 | assert_eq!(fnv1a(&repeat_500(b"\x7f")), 0x39e9f18f2f85e221); 493 | } 494 | } 495 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Unordered containers, implemented as hash-tables 12 | 13 | #![no_std] 14 | #![cfg_attr( 15 | not(feature = "disable"), 16 | feature(alloc, dropck_eyepatch, allocator_api, ptr_internals, try_reserve, alloc_layout_extra) 17 | )] 18 | 19 | #[cfg(not(feature = "disable"))] 20 | extern crate alloc as alloc_crate; 21 | 22 | #[cfg(not(feature = "disable"))] 23 | mod alloc { 24 | pub use alloc_crate::alloc::{handle_alloc_error, Global}; 25 | #[cfg(test)] 26 | pub use alloc_crate::vec::Vec; 27 | pub use core::alloc::*; 28 | } 29 | 30 | #[cfg(not(feature = "disable"))] 31 | mod collections { 32 | pub use alloc_crate::collections::CollectionAllocErr; 33 | } 34 | 35 | #[cfg(not(feature = "disable"))] 36 | #[deprecated = "use hashbrown instead"] 37 | pub mod fnv; 38 | #[cfg(not(feature = "disable"))] 39 | #[deprecated = "use hashbrown instead"] 40 | pub mod map; 41 | #[cfg(not(feature = "disable"))] 42 | #[deprecated = "use hashbrown instead"] 43 | pub mod set; 44 | #[cfg(not(feature = "disable"))] 45 | mod table; 46 | #[cfg(not(feature = "disable"))] 47 | #[cfg(not(feature = "disable"))] 48 | trait Recover { 49 | type Key; 50 | 51 | fn get(&self, key: &Q) -> Option<&Self::Key>; 52 | fn take(&mut self, key: &Q) -> Option; 53 | fn replace(&mut self, key: Self::Key) -> Option; 54 | } 55 | 56 | #[cfg(not(feature = "disable"))] 57 | #[deprecated = "use hashbrown instead"] 58 | pub use fnv::FnvHashMap; 59 | #[cfg(not(feature = "disable"))] 60 | #[deprecated = "use hashbrown instead"] 61 | pub use fnv::FnvHashSet; 62 | #[cfg(not(feature = "disable"))] 63 | #[deprecated = "use hashbrown instead"] 64 | pub use map::HashMap; 65 | #[cfg(not(feature = "disable"))] 66 | #[deprecated = "use hashbrown instead"] 67 | pub use set::HashSet; 68 | -------------------------------------------------------------------------------- /src/map.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | use self::Entry::*; 12 | use self::VacantEntryState::*; 13 | 14 | use collections::CollectionAllocErr; 15 | use core::borrow::Borrow; 16 | use core::cmp::max; 17 | use core::fmt::{self, Debug}; 18 | use core::hash::{BuildHasher, Hash}; 19 | use core::iter::{FromIterator, FusedIterator}; 20 | use core::mem::{self, replace}; 21 | use core::ops::{Deref, Index}; 22 | 23 | pub use fnv::FnvBuildHasher as RandomState; 24 | pub use fnv::FnvHasher as DefaultHasher; 25 | 26 | use super::table::BucketState::{Empty, Full}; 27 | use super::table::Fallibility::{Fallible, Infallible}; 28 | use super::table::{ 29 | self, Bucket, EmptyBucket, Fallibility, FullBucket, FullBucketMut, RawTable, SafeHash, 30 | }; 31 | 32 | const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two 33 | 34 | /// The default behavior of HashMap implements a maximum load factor of 90.9%. 35 | #[derive(Clone)] 36 | struct DefaultResizePolicy; 37 | 38 | impl DefaultResizePolicy { 39 | #[inline] 40 | fn new() -> DefaultResizePolicy { 41 | DefaultResizePolicy 42 | } 43 | 44 | /// A hash map's "capacity" is the number of elements it can hold without 45 | /// being resized. Its "raw capacity" is the number of slots required to 46 | /// provide that capacity, accounting for maximum loading. The raw capacity 47 | /// is always zero or a power of two. 48 | #[inline] 49 | fn try_raw_capacity(&self, len: usize) -> Result { 50 | if len == 0 { 51 | Ok(0) 52 | } else { 53 | // 1. Account for loading: `raw_capacity >= len * 1.1`. 54 | // 2. Ensure it is a power of two. 55 | // 3. Ensure it is at least the minimum size. 56 | let mut raw_cap = len.checked_mul(11) 57 | .map(|l| l / 10) 58 | .and_then(|l| l.checked_next_power_of_two()) 59 | .ok_or(CollectionAllocErr::CapacityOverflow)?; 60 | 61 | raw_cap = max(MIN_NONZERO_RAW_CAPACITY, raw_cap); 62 | Ok(raw_cap) 63 | } 64 | } 65 | 66 | #[inline] 67 | fn raw_capacity(&self, len: usize) -> usize { 68 | self.try_raw_capacity(len).expect("raw_capacity overflow") 69 | } 70 | 71 | /// The capacity of the given raw capacity. 72 | #[inline] 73 | fn capacity(&self, raw_cap: usize) -> usize { 74 | // This doesn't have to be checked for overflow since allocation size 75 | // in bytes will overflow earlier than multiplication by 10. 76 | // 77 | // As per https://github.com/rust-lang/rust/pull/30991 this is updated 78 | // to be: (raw_cap * den + den - 1) / num 79 | (raw_cap * 10 + 10 - 1) / 11 80 | } 81 | } 82 | 83 | // The main performance trick in this hashmap is called Robin Hood Hashing. 84 | // It gains its excellent performance from one essential operation: 85 | // 86 | // If an insertion collides with an existing element, and that element's 87 | // "probe distance" (how far away the element is from its ideal location) 88 | // is higher than how far we've already probed, swap the elements. 89 | // 90 | // This massively lowers variance in probe distance, and allows us to get very 91 | // high load factors with good performance. The 90% load factor I use is rather 92 | // conservative. 93 | // 94 | // > Why a load factor of approximately 90%? 95 | // 96 | // In general, all the distances to initial buckets will converge on the mean. 97 | // At a load factor of α, the odds of finding the target bucket after k 98 | // probes is approximately 1-α^k. If we set this equal to 50% (since we converge 99 | // on the mean) and set k=8 (64-byte cache line / 8-byte hash), α=0.92. I round 100 | // this down to make the math easier on the CPU and avoid its FPU. 101 | // Since on average we start the probing in the middle of a cache line, this 102 | // strategy pulls in two cache lines of hashes on every lookup. I think that's 103 | // pretty good, but if you want to trade off some space, it could go down to one 104 | // cache line on average with an α of 0.84. 105 | // 106 | // > Wait, what? Where did you get 1-α^k from? 107 | // 108 | // On the first probe, your odds of a collision with an existing element is α. 109 | // The odds of doing this twice in a row is approximately α^2. For three times, 110 | // α^3, etc. Therefore, the odds of colliding k times is α^k. The odds of NOT 111 | // colliding after k tries is 1-α^k. 112 | // 113 | // The paper from 1986 cited below mentions an implementation which keeps track 114 | // of the distance-to-initial-bucket histogram. This approach is not suitable 115 | // for modern architectures because it requires maintaining an internal data 116 | // structure. This allows very good first guesses, but we are most concerned 117 | // with guessing entire cache lines, not individual indexes. Furthermore, array 118 | // accesses are no longer linear and in one direction, as we have now. There 119 | // is also memory and cache pressure that this would entail that would be very 120 | // difficult to properly see in a microbenchmark. 121 | // 122 | // ## Future Improvements (FIXME!) 123 | // 124 | // Allow the load factor to be changed dynamically and/or at initialization. 125 | // 126 | // Also, would it be possible for us to reuse storage when growing the 127 | // underlying table? This is exactly the use case for 'realloc', and may 128 | // be worth exploring. 129 | // 130 | // ## Future Optimizations (FIXME!) 131 | // 132 | // Another possible design choice that I made without any real reason is 133 | // parameterizing the raw table over keys and values. Technically, all we need 134 | // is the size and alignment of keys and values, and the code should be just as 135 | // efficient (well, we might need one for power-of-two size and one for not...). 136 | // This has the potential to reduce code bloat in rust executables, without 137 | // really losing anything except 4 words (key size, key alignment, val size, 138 | // val alignment) which can be passed in to every call of a `RawTable` function. 139 | // This would definitely be an avenue worth exploring if people start complaining 140 | // about the size of rust executables. 141 | // 142 | // Annotate exceedingly likely branches in `table::make_hash` 143 | // and `search_hashed` to reduce instruction cache pressure 144 | // and mispredictions once it becomes possible (blocked on issue #11092). 145 | // 146 | // Shrinking the table could simply reallocate in place after moving buckets 147 | // to the first half. 148 | // 149 | // The growth algorithm (fragment of the Proof of Correctness) 150 | // -------------------- 151 | // 152 | // The growth algorithm is basically a fast path of the naive reinsertion- 153 | // during-resize algorithm. Other paths should never be taken. 154 | // 155 | // Consider growing a robin hood hashtable of capacity n. Normally, we do this 156 | // by allocating a new table of capacity `2n`, and then individually reinsert 157 | // each element in the old table into the new one. This guarantees that the 158 | // new table is a valid robin hood hashtable with all the desired statistical 159 | // properties. Remark that the order we reinsert the elements in should not 160 | // matter. For simplicity and efficiency, we will consider only linear 161 | // reinsertions, which consist of reinserting all elements in the old table 162 | // into the new one by increasing order of index. However we will not be 163 | // starting our reinsertions from index 0 in general. If we start from index 164 | // i, for the purpose of reinsertion we will consider all elements with real 165 | // index j < i to have virtual index n + j. 166 | // 167 | // Our hash generation scheme consists of generating a 64-bit hash and 168 | // truncating the most significant bits. When moving to the new table, we 169 | // simply introduce a new bit to the front of the hash. Therefore, if an 170 | // elements has ideal index i in the old table, it can have one of two ideal 171 | // locations in the new table. If the new bit is 0, then the new ideal index 172 | // is i. If the new bit is 1, then the new ideal index is n + i. Intuitively, 173 | // we are producing two independent tables of size n, and for each element we 174 | // independently choose which table to insert it into with equal probability. 175 | // However the rather than wrapping around themselves on overflowing their 176 | // indexes, the first table overflows into the first, and the first into the 177 | // second. Visually, our new table will look something like: 178 | // 179 | // [yy_xxx_xxxx_xxx|xx_yyy_yyyy_yyy] 180 | // 181 | // Where x's are elements inserted into the first table, y's are elements 182 | // inserted into the second, and _'s are empty sections. We now define a few 183 | // key concepts that we will use later. Note that this is a very abstract 184 | // perspective of the table. A real resized table would be at least half 185 | // empty. 186 | // 187 | // Theorem: A linear robin hood reinsertion from the first ideal element 188 | // produces identical results to a linear naive reinsertion from the same 189 | // element. 190 | // 191 | // FIXME(Gankro, pczarn): review the proof and put it all in a separate README.md 192 | // 193 | // Adaptive early resizing 194 | // ---------------------- 195 | // To protect against degenerate performance scenarios (including DOS attacks), 196 | // the implementation includes an adaptive behavior that can resize the map 197 | // early (before its capacity is exceeded) when suspiciously long probe sequences 198 | // are encountered. 199 | // 200 | // With this algorithm in place it would be possible to turn a CPU attack into 201 | // a memory attack due to the aggressive resizing. To prevent that the 202 | // adaptive behavior only triggers when the map is at least half full. 203 | // This reduces the effectiveness of the algorithm but also makes it completely safe. 204 | // 205 | // The previous safety measure also prevents degenerate interactions with 206 | // really bad quality hash algorithms that can make normal inputs look like a 207 | // DOS attack. 208 | // 209 | const DISPLACEMENT_THRESHOLD: usize = 128; 210 | // 211 | // The threshold of 128 is chosen to minimize the chance of exceeding it. 212 | // In particular, we want that chance to be less than 10^-8 with a load of 90%. 213 | // For displacement, the smallest constant that fits our needs is 90, 214 | // so we round that up to 128. 215 | // 216 | // At a load factor of α, the odds of finding the target bucket after exactly n 217 | // unsuccessful probes[1] are 218 | // 219 | // Pr_α{displacement = n} = 220 | // (1 - α) / α * ∑_{k≥1} e^(-kα) * (kα)^(k+n) / (k + n)! * (1 - kα / (k + n + 1)) 221 | // 222 | // We use this formula to find the probability of triggering the adaptive behavior 223 | // 224 | // Pr_0.909{displacement > 128} = 1.601 * 10^-11 225 | // 226 | // 1. Alfredo Viola (2005). Distributional analysis of Robin Hood linear probing 227 | // hashing with buckets. 228 | 229 | /// A hash map implemented with linear probing and Robin Hood bucket stealing. 230 | /// 231 | /// By default, `HashMap` uses a hashing algorithm selected to provide 232 | /// resistance against HashDoS attacks. The algorithm is randomly seeded, and a 233 | /// reasonable best-effort is made to generate this seed from a high quality, 234 | /// secure source of randomness provided by the host without blocking the 235 | /// program. Because of this, the randomness of the seed depends on the output 236 | /// quality of the system's random number generator when the seed is created. 237 | /// In particular, seeds generated when the system's entropy pool is abnormally 238 | /// low such as during system boot may be of a lower quality. 239 | /// 240 | /// The default hashing algorithm is currently SipHash 1-3, though this is 241 | /// subject to change at any point in the future. While its performance is very 242 | /// competitive for medium sized keys, other hashing algorithms will outperform 243 | /// it for small keys such as integers as well as large keys such as long 244 | /// strings, though those algorithms will typically *not* protect against 245 | /// attacks such as HashDoS. 246 | /// 247 | /// The hashing algorithm can be replaced on a per-`HashMap` basis using the 248 | /// [`default`], [`with_hasher`], and [`with_capacity_and_hasher`] methods. Many 249 | /// alternative algorithms are available on crates.io, such as the [`fnv`] crate. 250 | /// 251 | /// It is required that the keys implement the [`Eq`] and [`Hash`] traits, although 252 | /// this can frequently be achieved by using `#[derive(PartialEq, Eq, Hash)]`. 253 | /// If you implement these yourself, it is important that the following 254 | /// property holds: 255 | /// 256 | /// ```text 257 | /// k1 == k2 -> hash(k1) == hash(k2) 258 | /// ``` 259 | /// 260 | /// In other words, if two keys are equal, their hashes must be equal. 261 | /// 262 | /// It is a logic error for a key to be modified in such a way that the key's 263 | /// hash, as determined by the [`Hash`] trait, or its equality, as determined by 264 | /// the [`Eq`] trait, changes while it is in the map. This is normally only 265 | /// possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code. 266 | /// 267 | /// Relevant papers/articles: 268 | /// 269 | /// 1. Pedro Celis. ["Robin Hood Hashing"](https://cs.uwaterloo.ca/research/tr/1986/CS-86-14.pdf) 270 | /// 2. Emmanuel Goossaert. ["Robin Hood 271 | /// hashing"](http://codecapsule.com/2013/11/11/robin-hood-hashing/) 272 | /// 3. Emmanuel Goossaert. ["Robin Hood hashing: backward shift 273 | /// deletion"](http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/) 274 | /// 275 | /// # Examples 276 | /// 277 | /// ``` 278 | /// use std::collections::HashMap; 279 | /// 280 | /// // type inference lets us omit an explicit type signature (which 281 | /// // would be `HashMap<&str, &str>` in this example). 282 | /// let mut book_reviews = HashMap::new(); 283 | /// 284 | /// // review some books. 285 | /// book_reviews.insert("Adventures of Huckleberry Finn", "My favorite book."); 286 | /// book_reviews.insert("Grimms' Fairy Tales", "Masterpiece."); 287 | /// book_reviews.insert("Pride and Prejudice", "Very enjoyable."); 288 | /// book_reviews.insert("The Adventures of Sherlock Holmes", "Eye lyked it alot."); 289 | /// 290 | /// // check for a specific one. 291 | /// if !book_reviews.contains_key("Les Misérables") { 292 | /// println!("We've got {} reviews, but Les Misérables ain't one.", 293 | /// book_reviews.len()); 294 | /// } 295 | /// 296 | /// // oops, this review has a lot of spelling mistakes, let's delete it. 297 | /// book_reviews.remove("The Adventures of Sherlock Holmes"); 298 | /// 299 | /// // look up the values associated with some keys. 300 | /// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"]; 301 | /// for book in &to_find { 302 | /// match book_reviews.get(book) { 303 | /// Some(review) => println!("{}: {}", book, review), 304 | /// None => println!("{} is unreviewed.", book) 305 | /// } 306 | /// } 307 | /// 308 | /// // iterate over everything. 309 | /// for (book, review) in &book_reviews { 310 | /// println!("{}: \"{}\"", book, review); 311 | /// } 312 | /// ``` 313 | /// 314 | /// `HashMap` also implements an [`Entry API`](#method.entry), which allows 315 | /// for more complex methods of getting, setting, updating and removing keys and 316 | /// their values: 317 | /// 318 | /// ``` 319 | /// use std::collections::HashMap; 320 | /// 321 | /// // type inference lets us omit an explicit type signature (which 322 | /// // would be `HashMap<&str, u8>` in this example). 323 | /// let mut player_stats = HashMap::new(); 324 | /// 325 | /// fn random_stat_buff() -> u8 { 326 | /// // could actually return some random value here - let's just return 327 | /// // some fixed value for now 328 | /// 42 329 | /// } 330 | /// 331 | /// // insert a key only if it doesn't already exist 332 | /// player_stats.entry("health").or_insert(100); 333 | /// 334 | /// // insert a key using a function that provides a new value only if it 335 | /// // doesn't already exist 336 | /// player_stats.entry("defence").or_insert_with(random_stat_buff); 337 | /// 338 | /// // update a key, guarding against the key possibly not being set 339 | /// let stat = player_stats.entry("attack").or_insert(100); 340 | /// *stat += random_stat_buff(); 341 | /// ``` 342 | /// 343 | /// The easiest way to use `HashMap` with a custom type as key is to derive [`Eq`] and [`Hash`]. 344 | /// We must also derive [`PartialEq`]. 345 | /// 346 | /// [`Eq`]: ../../std/cmp/trait.Eq.html 347 | /// [`Hash`]: ../../std/hash/trait.Hash.html 348 | /// [`PartialEq`]: ../../std/cmp/trait.PartialEq.html 349 | /// [`RefCell`]: ../../std/cell/struct.RefCell.html 350 | /// [`Cell`]: ../../std/cell/struct.Cell.html 351 | /// [`default`]: #method.default 352 | /// [`with_hasher`]: #method.with_hasher 353 | /// [`with_capacity_and_hasher`]: #method.with_capacity_and_hasher 354 | /// [`fnv`]: https://crates.io/crates/fnv 355 | /// 356 | /// ``` 357 | /// use std::collections::HashMap; 358 | /// 359 | /// #[derive(Hash, Eq, PartialEq, Debug)] 360 | /// struct Viking { 361 | /// name: String, 362 | /// country: String, 363 | /// } 364 | /// 365 | /// impl Viking { 366 | /// /// Create a new Viking. 367 | /// fn new(name: &str, country: &str) -> Viking { 368 | /// Viking { name: name.to_string(), country: country.to_string() } 369 | /// } 370 | /// } 371 | /// 372 | /// // Use a HashMap to store the vikings' health points. 373 | /// let mut vikings = HashMap::new(); 374 | /// 375 | /// vikings.insert(Viking::new("Einar", "Norway"), 25); 376 | /// vikings.insert(Viking::new("Olaf", "Denmark"), 24); 377 | /// vikings.insert(Viking::new("Harald", "Iceland"), 12); 378 | /// 379 | /// // Use derived implementation to print the status of the vikings. 380 | /// for (viking, health) in &vikings { 381 | /// println!("{:?} has {} hp", viking, health); 382 | /// } 383 | /// ``` 384 | /// 385 | /// A `HashMap` with fixed list of elements can be initialized from an array: 386 | /// 387 | /// ``` 388 | /// use std::collections::HashMap; 389 | /// 390 | /// fn main() { 391 | /// let timber_resources: HashMap<&str, i32> = 392 | /// [("Norway", 100), 393 | /// ("Denmark", 50), 394 | /// ("Iceland", 10)] 395 | /// .iter().cloned().collect(); 396 | /// // use the values stored in map 397 | /// } 398 | /// ``` 399 | 400 | #[derive(Clone)] 401 | pub struct HashMap { 402 | // All hashes are keyed on these values, to prevent hash collision attacks. 403 | hash_builder: S, 404 | 405 | table: RawTable, 406 | 407 | resize_policy: DefaultResizePolicy, 408 | } 409 | 410 | /// Search for a pre-hashed key. 411 | /// If you don't already know the hash, use search or search_mut instead 412 | #[inline] 413 | fn search_hashed(table: M, hash: SafeHash, is_match: F) -> InternalEntry 414 | where 415 | M: Deref>, 416 | F: FnMut(&K) -> bool, 417 | { 418 | // This is the only function where capacity can be zero. To avoid 419 | // undefined behavior when Bucket::new gets the raw bucket in this 420 | // case, immediately return the appropriate search result. 421 | if table.capacity() == 0 { 422 | return InternalEntry::TableIsEmpty; 423 | } 424 | 425 | search_hashed_nonempty(table, hash, is_match) 426 | } 427 | 428 | /// Search for a pre-hashed key when the hash map is known to be non-empty. 429 | #[inline] 430 | fn search_hashed_nonempty( 431 | table: M, 432 | hash: SafeHash, 433 | mut is_match: F, 434 | ) -> InternalEntry 435 | where 436 | M: Deref>, 437 | F: FnMut(&K) -> bool, 438 | { 439 | // Do not check the capacity as an extra branch could slow the lookup. 440 | 441 | let size = table.size(); 442 | let mut probe = Bucket::new(table, hash); 443 | let mut displacement = 0; 444 | 445 | loop { 446 | let full = match probe.peek() { 447 | Empty(bucket) => { 448 | // Found a hole! 449 | return InternalEntry::Vacant { 450 | hash, 451 | elem: NoElem(bucket, displacement), 452 | }; 453 | } 454 | Full(bucket) => bucket, 455 | }; 456 | 457 | let probe_displacement = full.displacement(); 458 | 459 | if probe_displacement < displacement { 460 | // Found a luckier bucket than me. 461 | // We can finish the search early if we hit any bucket 462 | // with a lower distance to initial bucket than we've probed. 463 | return InternalEntry::Vacant { 464 | hash, 465 | elem: NeqElem(full, probe_displacement), 466 | }; 467 | } 468 | 469 | // If the hash doesn't match, it can't be this one.. 470 | if hash == full.hash() { 471 | // If the key doesn't match, it can't be this one.. 472 | if is_match(full.read().0) { 473 | return InternalEntry::Occupied { elem: full }; 474 | } 475 | } 476 | displacement += 1; 477 | probe = full.next(); 478 | debug_assert!(displacement <= size); 479 | } 480 | } 481 | 482 | fn pop_internal(starting_bucket: FullBucketMut) -> (K, V, &mut RawTable) { 483 | let (empty, retkey, retval) = starting_bucket.take(); 484 | let mut gap = match empty.gap_peek() { 485 | Ok(b) => b, 486 | Err(b) => return (retkey, retval, b.into_table()), 487 | }; 488 | 489 | while gap.full().displacement() != 0 { 490 | gap = match gap.shift() { 491 | Ok(b) => b, 492 | Err(b) => { 493 | return (retkey, retval, b.into_table()); 494 | } 495 | }; 496 | } 497 | 498 | // Now we've done all our shifting. Return the value we grabbed earlier. 499 | (retkey, retval, gap.into_table()) 500 | } 501 | 502 | /// Perform robin hood bucket stealing at the given `bucket`. You must 503 | /// also pass that bucket's displacement so we don't have to recalculate it. 504 | /// 505 | /// `hash`, `key`, and `val` are the elements to "robin hood" into the hashtable. 506 | fn robin_hood<'a, K: 'a, V: 'a>( 507 | bucket: FullBucketMut<'a, K, V>, 508 | mut displacement: usize, 509 | mut hash: SafeHash, 510 | mut key: K, 511 | mut val: V, 512 | ) -> FullBucketMut<'a, K, V> { 513 | let size = bucket.table().size(); 514 | let raw_capacity = bucket.table().capacity(); 515 | // There can be at most `size - dib` buckets to displace, because 516 | // in the worst case, there are `size` elements and we already are 517 | // `displacement` buckets away from the initial one. 518 | let idx_end = (bucket.index() + size - bucket.displacement()) % raw_capacity; 519 | // Save the *starting point*. 520 | let mut bucket = bucket.stash(); 521 | 522 | loop { 523 | let (old_hash, old_key, old_val) = bucket.replace(hash, key, val); 524 | hash = old_hash; 525 | key = old_key; 526 | val = old_val; 527 | 528 | loop { 529 | displacement += 1; 530 | let probe = bucket.next(); 531 | debug_assert!(probe.index() != idx_end); 532 | 533 | let full_bucket = match probe.peek() { 534 | Empty(bucket) => { 535 | // Found a hole! 536 | let bucket = bucket.put(hash, key, val); 537 | // Now that it's stolen, just read the value's pointer 538 | // right out of the table! Go back to the *starting point*. 539 | // 540 | // This use of `into_table` is misleading. It turns the 541 | // bucket, which is a FullBucket on top of a 542 | // FullBucketMut, into just one FullBucketMut. The "table" 543 | // refers to the inner FullBucketMut in this context. 544 | return bucket.into_table(); 545 | } 546 | Full(bucket) => bucket, 547 | }; 548 | 549 | let probe_displacement = full_bucket.displacement(); 550 | 551 | bucket = full_bucket; 552 | 553 | // Robin hood! Steal the spot. 554 | if probe_displacement < displacement { 555 | displacement = probe_displacement; 556 | break; 557 | } 558 | } 559 | } 560 | } 561 | 562 | impl HashMap 563 | where 564 | K: Eq + Hash, 565 | S: BuildHasher, 566 | { 567 | fn make_hash(&self, x: &X) -> SafeHash 568 | where 569 | X: Hash, 570 | { 571 | table::make_hash(&self.hash_builder, x) 572 | } 573 | 574 | /// Search for a key, yielding the index if it's found in the hashtable. 575 | /// If you already have the hash for the key lying around, or if you need an 576 | /// InternalEntry, use search_hashed or search_hashed_nonempty. 577 | #[inline] 578 | fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> Option>> 579 | where 580 | K: Borrow, 581 | Q: Eq + Hash, 582 | { 583 | if self.is_empty() { 584 | return None; 585 | } 586 | 587 | let hash = self.make_hash(q); 588 | search_hashed_nonempty(&self.table, hash, |k| q.eq(k.borrow())).into_occupied_bucket() 589 | } 590 | 591 | #[inline] 592 | fn search_mut<'a, Q: ?Sized>( 593 | &'a mut self, 594 | q: &Q, 595 | ) -> Option>> 596 | where 597 | K: Borrow, 598 | Q: Eq + Hash, 599 | { 600 | if self.is_empty() { 601 | return None; 602 | } 603 | 604 | let hash = self.make_hash(q); 605 | search_hashed_nonempty(&mut self.table, hash, |k| q.eq(k.borrow())).into_occupied_bucket() 606 | } 607 | 608 | // The caller should ensure that invariants by Robin Hood Hashing hold 609 | // and that there's space in the underlying table. 610 | fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) { 611 | let mut buckets = Bucket::new(&mut self.table, hash); 612 | let start_index = buckets.index(); 613 | 614 | loop { 615 | // We don't need to compare hashes for value swap. 616 | // Not even DIBs for Robin Hood. 617 | buckets = match buckets.peek() { 618 | Empty(empty) => { 619 | empty.put(hash, k, v); 620 | return; 621 | } 622 | Full(b) => b.into_bucket(), 623 | }; 624 | buckets.next(); 625 | debug_assert!(buckets.index() != start_index); 626 | } 627 | } 628 | } 629 | 630 | impl HashMap { 631 | /// Creates an empty `HashMap`. 632 | /// 633 | /// The hash map is initially created with a capacity of 0, so it will not allocate until it 634 | /// is first inserted into. 635 | /// 636 | /// # Examples 637 | /// 638 | /// ``` 639 | /// use std::collections::HashMap; 640 | /// let mut map: HashMap<&str, i32> = HashMap::new(); 641 | /// ``` 642 | #[inline] 643 | pub fn new() -> HashMap { 644 | Default::default() 645 | } 646 | 647 | /// Creates an empty `HashMap` with the specified capacity. 648 | /// 649 | /// The hash map will be able to hold at least `capacity` elements without 650 | /// reallocating. If `capacity` is 0, the hash map will not allocate. 651 | /// 652 | /// # Examples 653 | /// 654 | /// ``` 655 | /// use std::collections::HashMap; 656 | /// let mut map: HashMap<&str, i32> = HashMap::with_capacity(10); 657 | /// ``` 658 | #[inline] 659 | pub fn with_capacity(capacity: usize) -> HashMap { 660 | HashMap::with_capacity_and_hasher(capacity, Default::default()) 661 | } 662 | } 663 | 664 | impl HashMap 665 | where 666 | K: Eq + Hash, 667 | S: BuildHasher, 668 | { 669 | /// Creates an empty `HashMap` which will use the given hash builder to hash 670 | /// keys. 671 | /// 672 | /// The created map has the default initial capacity. 673 | /// 674 | /// Warning: `hash_builder` is normally randomly generated, and 675 | /// is designed to allow HashMaps to be resistant to attacks that 676 | /// cause many collisions and very poor performance. Setting it 677 | /// manually using this function can expose a DoS attack vector. 678 | /// 679 | /// # Examples 680 | /// 681 | /// ``` 682 | /// use std::collections::HashMap; 683 | /// use std::collections::hash_map::RandomState; 684 | /// 685 | /// let s = RandomState::new(); 686 | /// let mut map = HashMap::with_hasher(s); 687 | /// map.insert(1, 2); 688 | /// ``` 689 | #[inline] 690 | pub fn with_hasher(hash_builder: S) -> HashMap { 691 | HashMap { 692 | hash_builder, 693 | resize_policy: DefaultResizePolicy::new(), 694 | table: RawTable::new(0), 695 | } 696 | } 697 | 698 | /// Creates an empty `HashMap` with the specified capacity, using `hash_builder` 699 | /// to hash the keys. 700 | /// 701 | /// The hash map will be able to hold at least `capacity` elements without 702 | /// reallocating. If `capacity` is 0, the hash map will not allocate. 703 | /// 704 | /// Warning: `hash_builder` is normally randomly generated, and 705 | /// is designed to allow HashMaps to be resistant to attacks that 706 | /// cause many collisions and very poor performance. Setting it 707 | /// manually using this function can expose a DoS attack vector. 708 | /// 709 | /// # Examples 710 | /// 711 | /// ``` 712 | /// use std::collections::HashMap; 713 | /// use std::collections::hash_map::RandomState; 714 | /// 715 | /// let s = RandomState::new(); 716 | /// let mut map = HashMap::with_capacity_and_hasher(10, s); 717 | /// map.insert(1, 2); 718 | /// ``` 719 | #[inline] 720 | pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap { 721 | let resize_policy = DefaultResizePolicy::new(); 722 | let raw_cap = resize_policy.raw_capacity(capacity); 723 | HashMap { 724 | hash_builder, 725 | resize_policy, 726 | table: RawTable::new(raw_cap), 727 | } 728 | } 729 | 730 | /// Returns a reference to the map's [`BuildHasher`]. 731 | /// 732 | /// [`BuildHasher`]: ../../std/hash/trait.BuildHasher.html 733 | /// 734 | /// # Examples 735 | /// 736 | /// ``` 737 | /// use std::collections::HashMap; 738 | /// use std::collections::hash_map::RandomState; 739 | /// 740 | /// let hasher = RandomState::new(); 741 | /// let map: HashMap = HashMap::with_hasher(hasher); 742 | /// let hasher: &RandomState = map.hasher(); 743 | /// ``` 744 | pub fn hasher(&self) -> &S { 745 | &self.hash_builder 746 | } 747 | 748 | /// Returns the number of elements the map can hold without reallocating. 749 | /// 750 | /// This number is a lower bound; the `HashMap` might be able to hold 751 | /// more, but is guaranteed to be able to hold at least this many. 752 | /// 753 | /// # Examples 754 | /// 755 | /// ``` 756 | /// use std::collections::HashMap; 757 | /// let map: HashMap = HashMap::with_capacity(100); 758 | /// assert!(map.capacity() >= 100); 759 | /// ``` 760 | #[inline] 761 | pub fn capacity(&self) -> usize { 762 | self.resize_policy.capacity(self.raw_capacity()) 763 | } 764 | 765 | /// Returns the hash map's raw capacity. 766 | #[inline] 767 | fn raw_capacity(&self) -> usize { 768 | self.table.capacity() 769 | } 770 | 771 | /// Reserves capacity for at least `additional` more elements to be inserted 772 | /// in the `HashMap`. The collection may reserve more space to avoid 773 | /// frequent reallocations. 774 | /// 775 | /// # Panics 776 | /// 777 | /// Panics if the new allocation size overflows [`usize`]. 778 | /// 779 | /// [`usize`]: ../../std/primitive.usize.html 780 | /// 781 | /// # Examples 782 | /// 783 | /// ``` 784 | /// use std::collections::HashMap; 785 | /// let mut map: HashMap<&str, i32> = HashMap::new(); 786 | /// map.reserve(10); 787 | /// ``` 788 | pub fn reserve(&mut self, additional: usize) { 789 | match self.reserve_internal(additional, Infallible) { 790 | Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"), 791 | Err(CollectionAllocErr::AllocErr) => unreachable!(), 792 | Ok(()) => { /* yay */ } 793 | } 794 | } 795 | 796 | /// Tries to reserve capacity for at least `additional` more elements to be inserted 797 | /// in the given `HashMap`. The collection may reserve more space to avoid 798 | /// frequent reallocations. 799 | /// 800 | /// # Errors 801 | /// 802 | /// If the capacity overflows, or the allocator reports a failure, then an error 803 | /// is returned. 804 | /// 805 | /// # Examples 806 | /// 807 | /// ``` 808 | /// #![feature(try_reserve)] 809 | /// use std::collections::HashMap; 810 | /// let mut map: HashMap<&str, isize> = HashMap::new(); 811 | /// map.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?"); 812 | /// ``` 813 | pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { 814 | self.reserve_internal(additional, Fallible) 815 | } 816 | 817 | fn reserve_internal(&mut self, additional: usize, fallibility: Fallibility) 818 | -> Result<(), CollectionAllocErr> { 819 | 820 | let remaining = self.capacity() - self.len(); // this can't overflow 821 | if remaining < additional { 822 | let min_cap = self.len() 823 | .checked_add(additional) 824 | .ok_or(CollectionAllocErr::CapacityOverflow)?; 825 | let raw_cap = self.resize_policy.try_raw_capacity(min_cap)?; 826 | self.try_resize(raw_cap, fallibility)?; 827 | } else if self.table.tag() && remaining <= self.len() { 828 | // Probe sequence is too long and table is half full, 829 | // resize early to reduce probing length. 830 | let new_capacity = self.table.capacity() * 2; 831 | self.try_resize(new_capacity, fallibility)?; 832 | } 833 | Ok(()) 834 | } 835 | 836 | /// Resizes the internal vectors to a new capacity. It's your 837 | /// responsibility to: 838 | /// 1) Ensure `new_raw_cap` is enough for all the elements, accounting 839 | /// for the load factor. 840 | /// 2) Ensure `new_raw_cap` is a power of two or zero. 841 | #[inline(never)] 842 | #[cold] 843 | fn try_resize( 844 | &mut self, 845 | new_raw_cap: usize, 846 | fallibility: Fallibility, 847 | ) -> Result<(), CollectionAllocErr> { 848 | assert!(self.table.size() <= new_raw_cap); 849 | assert!(new_raw_cap.is_power_of_two() || new_raw_cap == 0); 850 | 851 | let mut old_table = replace( 852 | &mut self.table, 853 | match fallibility { 854 | Infallible => RawTable::new(new_raw_cap), 855 | Fallible => RawTable::try_new(new_raw_cap)?, 856 | }, 857 | ); 858 | let old_size = old_table.size(); 859 | 860 | if old_table.size() == 0 { 861 | return Ok(()); 862 | } 863 | 864 | let mut bucket = Bucket::head_bucket(&mut old_table); 865 | 866 | // This is how the buckets might be laid out in memory: 867 | // ($ marks an initialized bucket) 868 | // ________________ 869 | // |$$$_$$$$$$_$$$$$| 870 | // 871 | // But we've skipped the entire initial cluster of buckets 872 | // and will continue iteration in this order: 873 | // ________________ 874 | // |$$$$$$_$$$$$ 875 | // ^ wrap around once end is reached 876 | // ________________ 877 | // $$$_____________| 878 | // ^ exit once table.size == 0 879 | loop { 880 | bucket = match bucket.peek() { 881 | Full(bucket) => { 882 | let h = bucket.hash(); 883 | let (b, k, v) = bucket.take(); 884 | self.insert_hashed_ordered(h, k, v); 885 | if b.table().size() == 0 { 886 | break; 887 | } 888 | b.into_bucket() 889 | } 890 | Empty(b) => b.into_bucket(), 891 | }; 892 | bucket.next(); 893 | } 894 | 895 | assert_eq!(self.table.size(), old_size); 896 | Ok(()) 897 | } 898 | 899 | /// Shrinks the capacity of the map as much as possible. It will drop 900 | /// down as much as possible while maintaining the internal rules 901 | /// and possibly leaving some space in accordance with the resize policy. 902 | /// 903 | /// # Examples 904 | /// 905 | /// ``` 906 | /// use std::collections::HashMap; 907 | /// 908 | /// let mut map: HashMap = HashMap::with_capacity(100); 909 | /// map.insert(1, 2); 910 | /// map.insert(3, 4); 911 | /// assert!(map.capacity() >= 100); 912 | /// map.shrink_to_fit(); 913 | /// assert!(map.capacity() >= 2); 914 | /// ``` 915 | pub fn shrink_to_fit(&mut self) { 916 | let new_raw_cap = self.resize_policy.raw_capacity(self.len()); 917 | if self.raw_capacity() != new_raw_cap { 918 | let old_table = replace(&mut self.table, RawTable::new(new_raw_cap)); 919 | let old_size = old_table.size(); 920 | 921 | // Shrink the table. Naive algorithm for resizing: 922 | for (h, k, v) in old_table.into_iter() { 923 | self.insert_hashed_nocheck(h, k, v); 924 | } 925 | 926 | debug_assert_eq!(self.table.size(), old_size); 927 | } 928 | } 929 | 930 | /// Shrinks the capacity of the map with a lower limit. It will drop 931 | /// down no lower than the supplied limit while maintaining the internal rules 932 | /// and possibly leaving some space in accordance with the resize policy. 933 | /// 934 | /// Panics if the current capacity is smaller than the supplied 935 | /// minimum capacity. 936 | /// 937 | /// # Examples 938 | /// 939 | /// ``` 940 | /// #![feature(shrink_to)] 941 | /// use std::collections::HashMap; 942 | /// 943 | /// let mut map: HashMap = HashMap::with_capacity(100); 944 | /// map.insert(1, 2); 945 | /// map.insert(3, 4); 946 | /// assert!(map.capacity() >= 100); 947 | /// map.shrink_to(10); 948 | /// assert!(map.capacity() >= 10); 949 | /// map.shrink_to(0); 950 | /// assert!(map.capacity() >= 2); 951 | /// ``` 952 | pub fn shrink_to(&mut self, min_capacity: usize) { 953 | assert!( 954 | self.capacity() >= min_capacity, 955 | "Tried to shrink to a larger capacity" 956 | ); 957 | 958 | let new_raw_cap = self.resize_policy 959 | .raw_capacity(max(self.len(), min_capacity)); 960 | if self.raw_capacity() != new_raw_cap { 961 | let old_table = replace(&mut self.table, RawTable::new(new_raw_cap)); 962 | let old_size = old_table.size(); 963 | 964 | // Shrink the table. Naive algorithm for resizing: 965 | for (h, k, v) in old_table.into_iter() { 966 | self.insert_hashed_nocheck(h, k, v); 967 | } 968 | 969 | debug_assert_eq!(self.table.size(), old_size); 970 | } 971 | } 972 | 973 | /// Insert a pre-hashed key-value pair, without first checking 974 | /// that there's enough room in the buckets. Returns a reference to the 975 | /// newly insert value. 976 | /// 977 | /// If the key already exists, the hashtable will be returned untouched 978 | /// and a reference to the existing element will be returned. 979 | fn insert_hashed_nocheck(&mut self, hash: SafeHash, k: K, v: V) -> Option { 980 | let entry = search_hashed(&mut self.table, hash, |key| *key == k).into_entry(k); 981 | match entry { 982 | Some(Occupied(mut elem)) => Some(elem.insert(v)), 983 | Some(Vacant(elem)) => { 984 | elem.insert(v); 985 | None 986 | } 987 | None => unreachable!(), 988 | } 989 | } 990 | 991 | /// An iterator visiting all keys in arbitrary order. 992 | /// The iterator element type is `&'a K`. 993 | /// 994 | /// # Examples 995 | /// 996 | /// ``` 997 | /// use std::collections::HashMap; 998 | /// 999 | /// let mut map = HashMap::new(); 1000 | /// map.insert("a", 1); 1001 | /// map.insert("b", 2); 1002 | /// map.insert("c", 3); 1003 | /// 1004 | /// for key in map.keys() { 1005 | /// println!("{}", key); 1006 | /// } 1007 | /// ``` 1008 | pub fn keys(&self) -> Keys { 1009 | Keys { inner: self.iter() } 1010 | } 1011 | 1012 | /// An iterator visiting all values in arbitrary order. 1013 | /// The iterator element type is `&'a V`. 1014 | /// 1015 | /// # Examples 1016 | /// 1017 | /// ``` 1018 | /// use std::collections::HashMap; 1019 | /// 1020 | /// let mut map = HashMap::new(); 1021 | /// map.insert("a", 1); 1022 | /// map.insert("b", 2); 1023 | /// map.insert("c", 3); 1024 | /// 1025 | /// for val in map.values() { 1026 | /// println!("{}", val); 1027 | /// } 1028 | /// ``` 1029 | pub fn values(&self) -> Values { 1030 | Values { inner: self.iter() } 1031 | } 1032 | 1033 | /// An iterator visiting all values mutably in arbitrary order. 1034 | /// The iterator element type is `&'a mut V`. 1035 | /// 1036 | /// # Examples 1037 | /// 1038 | /// ``` 1039 | /// use std::collections::HashMap; 1040 | /// 1041 | /// let mut map = HashMap::new(); 1042 | /// 1043 | /// map.insert("a", 1); 1044 | /// map.insert("b", 2); 1045 | /// map.insert("c", 3); 1046 | /// 1047 | /// for val in map.values_mut() { 1048 | /// *val = *val + 10; 1049 | /// } 1050 | /// 1051 | /// for val in map.values() { 1052 | /// println!("{}", val); 1053 | /// } 1054 | /// ``` 1055 | pub fn values_mut(&mut self) -> ValuesMut { 1056 | ValuesMut { 1057 | inner: self.iter_mut(), 1058 | } 1059 | } 1060 | 1061 | /// An iterator visiting all key-value pairs in arbitrary order. 1062 | /// The iterator element type is `(&'a K, &'a V)`. 1063 | /// 1064 | /// # Examples 1065 | /// 1066 | /// ``` 1067 | /// use std::collections::HashMap; 1068 | /// 1069 | /// let mut map = HashMap::new(); 1070 | /// map.insert("a", 1); 1071 | /// map.insert("b", 2); 1072 | /// map.insert("c", 3); 1073 | /// 1074 | /// for (key, val) in map.iter() { 1075 | /// println!("key: {} val: {}", key, val); 1076 | /// } 1077 | /// ``` 1078 | pub fn iter(&self) -> Iter { 1079 | Iter { 1080 | inner: self.table.iter(), 1081 | } 1082 | } 1083 | 1084 | /// An iterator visiting all key-value pairs in arbitrary order, 1085 | /// with mutable references to the values. 1086 | /// The iterator element type is `(&'a K, &'a mut V)`. 1087 | /// 1088 | /// # Examples 1089 | /// 1090 | /// ``` 1091 | /// use std::collections::HashMap; 1092 | /// 1093 | /// let mut map = HashMap::new(); 1094 | /// map.insert("a", 1); 1095 | /// map.insert("b", 2); 1096 | /// map.insert("c", 3); 1097 | /// 1098 | /// // Update all values 1099 | /// for (_, val) in map.iter_mut() { 1100 | /// *val *= 2; 1101 | /// } 1102 | /// 1103 | /// for (key, val) in &map { 1104 | /// println!("key: {} val: {}", key, val); 1105 | /// } 1106 | /// ``` 1107 | pub fn iter_mut(&mut self) -> IterMut { 1108 | IterMut { 1109 | inner: self.table.iter_mut(), 1110 | } 1111 | } 1112 | 1113 | /// Gets the given key's corresponding entry in the map for in-place manipulation. 1114 | /// 1115 | /// # Examples 1116 | /// 1117 | /// ``` 1118 | /// use std::collections::HashMap; 1119 | /// 1120 | /// let mut letters = HashMap::new(); 1121 | /// 1122 | /// for ch in "a short treatise on fungi".chars() { 1123 | /// let counter = letters.entry(ch).or_insert(0); 1124 | /// *counter += 1; 1125 | /// } 1126 | /// 1127 | /// assert_eq!(letters[&'s'], 2); 1128 | /// assert_eq!(letters[&'t'], 3); 1129 | /// assert_eq!(letters[&'u'], 1); 1130 | /// assert_eq!(letters.get(&'y'), None); 1131 | /// ``` 1132 | pub fn entry(&mut self, key: K) -> Entry { 1133 | // Gotta resize now. 1134 | self.reserve(1); 1135 | let hash = self.make_hash(&key); 1136 | search_hashed(&mut self.table, hash, |q| q.eq(&key)) 1137 | .into_entry(key) 1138 | .expect("unreachable") 1139 | } 1140 | 1141 | /// Returns the number of elements in the map. 1142 | /// 1143 | /// # Examples 1144 | /// 1145 | /// ``` 1146 | /// use std::collections::HashMap; 1147 | /// 1148 | /// let mut a = HashMap::new(); 1149 | /// assert_eq!(a.len(), 0); 1150 | /// a.insert(1, "a"); 1151 | /// assert_eq!(a.len(), 1); 1152 | /// ``` 1153 | pub fn len(&self) -> usize { 1154 | self.table.size() 1155 | } 1156 | 1157 | /// Returns true if the map contains no elements. 1158 | /// 1159 | /// # Examples 1160 | /// 1161 | /// ``` 1162 | /// use std::collections::HashMap; 1163 | /// 1164 | /// let mut a = HashMap::new(); 1165 | /// assert!(a.is_empty()); 1166 | /// a.insert(1, "a"); 1167 | /// assert!(!a.is_empty()); 1168 | /// ``` 1169 | #[inline] 1170 | pub fn is_empty(&self) -> bool { 1171 | self.len() == 0 1172 | } 1173 | 1174 | /// Clears the map, returning all key-value pairs as an iterator. Keeps the 1175 | /// allocated memory for reuse. 1176 | /// 1177 | /// # Examples 1178 | /// 1179 | /// ``` 1180 | /// use std::collections::HashMap; 1181 | /// 1182 | /// let mut a = HashMap::new(); 1183 | /// a.insert(1, "a"); 1184 | /// a.insert(2, "b"); 1185 | /// 1186 | /// for (k, v) in a.drain().take(1) { 1187 | /// assert!(k == 1 || k == 2); 1188 | /// assert!(v == "a" || v == "b"); 1189 | /// } 1190 | /// 1191 | /// assert!(a.is_empty()); 1192 | /// ``` 1193 | #[inline] 1194 | pub fn drain(&mut self) -> Drain { 1195 | Drain { 1196 | inner: self.table.drain(), 1197 | } 1198 | } 1199 | 1200 | /// Clears the map, removing all key-value pairs. Keeps the allocated memory 1201 | /// for reuse. 1202 | /// 1203 | /// # Examples 1204 | /// 1205 | /// ``` 1206 | /// use std::collections::HashMap; 1207 | /// 1208 | /// let mut a = HashMap::new(); 1209 | /// a.insert(1, "a"); 1210 | /// a.clear(); 1211 | /// assert!(a.is_empty()); 1212 | /// ``` 1213 | #[inline] 1214 | pub fn clear(&mut self) { 1215 | self.drain(); 1216 | } 1217 | 1218 | /// Returns a reference to the value corresponding to the key. 1219 | /// 1220 | /// The key may be any borrowed form of the map's key type, but 1221 | /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for 1222 | /// the key type. 1223 | /// 1224 | /// [`Eq`]: ../../std/cmp/trait.Eq.html 1225 | /// [`Hash`]: ../../std/hash/trait.Hash.html 1226 | /// 1227 | /// # Examples 1228 | /// 1229 | /// ``` 1230 | /// use std::collections::HashMap; 1231 | /// 1232 | /// let mut map = HashMap::new(); 1233 | /// map.insert(1, "a"); 1234 | /// assert_eq!(map.get(&1), Some(&"a")); 1235 | /// assert_eq!(map.get(&2), None); 1236 | /// ``` 1237 | #[inline] 1238 | pub fn get(&self, k: &Q) -> Option<&V> 1239 | where 1240 | K: Borrow, 1241 | Q: Hash + Eq, 1242 | { 1243 | self.search(k).map(|bucket| bucket.into_refs().1) 1244 | } 1245 | 1246 | /// Returns the key-value pair corresponding to the supplied key. 1247 | /// 1248 | /// The supplied key may be any borrowed form of the map's key type, but 1249 | /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for 1250 | /// the key type. 1251 | /// 1252 | /// [`Eq`]: ../../std/cmp/trait.Eq.html 1253 | /// [`Hash`]: ../../std/hash/trait.Hash.html 1254 | /// 1255 | /// # Examples 1256 | /// 1257 | /// ``` 1258 | /// #![feature(map_get_key_value)] 1259 | /// use std::collections::HashMap; 1260 | /// 1261 | /// let mut map = HashMap::new(); 1262 | /// map.insert(1, "a"); 1263 | /// assert_eq!(map.get_key_value(&1), Some((&1, &"a"))); 1264 | /// assert_eq!(map.get_key_value(&2), None); 1265 | /// ``` 1266 | pub fn get_key_value(&self, k: &Q) -> Option<(&K, &V)> 1267 | where 1268 | K: Borrow, 1269 | Q: Hash + Eq, 1270 | { 1271 | self.search(k).map(|bucket| bucket.into_refs()) 1272 | } 1273 | 1274 | /// Returns true if the map contains a value for the specified key. 1275 | /// 1276 | /// The key may be any borrowed form of the map's key type, but 1277 | /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for 1278 | /// the key type. 1279 | /// 1280 | /// [`Eq`]: ../../std/cmp/trait.Eq.html 1281 | /// [`Hash`]: ../../std/hash/trait.Hash.html 1282 | /// 1283 | /// # Examples 1284 | /// 1285 | /// ``` 1286 | /// use std::collections::HashMap; 1287 | /// 1288 | /// let mut map = HashMap::new(); 1289 | /// map.insert(1, "a"); 1290 | /// assert_eq!(map.contains_key(&1), true); 1291 | /// assert_eq!(map.contains_key(&2), false); 1292 | /// ``` 1293 | pub fn contains_key(&self, k: &Q) -> bool 1294 | where 1295 | K: Borrow, 1296 | Q: Hash + Eq, 1297 | { 1298 | self.search(k).is_some() 1299 | } 1300 | 1301 | /// Returns a mutable reference to the value corresponding to the key. 1302 | /// 1303 | /// The key may be any borrowed form of the map's key type, but 1304 | /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for 1305 | /// the key type. 1306 | /// 1307 | /// [`Eq`]: ../../std/cmp/trait.Eq.html 1308 | /// [`Hash`]: ../../std/hash/trait.Hash.html 1309 | /// 1310 | /// # Examples 1311 | /// 1312 | /// ``` 1313 | /// use std::collections::HashMap; 1314 | /// 1315 | /// let mut map = HashMap::new(); 1316 | /// map.insert(1, "a"); 1317 | /// if let Some(x) = map.get_mut(&1) { 1318 | /// *x = "b"; 1319 | /// } 1320 | /// assert_eq!(map[&1], "b"); 1321 | /// ``` 1322 | pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> 1323 | where 1324 | K: Borrow, 1325 | Q: Hash + Eq, 1326 | { 1327 | self.search_mut(k).map(|bucket| bucket.into_mut_refs().1) 1328 | } 1329 | 1330 | /// Inserts a key-value pair into the map. 1331 | /// 1332 | /// If the map did not have this key present, [`None`] is returned. 1333 | /// 1334 | /// If the map did have this key present, the value is updated, and the old 1335 | /// value is returned. The key is not updated, though; this matters for 1336 | /// types that can be `==` without being identical. See the [module-level 1337 | /// documentation] for more. 1338 | /// 1339 | /// [`None`]: ../../std/option/enum.Option.html#variant.None 1340 | /// [module-level documentation]: index.html#insert-and-complex-keys 1341 | /// 1342 | /// # Examples 1343 | /// 1344 | /// ``` 1345 | /// use std::collections::HashMap; 1346 | /// 1347 | /// let mut map = HashMap::new(); 1348 | /// assert_eq!(map.insert(37, "a"), None); 1349 | /// assert_eq!(map.is_empty(), false); 1350 | /// 1351 | /// map.insert(37, "b"); 1352 | /// assert_eq!(map.insert(37, "c"), Some("b")); 1353 | /// assert_eq!(map[&37], "c"); 1354 | /// ``` 1355 | pub fn insert(&mut self, k: K, v: V) -> Option { 1356 | let hash = self.make_hash(&k); 1357 | self.reserve(1); 1358 | self.insert_hashed_nocheck(hash, k, v) 1359 | } 1360 | 1361 | /// Removes a key from the map, returning the value at the key if the key 1362 | /// was previously in the map. 1363 | /// 1364 | /// The key may be any borrowed form of the map's key type, but 1365 | /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for 1366 | /// the key type. 1367 | /// 1368 | /// [`Eq`]: ../../std/cmp/trait.Eq.html 1369 | /// [`Hash`]: ../../std/hash/trait.Hash.html 1370 | /// 1371 | /// # Examples 1372 | /// 1373 | /// ``` 1374 | /// use std::collections::HashMap; 1375 | /// 1376 | /// let mut map = HashMap::new(); 1377 | /// map.insert(1, "a"); 1378 | /// assert_eq!(map.remove(&1), Some("a")); 1379 | /// assert_eq!(map.remove(&1), None); 1380 | /// ``` 1381 | pub fn remove(&mut self, k: &Q) -> Option 1382 | where 1383 | K: Borrow, 1384 | Q: Hash + Eq, 1385 | { 1386 | self.search_mut(k).map(|bucket| pop_internal(bucket).1) 1387 | } 1388 | 1389 | /// Removes a key from the map, returning the stored key and value if the 1390 | /// key was previously in the map. 1391 | /// 1392 | /// The key may be any borrowed form of the map's key type, but 1393 | /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for 1394 | /// the key type. 1395 | /// 1396 | /// [`Eq`]: ../../std/cmp/trait.Eq.html 1397 | /// [`Hash`]: ../../std/hash/trait.Hash.html 1398 | /// 1399 | /// # Examples 1400 | /// 1401 | /// ``` 1402 | /// use std::collections::HashMap; 1403 | /// 1404 | /// # fn main() { 1405 | /// let mut map = HashMap::new(); 1406 | /// map.insert(1, "a"); 1407 | /// assert_eq!(map.remove_entry(&1), Some((1, "a"))); 1408 | /// assert_eq!(map.remove(&1), None); 1409 | /// # } 1410 | /// ``` 1411 | pub fn remove_entry(&mut self, k: &Q) -> Option<(K, V)> 1412 | where 1413 | K: Borrow, 1414 | Q: Hash + Eq, 1415 | { 1416 | self.search_mut(k).map(|bucket| { 1417 | let (k, v, _) = pop_internal(bucket); 1418 | (k, v) 1419 | }) 1420 | } 1421 | 1422 | /// Retains only the elements specified by the predicate. 1423 | /// 1424 | /// In other words, remove all pairs `(k, v)` such that `f(&k,&mut v)` returns `false`. 1425 | /// 1426 | /// # Examples 1427 | /// 1428 | /// ``` 1429 | /// use std::collections::HashMap; 1430 | /// 1431 | /// let mut map: HashMap = (0..8).map(|x|(x, x*10)).collect(); 1432 | /// map.retain(|&k, _| k % 2 == 0); 1433 | /// assert_eq!(map.len(), 4); 1434 | /// ``` 1435 | pub fn retain(&mut self, mut f: F) 1436 | where 1437 | F: FnMut(&K, &mut V) -> bool, 1438 | { 1439 | if self.table.size() == 0 { 1440 | return; 1441 | } 1442 | let mut elems_left = self.table.size(); 1443 | let mut bucket = Bucket::head_bucket(&mut self.table); 1444 | bucket.prev(); 1445 | let start_index = bucket.index(); 1446 | while elems_left != 0 { 1447 | bucket = match bucket.peek() { 1448 | Full(mut full) => { 1449 | elems_left -= 1; 1450 | let should_remove = { 1451 | let (k, v) = full.read_mut(); 1452 | !f(k, v) 1453 | }; 1454 | if should_remove { 1455 | let prev_raw = full.raw(); 1456 | let (_, _, t) = pop_internal(full); 1457 | Bucket::new_from(prev_raw, t) 1458 | } else { 1459 | full.into_bucket() 1460 | } 1461 | } 1462 | Empty(b) => b.into_bucket(), 1463 | }; 1464 | bucket.prev(); // reverse iteration 1465 | debug_assert!(elems_left == 0 || bucket.index() != start_index); 1466 | } 1467 | } 1468 | } 1469 | 1470 | impl PartialEq for HashMap 1471 | where 1472 | K: Eq + Hash, 1473 | V: PartialEq, 1474 | S: BuildHasher, 1475 | { 1476 | fn eq(&self, other: &HashMap) -> bool { 1477 | if self.len() != other.len() { 1478 | return false; 1479 | } 1480 | 1481 | self.iter() 1482 | .all(|(key, value)| other.get(key).map_or(false, |v| *value == *v)) 1483 | } 1484 | } 1485 | 1486 | impl Eq for HashMap 1487 | where 1488 | K: Eq + Hash, 1489 | V: Eq, 1490 | S: BuildHasher, 1491 | { 1492 | } 1493 | 1494 | impl Debug for HashMap 1495 | where 1496 | K: Eq + Hash + Debug, 1497 | V: Debug, 1498 | S: BuildHasher, 1499 | { 1500 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1501 | f.debug_map().entries(self.iter()).finish() 1502 | } 1503 | } 1504 | 1505 | impl Default for HashMap 1506 | where 1507 | K: Eq + Hash, 1508 | S: BuildHasher + Default, 1509 | { 1510 | /// Creates an empty `HashMap`, with the `Default` value for the hasher. 1511 | fn default() -> HashMap { 1512 | HashMap::with_hasher(Default::default()) 1513 | } 1514 | } 1515 | 1516 | impl<'a, K, Q: ?Sized, V, S> Index<&'a Q> for HashMap 1517 | where 1518 | K: Eq + Hash + Borrow, 1519 | Q: Eq + Hash, 1520 | S: BuildHasher, 1521 | { 1522 | type Output = V; 1523 | 1524 | /// Returns a reference to the value corresponding to the supplied key. 1525 | /// 1526 | /// # Panics 1527 | /// 1528 | /// Panics if the key is not present in the `HashMap`. 1529 | #[inline] 1530 | fn index(&self, key: &Q) -> &V { 1531 | self.get(key).expect("no entry found for key") 1532 | } 1533 | } 1534 | 1535 | /// An iterator over the entries of a `HashMap`. 1536 | /// 1537 | /// This `struct` is created by the [`iter`] method on [`HashMap`]. See its 1538 | /// documentation for more. 1539 | /// 1540 | /// [`iter`]: struct.HashMap.html#method.iter 1541 | /// [`HashMap`]: struct.HashMap.html 1542 | pub struct Iter<'a, K: 'a, V: 'a> { 1543 | inner: table::Iter<'a, K, V>, 1544 | } 1545 | 1546 | // FIXME(#26925) Remove in favor of `#[derive(Clone)]` 1547 | impl<'a, K, V> Clone for Iter<'a, K, V> { 1548 | fn clone(&self) -> Iter<'a, K, V> { 1549 | Iter { 1550 | inner: self.inner.clone(), 1551 | } 1552 | } 1553 | } 1554 | 1555 | impl<'a, K: Debug, V: Debug> fmt::Debug for Iter<'a, K, V> { 1556 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1557 | f.debug_list().entries(self.clone()).finish() 1558 | } 1559 | } 1560 | 1561 | /// A mutable iterator over the entries of a `HashMap`. 1562 | /// 1563 | /// This `struct` is created by the [`iter_mut`] method on [`HashMap`]. See its 1564 | /// documentation for more. 1565 | /// 1566 | /// [`iter_mut`]: struct.HashMap.html#method.iter_mut 1567 | /// [`HashMap`]: struct.HashMap.html 1568 | pub struct IterMut<'a, K: 'a, V: 'a> { 1569 | inner: table::IterMut<'a, K, V>, 1570 | } 1571 | 1572 | /// An owning iterator over the entries of a `HashMap`. 1573 | /// 1574 | /// This `struct` is created by the [`into_iter`] method on [`HashMap`][`HashMap`] 1575 | /// (provided by the `IntoIterator` trait). See its documentation for more. 1576 | /// 1577 | /// [`into_iter`]: struct.HashMap.html#method.into_iter 1578 | /// [`HashMap`]: struct.HashMap.html 1579 | pub struct IntoIter { 1580 | pub(super) inner: table::IntoIter, 1581 | } 1582 | 1583 | /// An iterator over the keys of a `HashMap`. 1584 | /// 1585 | /// This `struct` is created by the [`keys`] method on [`HashMap`]. See its 1586 | /// documentation for more. 1587 | /// 1588 | /// [`keys`]: struct.HashMap.html#method.keys 1589 | /// [`HashMap`]: struct.HashMap.html 1590 | pub struct Keys<'a, K: 'a, V: 'a> { 1591 | inner: Iter<'a, K, V>, 1592 | } 1593 | 1594 | // FIXME(#26925) Remove in favor of `#[derive(Clone)]` 1595 | impl<'a, K, V> Clone for Keys<'a, K, V> { 1596 | fn clone(&self) -> Keys<'a, K, V> { 1597 | Keys { 1598 | inner: self.inner.clone(), 1599 | } 1600 | } 1601 | } 1602 | 1603 | impl<'a, K: Debug, V> fmt::Debug for Keys<'a, K, V> { 1604 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1605 | f.debug_list().entries(self.clone()).finish() 1606 | } 1607 | } 1608 | 1609 | /// An iterator over the values of a `HashMap`. 1610 | /// 1611 | /// This `struct` is created by the [`values`] method on [`HashMap`]. See its 1612 | /// documentation for more. 1613 | /// 1614 | /// [`values`]: struct.HashMap.html#method.values 1615 | /// [`HashMap`]: struct.HashMap.html 1616 | pub struct Values<'a, K: 'a, V: 'a> { 1617 | inner: Iter<'a, K, V>, 1618 | } 1619 | 1620 | // FIXME(#26925) Remove in favor of `#[derive(Clone)]` 1621 | impl<'a, K, V> Clone for Values<'a, K, V> { 1622 | fn clone(&self) -> Values<'a, K, V> { 1623 | Values { 1624 | inner: self.inner.clone(), 1625 | } 1626 | } 1627 | } 1628 | 1629 | impl<'a, K, V: Debug> fmt::Debug for Values<'a, K, V> { 1630 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1631 | f.debug_list().entries(self.clone()).finish() 1632 | } 1633 | } 1634 | 1635 | /// A draining iterator over the entries of a `HashMap`. 1636 | /// 1637 | /// This `struct` is created by the [`drain`] method on [`HashMap`]. See its 1638 | /// documentation for more. 1639 | /// 1640 | /// [`drain`]: struct.HashMap.html#method.drain 1641 | /// [`HashMap`]: struct.HashMap.html 1642 | pub struct Drain<'a, K: 'a, V: 'a> { 1643 | pub(super) inner: table::Drain<'a, K, V>, 1644 | } 1645 | 1646 | /// A mutable iterator over the values of a `HashMap`. 1647 | /// 1648 | /// This `struct` is created by the [`values_mut`] method on [`HashMap`]. See its 1649 | /// documentation for more. 1650 | /// 1651 | /// [`values_mut`]: struct.HashMap.html#method.values_mut 1652 | /// [`HashMap`]: struct.HashMap.html 1653 | pub struct ValuesMut<'a, K: 'a, V: 'a> { 1654 | inner: IterMut<'a, K, V>, 1655 | } 1656 | 1657 | enum InternalEntry { 1658 | Occupied { 1659 | elem: FullBucket, 1660 | }, 1661 | Vacant { 1662 | hash: SafeHash, 1663 | elem: VacantEntryState, 1664 | }, 1665 | TableIsEmpty, 1666 | } 1667 | 1668 | impl InternalEntry { 1669 | #[inline] 1670 | fn into_occupied_bucket(self) -> Option> { 1671 | match self { 1672 | InternalEntry::Occupied { elem } => Some(elem), 1673 | _ => None, 1674 | } 1675 | } 1676 | } 1677 | 1678 | impl<'a, K, V> InternalEntry> { 1679 | #[inline] 1680 | fn into_entry(self, key: K) -> Option> { 1681 | match self { 1682 | InternalEntry::Occupied { elem } => Some(Occupied(OccupiedEntry { 1683 | key: Some(key), 1684 | elem, 1685 | })), 1686 | InternalEntry::Vacant { hash, elem } => Some(Vacant(VacantEntry { hash, key, elem })), 1687 | InternalEntry::TableIsEmpty => None, 1688 | } 1689 | } 1690 | } 1691 | 1692 | /// A view into a single entry in a map, which may either be vacant or occupied. 1693 | /// 1694 | /// This `enum` is constructed from the [`entry`] method on [`HashMap`]. 1695 | /// 1696 | /// [`HashMap`]: struct.HashMap.html 1697 | /// [`entry`]: struct.HashMap.html#method.entry 1698 | pub enum Entry<'a, K: 'a, V: 'a> { 1699 | /// An occupied entry. 1700 | Occupied(OccupiedEntry<'a, K, V>), 1701 | 1702 | /// A vacant entry. 1703 | Vacant(VacantEntry<'a, K, V>), 1704 | } 1705 | 1706 | impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for Entry<'a, K, V> { 1707 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1708 | match *self { 1709 | Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(), 1710 | Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(), 1711 | } 1712 | } 1713 | } 1714 | 1715 | /// A view into an occupied entry in a `HashMap`. 1716 | /// It is part of the [`Entry`] enum. 1717 | /// 1718 | /// [`Entry`]: enum.Entry.html 1719 | pub struct OccupiedEntry<'a, K: 'a, V: 'a> { 1720 | key: Option, 1721 | elem: FullBucket>, 1722 | } 1723 | 1724 | impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for OccupiedEntry<'a, K, V> { 1725 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1726 | f.debug_struct("OccupiedEntry") 1727 | .field("key", self.key()) 1728 | .field("value", self.get()) 1729 | .finish() 1730 | } 1731 | } 1732 | 1733 | /// A view into a vacant entry in a `HashMap`. 1734 | /// It is part of the [`Entry`] enum. 1735 | /// 1736 | /// [`Entry`]: enum.Entry.html 1737 | pub struct VacantEntry<'a, K: 'a, V: 'a> { 1738 | hash: SafeHash, 1739 | key: K, 1740 | elem: VacantEntryState>, 1741 | } 1742 | 1743 | impl<'a, K: 'a + Debug, V: 'a> Debug for VacantEntry<'a, K, V> { 1744 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1745 | f.debug_tuple("VacantEntry").field(self.key()).finish() 1746 | } 1747 | } 1748 | 1749 | /// Possible states of a VacantEntry. 1750 | enum VacantEntryState { 1751 | /// The index is occupied, but the key to insert has precedence, 1752 | /// and will kick the current one out on insertion. 1753 | NeqElem(FullBucket, usize), 1754 | /// The index is genuinely vacant. 1755 | NoElem(EmptyBucket, usize), 1756 | } 1757 | 1758 | impl<'a, K, V, S> IntoIterator for &'a HashMap 1759 | where 1760 | K: Eq + Hash, 1761 | S: BuildHasher, 1762 | { 1763 | type Item = (&'a K, &'a V); 1764 | type IntoIter = Iter<'a, K, V>; 1765 | 1766 | fn into_iter(self) -> Iter<'a, K, V> { 1767 | self.iter() 1768 | } 1769 | } 1770 | 1771 | impl<'a, K, V, S> IntoIterator for &'a mut HashMap 1772 | where 1773 | K: Eq + Hash, 1774 | S: BuildHasher, 1775 | { 1776 | type Item = (&'a K, &'a mut V); 1777 | type IntoIter = IterMut<'a, K, V>; 1778 | 1779 | fn into_iter(self) -> IterMut<'a, K, V> { 1780 | self.iter_mut() 1781 | } 1782 | } 1783 | 1784 | impl IntoIterator for HashMap 1785 | where 1786 | K: Eq + Hash, 1787 | S: BuildHasher, 1788 | { 1789 | type Item = (K, V); 1790 | type IntoIter = IntoIter; 1791 | 1792 | /// Creates a consuming iterator, that is, one that moves each key-value 1793 | /// pair out of the map in arbitrary order. The map cannot be used after 1794 | /// calling this. 1795 | /// 1796 | /// # Examples 1797 | /// 1798 | /// ``` 1799 | /// use std::collections::HashMap; 1800 | /// 1801 | /// let mut map = HashMap::new(); 1802 | /// map.insert("a", 1); 1803 | /// map.insert("b", 2); 1804 | /// map.insert("c", 3); 1805 | /// 1806 | /// // Not possible with .iter() 1807 | /// let vec: Vec<(&str, i32)> = map.into_iter().collect(); 1808 | /// ``` 1809 | fn into_iter(self) -> IntoIter { 1810 | IntoIter { 1811 | inner: self.table.into_iter(), 1812 | } 1813 | } 1814 | } 1815 | 1816 | impl<'a, K, V> Iterator for Iter<'a, K, V> { 1817 | type Item = (&'a K, &'a V); 1818 | 1819 | #[inline] 1820 | fn next(&mut self) -> Option<(&'a K, &'a V)> { 1821 | self.inner.next() 1822 | } 1823 | #[inline] 1824 | fn size_hint(&self) -> (usize, Option) { 1825 | self.inner.size_hint() 1826 | } 1827 | } 1828 | impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> { 1829 | #[inline] 1830 | fn len(&self) -> usize { 1831 | self.inner.len() 1832 | } 1833 | } 1834 | 1835 | impl<'a, K, V> FusedIterator for Iter<'a, K, V> {} 1836 | 1837 | impl<'a, K, V> Iterator for IterMut<'a, K, V> { 1838 | type Item = (&'a K, &'a mut V); 1839 | 1840 | #[inline] 1841 | fn next(&mut self) -> Option<(&'a K, &'a mut V)> { 1842 | self.inner.next() 1843 | } 1844 | #[inline] 1845 | fn size_hint(&self) -> (usize, Option) { 1846 | self.inner.size_hint() 1847 | } 1848 | } 1849 | impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> { 1850 | #[inline] 1851 | fn len(&self) -> usize { 1852 | self.inner.len() 1853 | } 1854 | } 1855 | impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {} 1856 | 1857 | impl<'a, K, V> fmt::Debug for IterMut<'a, K, V> 1858 | where 1859 | K: fmt::Debug, 1860 | V: fmt::Debug, 1861 | { 1862 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1863 | f.debug_list().entries(self.inner.iter()).finish() 1864 | } 1865 | } 1866 | 1867 | impl Iterator for IntoIter { 1868 | type Item = (K, V); 1869 | 1870 | #[inline] 1871 | fn next(&mut self) -> Option<(K, V)> { 1872 | self.inner.next().map(|(_, k, v)| (k, v)) 1873 | } 1874 | #[inline] 1875 | fn size_hint(&self) -> (usize, Option) { 1876 | self.inner.size_hint() 1877 | } 1878 | } 1879 | impl ExactSizeIterator for IntoIter { 1880 | #[inline] 1881 | fn len(&self) -> usize { 1882 | self.inner.len() 1883 | } 1884 | } 1885 | impl FusedIterator for IntoIter {} 1886 | 1887 | impl fmt::Debug for IntoIter { 1888 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1889 | f.debug_list().entries(self.inner.iter()).finish() 1890 | } 1891 | } 1892 | 1893 | impl<'a, K, V> Iterator for Keys<'a, K, V> { 1894 | type Item = &'a K; 1895 | 1896 | #[inline] 1897 | fn next(&mut self) -> Option<(&'a K)> { 1898 | self.inner.next().map(|(k, _)| k) 1899 | } 1900 | #[inline] 1901 | fn size_hint(&self) -> (usize, Option) { 1902 | self.inner.size_hint() 1903 | } 1904 | } 1905 | impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> { 1906 | #[inline] 1907 | fn len(&self) -> usize { 1908 | self.inner.len() 1909 | } 1910 | } 1911 | impl<'a, K, V> FusedIterator for Keys<'a, K, V> {} 1912 | 1913 | impl<'a, K, V> Iterator for Values<'a, K, V> { 1914 | type Item = &'a V; 1915 | 1916 | #[inline] 1917 | fn next(&mut self) -> Option<(&'a V)> { 1918 | self.inner.next().map(|(_, v)| v) 1919 | } 1920 | #[inline] 1921 | fn size_hint(&self) -> (usize, Option) { 1922 | self.inner.size_hint() 1923 | } 1924 | } 1925 | impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> { 1926 | #[inline] 1927 | fn len(&self) -> usize { 1928 | self.inner.len() 1929 | } 1930 | } 1931 | impl<'a, K, V> FusedIterator for Values<'a, K, V> {} 1932 | 1933 | impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { 1934 | type Item = &'a mut V; 1935 | 1936 | #[inline] 1937 | fn next(&mut self) -> Option<(&'a mut V)> { 1938 | self.inner.next().map(|(_, v)| v) 1939 | } 1940 | #[inline] 1941 | fn size_hint(&self) -> (usize, Option) { 1942 | self.inner.size_hint() 1943 | } 1944 | } 1945 | impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> { 1946 | #[inline] 1947 | fn len(&self) -> usize { 1948 | self.inner.len() 1949 | } 1950 | } 1951 | impl<'a, K, V> FusedIterator for ValuesMut<'a, K, V> {} 1952 | 1953 | impl<'a, K, V> fmt::Debug for ValuesMut<'a, K, V> 1954 | where 1955 | K: fmt::Debug, 1956 | V: fmt::Debug, 1957 | { 1958 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1959 | f.debug_list().entries(self.inner.inner.iter()).finish() 1960 | } 1961 | } 1962 | 1963 | impl<'a, K, V> Iterator for Drain<'a, K, V> { 1964 | type Item = (K, V); 1965 | 1966 | #[inline] 1967 | fn next(&mut self) -> Option<(K, V)> { 1968 | self.inner.next().map(|(_, k, v)| (k, v)) 1969 | } 1970 | #[inline] 1971 | fn size_hint(&self) -> (usize, Option) { 1972 | self.inner.size_hint() 1973 | } 1974 | } 1975 | impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> { 1976 | #[inline] 1977 | fn len(&self) -> usize { 1978 | self.inner.len() 1979 | } 1980 | } 1981 | impl<'a, K, V> FusedIterator for Drain<'a, K, V> {} 1982 | 1983 | impl<'a, K, V> fmt::Debug for Drain<'a, K, V> 1984 | where 1985 | K: fmt::Debug, 1986 | V: fmt::Debug, 1987 | { 1988 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1989 | f.debug_list().entries(self.inner.iter()).finish() 1990 | } 1991 | } 1992 | 1993 | impl<'a, K, V> Entry<'a, K, V> { 1994 | /// Ensures a value is in the entry by inserting the default if empty, and returns 1995 | /// a mutable reference to the value in the entry. 1996 | /// 1997 | /// # Examples 1998 | /// 1999 | /// ``` 2000 | /// use std::collections::HashMap; 2001 | /// 2002 | /// let mut map: HashMap<&str, u32> = HashMap::new(); 2003 | /// map.entry("poneyland").or_insert(12); 2004 | /// 2005 | /// assert_eq!(map["poneyland"], 12); 2006 | /// 2007 | /// *map.entry("poneyland").or_insert(12) += 10; 2008 | /// assert_eq!(map["poneyland"], 22); 2009 | /// ``` 2010 | pub fn or_insert(self, default: V) -> &'a mut V { 2011 | match self { 2012 | Occupied(entry) => entry.into_mut(), 2013 | Vacant(entry) => entry.insert(default), 2014 | } 2015 | } 2016 | 2017 | /// Ensures a value is in the entry by inserting the result of the default function if empty, 2018 | /// and returns a mutable reference to the value in the entry. 2019 | /// 2020 | /// # Examples 2021 | /// 2022 | /// ``` 2023 | /// use std::collections::HashMap; 2024 | /// 2025 | /// let mut map: HashMap<&str, String> = HashMap::new(); 2026 | /// let s = "hoho".to_string(); 2027 | /// 2028 | /// map.entry("poneyland").or_insert_with(|| s); 2029 | /// 2030 | /// assert_eq!(map["poneyland"], "hoho".to_string()); 2031 | /// ``` 2032 | pub fn or_insert_with V>(self, default: F) -> &'a mut V { 2033 | match self { 2034 | Occupied(entry) => entry.into_mut(), 2035 | Vacant(entry) => entry.insert(default()), 2036 | } 2037 | } 2038 | 2039 | /// Returns a reference to this entry's key. 2040 | /// 2041 | /// # Examples 2042 | /// 2043 | /// ``` 2044 | /// use std::collections::HashMap; 2045 | /// 2046 | /// let mut map: HashMap<&str, u32> = HashMap::new(); 2047 | /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); 2048 | /// ``` 2049 | pub fn key(&self) -> &K { 2050 | match *self { 2051 | Occupied(ref entry) => entry.key(), 2052 | Vacant(ref entry) => entry.key(), 2053 | } 2054 | } 2055 | 2056 | /// Provides in-place mutable access to an occupied entry before any 2057 | /// potential inserts into the map. 2058 | /// 2059 | /// # Examples 2060 | /// 2061 | /// ``` 2062 | /// use std::collections::HashMap; 2063 | /// 2064 | /// let mut map: HashMap<&str, u32> = HashMap::new(); 2065 | /// 2066 | /// map.entry("poneyland") 2067 | /// .and_modify(|e| { *e += 1 }) 2068 | /// .or_insert(42); 2069 | /// assert_eq!(map["poneyland"], 42); 2070 | /// 2071 | /// map.entry("poneyland") 2072 | /// .and_modify(|e| { *e += 1 }) 2073 | /// .or_insert(42); 2074 | /// assert_eq!(map["poneyland"], 43); 2075 | /// ``` 2076 | pub fn and_modify(self, f: F) -> Self 2077 | where 2078 | F: FnOnce(&mut V), 2079 | { 2080 | match self { 2081 | Occupied(mut entry) => { 2082 | f(entry.get_mut()); 2083 | Occupied(entry) 2084 | } 2085 | Vacant(entry) => Vacant(entry), 2086 | } 2087 | } 2088 | } 2089 | 2090 | impl<'a, K, V: Default> Entry<'a, K, V> { 2091 | /// Ensures a value is in the entry by inserting the default value if empty, 2092 | /// and returns a mutable reference to the value in the entry. 2093 | /// 2094 | /// # Examples 2095 | /// 2096 | /// ``` 2097 | /// # fn main() { 2098 | /// use std::collections::HashMap; 2099 | /// 2100 | /// let mut map: HashMap<&str, Option> = HashMap::new(); 2101 | /// map.entry("poneyland").or_default(); 2102 | /// 2103 | /// assert_eq!(map["poneyland"], None); 2104 | /// # } 2105 | /// ``` 2106 | pub fn or_default(self) -> &'a mut V { 2107 | match self { 2108 | Occupied(entry) => entry.into_mut(), 2109 | Vacant(entry) => entry.insert(Default::default()), 2110 | } 2111 | } 2112 | } 2113 | 2114 | impl<'a, K, V> OccupiedEntry<'a, K, V> { 2115 | /// Gets a reference to the key in the entry. 2116 | /// 2117 | /// # Examples 2118 | /// 2119 | /// ``` 2120 | /// use std::collections::HashMap; 2121 | /// 2122 | /// let mut map: HashMap<&str, u32> = HashMap::new(); 2123 | /// map.entry("poneyland").or_insert(12); 2124 | /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); 2125 | /// ``` 2126 | pub fn key(&self) -> &K { 2127 | self.elem.read().0 2128 | } 2129 | 2130 | /// Take the ownership of the key and value from the map. 2131 | /// 2132 | /// # Examples 2133 | /// 2134 | /// ``` 2135 | /// use std::collections::HashMap; 2136 | /// use std::collections::hash_map::Entry; 2137 | /// 2138 | /// let mut map: HashMap<&str, u32> = HashMap::new(); 2139 | /// map.entry("poneyland").or_insert(12); 2140 | /// 2141 | /// if let Entry::Occupied(o) = map.entry("poneyland") { 2142 | /// // We delete the entry from the map. 2143 | /// o.remove_entry(); 2144 | /// } 2145 | /// 2146 | /// assert_eq!(map.contains_key("poneyland"), false); 2147 | /// ``` 2148 | pub fn remove_entry(self) -> (K, V) { 2149 | let (k, v, _) = pop_internal(self.elem); 2150 | (k, v) 2151 | } 2152 | 2153 | /// Gets a reference to the value in the entry. 2154 | /// 2155 | /// # Examples 2156 | /// 2157 | /// ``` 2158 | /// use std::collections::HashMap; 2159 | /// use std::collections::hash_map::Entry; 2160 | /// 2161 | /// let mut map: HashMap<&str, u32> = HashMap::new(); 2162 | /// map.entry("poneyland").or_insert(12); 2163 | /// 2164 | /// if let Entry::Occupied(o) = map.entry("poneyland") { 2165 | /// assert_eq!(o.get(), &12); 2166 | /// } 2167 | /// ``` 2168 | pub fn get(&self) -> &V { 2169 | self.elem.read().1 2170 | } 2171 | 2172 | /// Gets a mutable reference to the value in the entry. 2173 | /// 2174 | /// If you need a reference to the `OccupiedEntry` which may outlive the 2175 | /// destruction of the `Entry` value, see [`into_mut`]. 2176 | /// 2177 | /// [`into_mut`]: #method.into_mut 2178 | /// 2179 | /// # Examples 2180 | /// 2181 | /// ``` 2182 | /// use std::collections::HashMap; 2183 | /// use std::collections::hash_map::Entry; 2184 | /// 2185 | /// let mut map: HashMap<&str, u32> = HashMap::new(); 2186 | /// map.entry("poneyland").or_insert(12); 2187 | /// 2188 | /// assert_eq!(map["poneyland"], 12); 2189 | /// if let Entry::Occupied(mut o) = map.entry("poneyland") { 2190 | /// *o.get_mut() += 10; 2191 | /// assert_eq!(*o.get(), 22); 2192 | /// 2193 | /// // We can use the same Entry multiple times. 2194 | /// *o.get_mut() += 2; 2195 | /// } 2196 | /// 2197 | /// assert_eq!(map["poneyland"], 24); 2198 | /// ``` 2199 | pub fn get_mut(&mut self) -> &mut V { 2200 | self.elem.read_mut().1 2201 | } 2202 | 2203 | /// Converts the OccupiedEntry into a mutable reference to the value in the entry 2204 | /// with a lifetime bound to the map itself. 2205 | /// 2206 | /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`]. 2207 | /// 2208 | /// [`get_mut`]: #method.get_mut 2209 | /// 2210 | /// # Examples 2211 | /// 2212 | /// ``` 2213 | /// use std::collections::HashMap; 2214 | /// use std::collections::hash_map::Entry; 2215 | /// 2216 | /// let mut map: HashMap<&str, u32> = HashMap::new(); 2217 | /// map.entry("poneyland").or_insert(12); 2218 | /// 2219 | /// assert_eq!(map["poneyland"], 12); 2220 | /// if let Entry::Occupied(o) = map.entry("poneyland") { 2221 | /// *o.into_mut() += 10; 2222 | /// } 2223 | /// 2224 | /// assert_eq!(map["poneyland"], 22); 2225 | /// ``` 2226 | pub fn into_mut(self) -> &'a mut V { 2227 | self.elem.into_mut_refs().1 2228 | } 2229 | 2230 | /// Sets the value of the entry, and returns the entry's old value. 2231 | /// 2232 | /// # Examples 2233 | /// 2234 | /// ``` 2235 | /// use std::collections::HashMap; 2236 | /// use std::collections::hash_map::Entry; 2237 | /// 2238 | /// let mut map: HashMap<&str, u32> = HashMap::new(); 2239 | /// map.entry("poneyland").or_insert(12); 2240 | /// 2241 | /// if let Entry::Occupied(mut o) = map.entry("poneyland") { 2242 | /// assert_eq!(o.insert(15), 12); 2243 | /// } 2244 | /// 2245 | /// assert_eq!(map["poneyland"], 15); 2246 | /// ``` 2247 | pub fn insert(&mut self, mut value: V) -> V { 2248 | let old_value = self.get_mut(); 2249 | mem::swap(&mut value, old_value); 2250 | value 2251 | } 2252 | 2253 | /// Takes the value out of the entry, and returns it. 2254 | /// 2255 | /// # Examples 2256 | /// 2257 | /// ``` 2258 | /// use std::collections::HashMap; 2259 | /// use std::collections::hash_map::Entry; 2260 | /// 2261 | /// let mut map: HashMap<&str, u32> = HashMap::new(); 2262 | /// map.entry("poneyland").or_insert(12); 2263 | /// 2264 | /// if let Entry::Occupied(o) = map.entry("poneyland") { 2265 | /// assert_eq!(o.remove(), 12); 2266 | /// } 2267 | /// 2268 | /// assert_eq!(map.contains_key("poneyland"), false); 2269 | /// ``` 2270 | pub fn remove(self) -> V { 2271 | pop_internal(self.elem).1 2272 | } 2273 | 2274 | /// Returns a key that was used for search. 2275 | /// 2276 | /// The key was retained for further use. 2277 | fn take_key(&mut self) -> Option { 2278 | self.key.take() 2279 | } 2280 | 2281 | /// Replaces the entry, returning the old key and value. The new key in the hash map will be 2282 | /// the key used to create this entry. 2283 | /// 2284 | /// # Examples 2285 | /// 2286 | /// ``` 2287 | /// #![feature(map_entry_replace)] 2288 | /// use std::collections::hash_map::{Entry, HashMap}; 2289 | /// use std::rc::Rc; 2290 | /// 2291 | /// let mut map: HashMap, u32> = HashMap::new(); 2292 | /// map.insert(Rc::new("Stringthing".to_string()), 15); 2293 | /// 2294 | /// let my_key = Rc::new("Stringthing".to_string()); 2295 | /// 2296 | /// if let Entry::Occupied(entry) = map.entry(my_key) { 2297 | /// // Also replace the key with a handle to our other key. 2298 | /// let (old_key, old_value): (Rc, u32) = entry.replace_entry(16); 2299 | /// } 2300 | /// 2301 | /// ``` 2302 | pub fn replace_entry(mut self, value: V) -> (K, V) { 2303 | let (old_key, old_value) = self.elem.read_mut(); 2304 | 2305 | let old_key = mem::replace(old_key, self.key.unwrap()); 2306 | let old_value = mem::replace(old_value, value); 2307 | 2308 | (old_key, old_value) 2309 | } 2310 | 2311 | /// Replaces the key in the hash map with the key used to create this entry. 2312 | /// 2313 | /// # Examples 2314 | /// 2315 | /// ``` 2316 | /// #![feature(map_entry_replace)] 2317 | /// use std::collections::hash_map::{Entry, HashMap}; 2318 | /// use std::rc::Rc; 2319 | /// 2320 | /// let mut map: HashMap, u32> = HashMap::new(); 2321 | /// let mut known_strings: Vec> = Vec::new(); 2322 | /// 2323 | /// // Initialise known strings, run program, etc. 2324 | /// 2325 | /// reclaim_memory(&mut map, &known_strings); 2326 | /// 2327 | /// fn reclaim_memory(map: &mut HashMap, u32>, known_strings: &[Rc] ) { 2328 | /// for s in known_strings { 2329 | /// if let Entry::Occupied(entry) = map.entry(s.clone()) { 2330 | /// // Replaces the entry's key with our version of it in `known_strings`. 2331 | /// entry.replace_key(); 2332 | /// } 2333 | /// } 2334 | /// } 2335 | /// ``` 2336 | pub fn replace_key(mut self) -> K { 2337 | let (old_key, _) = self.elem.read_mut(); 2338 | mem::replace(old_key, self.key.unwrap()) 2339 | } 2340 | } 2341 | 2342 | impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { 2343 | /// Gets a reference to the key that would be used when inserting a value 2344 | /// through the `VacantEntry`. 2345 | /// 2346 | /// # Examples 2347 | /// 2348 | /// ``` 2349 | /// use std::collections::HashMap; 2350 | /// 2351 | /// let mut map: HashMap<&str, u32> = HashMap::new(); 2352 | /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); 2353 | /// ``` 2354 | pub fn key(&self) -> &K { 2355 | &self.key 2356 | } 2357 | 2358 | /// Take ownership of the key. 2359 | /// 2360 | /// # Examples 2361 | /// 2362 | /// ``` 2363 | /// use std::collections::HashMap; 2364 | /// use std::collections::hash_map::Entry; 2365 | /// 2366 | /// let mut map: HashMap<&str, u32> = HashMap::new(); 2367 | /// 2368 | /// if let Entry::Vacant(v) = map.entry("poneyland") { 2369 | /// v.into_key(); 2370 | /// } 2371 | /// ``` 2372 | pub fn into_key(self) -> K { 2373 | self.key 2374 | } 2375 | 2376 | /// Sets the value of the entry with the VacantEntry's key, 2377 | /// and returns a mutable reference to it. 2378 | /// 2379 | /// # Examples 2380 | /// 2381 | /// ``` 2382 | /// use std::collections::HashMap; 2383 | /// use std::collections::hash_map::Entry; 2384 | /// 2385 | /// let mut map: HashMap<&str, u32> = HashMap::new(); 2386 | /// 2387 | /// if let Entry::Vacant(o) = map.entry("poneyland") { 2388 | /// o.insert(37); 2389 | /// } 2390 | /// assert_eq!(map["poneyland"], 37); 2391 | /// ``` 2392 | pub fn insert(self, value: V) -> &'a mut V { 2393 | let b = match self.elem { 2394 | NeqElem(mut bucket, disp) => { 2395 | if disp >= DISPLACEMENT_THRESHOLD { 2396 | bucket.table_mut().set_tag(true); 2397 | } 2398 | robin_hood(bucket, disp, self.hash, self.key, value) 2399 | } 2400 | NoElem(mut bucket, disp) => { 2401 | if disp >= DISPLACEMENT_THRESHOLD { 2402 | bucket.table_mut().set_tag(true); 2403 | } 2404 | bucket.put(self.hash, self.key, value) 2405 | } 2406 | }; 2407 | b.into_mut_refs().1 2408 | } 2409 | } 2410 | 2411 | impl FromIterator<(K, V)> for HashMap 2412 | where 2413 | K: Eq + Hash, 2414 | S: BuildHasher + Default, 2415 | { 2416 | fn from_iter>(iter: T) -> HashMap { 2417 | let mut map = HashMap::with_hasher(Default::default()); 2418 | map.extend(iter); 2419 | map 2420 | } 2421 | } 2422 | 2423 | impl Extend<(K, V)> for HashMap 2424 | where 2425 | K: Eq + Hash, 2426 | S: BuildHasher, 2427 | { 2428 | fn extend>(&mut self, iter: T) { 2429 | // Keys may be already present or show multiple times in the iterator. 2430 | // Reserve the entire hint lower bound if the map is empty. 2431 | // Otherwise reserve half the hint (rounded up), so the map 2432 | // will only resize twice in the worst case. 2433 | let iter = iter.into_iter(); 2434 | let reserve = if self.is_empty() { 2435 | iter.size_hint().0 2436 | } else { 2437 | (iter.size_hint().0 + 1) / 2 2438 | }; 2439 | self.reserve(reserve); 2440 | for (k, v) in iter { 2441 | self.insert(k, v); 2442 | } 2443 | } 2444 | } 2445 | 2446 | impl<'a, K, V, S> Extend<(&'a K, &'a V)> for HashMap 2447 | where 2448 | K: Eq + Hash + Copy, 2449 | V: Copy, 2450 | S: BuildHasher, 2451 | { 2452 | fn extend>(&mut self, iter: T) { 2453 | self.extend(iter.into_iter().map(|(&key, &value)| (key, value))); 2454 | } 2455 | } 2456 | 2457 | impl super::Recover for HashMap 2458 | where 2459 | K: Eq + Hash + Borrow, 2460 | S: BuildHasher, 2461 | Q: Eq + Hash, 2462 | { 2463 | type Key = K; 2464 | 2465 | #[inline] 2466 | fn get(&self, key: &Q) -> Option<&K> { 2467 | self.search(key).map(|bucket| bucket.into_refs().0) 2468 | } 2469 | 2470 | fn take(&mut self, key: &Q) -> Option { 2471 | self.search_mut(key).map(|bucket| pop_internal(bucket).0) 2472 | } 2473 | 2474 | #[inline] 2475 | fn replace(&mut self, key: K) -> Option { 2476 | self.reserve(1); 2477 | 2478 | match self.entry(key) { 2479 | Occupied(mut occupied) => { 2480 | let key = occupied.take_key().unwrap(); 2481 | Some(mem::replace(occupied.elem.read_mut().0, key)) 2482 | } 2483 | Vacant(vacant) => { 2484 | vacant.insert(()); 2485 | None 2486 | } 2487 | } 2488 | } 2489 | } 2490 | 2491 | #[allow(dead_code)] 2492 | fn assert_covariance() { 2493 | fn map_key<'new>(v: HashMap<&'static str, u8>) -> HashMap<&'new str, u8> { 2494 | v 2495 | } 2496 | fn map_val<'new>(v: HashMap) -> HashMap { 2497 | v 2498 | } 2499 | fn iter_key<'a, 'new>(v: Iter<'a, &'static str, u8>) -> Iter<'a, &'new str, u8> { 2500 | v 2501 | } 2502 | fn iter_val<'a, 'new>(v: Iter<'a, u8, &'static str>) -> Iter<'a, u8, &'new str> { 2503 | v 2504 | } 2505 | fn into_iter_key<'new>(v: IntoIter<&'static str, u8>) -> IntoIter<&'new str, u8> { 2506 | v 2507 | } 2508 | fn into_iter_val<'new>(v: IntoIter) -> IntoIter { 2509 | v 2510 | } 2511 | fn keys_key<'a, 'new>(v: Keys<'a, &'static str, u8>) -> Keys<'a, &'new str, u8> { 2512 | v 2513 | } 2514 | fn keys_val<'a, 'new>(v: Keys<'a, u8, &'static str>) -> Keys<'a, u8, &'new str> { 2515 | v 2516 | } 2517 | fn values_key<'a, 'new>(v: Values<'a, &'static str, u8>) -> Values<'a, &'new str, u8> { 2518 | v 2519 | } 2520 | fn values_val<'a, 'new>(v: Values<'a, u8, &'static str>) -> Values<'a, u8, &'new str> { 2521 | v 2522 | } 2523 | fn drain<'new>( 2524 | d: Drain<'static, &'static str, &'static str>, 2525 | ) -> Drain<'new, &'new str, &'new str> { 2526 | d 2527 | } 2528 | } 2529 | -------------------------------------------------------------------------------- /src/set.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | use core::borrow::Borrow; 12 | use core::fmt; 13 | use core::hash::{BuildHasher, Hash}; 14 | use core::iter::{Chain, FromIterator, FusedIterator}; 15 | use core::ops::{BitAnd, BitOr, BitXor, Sub}; 16 | 17 | use super::map::{self, HashMap, Keys, RandomState}; 18 | use super::Recover; 19 | 20 | // Future Optimization (FIXME!) 21 | // ============================= 22 | // 23 | // Iteration over zero sized values is a noop. There is no need 24 | // for `bucket.val` in the case of HashSet. I suppose we would need HKT 25 | // to get rid of it properly. 26 | 27 | /// A hash set implemented as a `HashMap` where the value is `()`. 28 | /// 29 | /// As with the [`HashMap`] type, a `HashSet` requires that the elements 30 | /// implement the [`Eq`] and [`Hash`] traits. This can frequently be achieved by 31 | /// using `#[derive(PartialEq, Eq, Hash)]`. If you implement these yourself, 32 | /// it is important that the following property holds: 33 | /// 34 | /// ```text 35 | /// k1 == k2 -> hash(k1) == hash(k2) 36 | /// ``` 37 | /// 38 | /// In other words, if two keys are equal, their hashes must be equal. 39 | /// 40 | /// 41 | /// It is a logic error for an item to be modified in such a way that the 42 | /// item's hash, as determined by the [`Hash`] trait, or its equality, as 43 | /// determined by the [`Eq`] trait, changes while it is in the set. This is 44 | /// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or 45 | /// unsafe code. 46 | /// 47 | /// # Examples 48 | /// 49 | /// ``` 50 | /// use std::collections::HashSet; 51 | /// // Type inference lets us omit an explicit type signature (which 52 | /// // would be `HashSet<&str>` in this example). 53 | /// let mut books = HashSet::new(); 54 | /// 55 | /// // Add some books. 56 | /// books.insert("A Dance With Dragons"); 57 | /// books.insert("To Kill a Mockingbird"); 58 | /// books.insert("The Odyssey"); 59 | /// books.insert("The Great Gatsby"); 60 | /// 61 | /// // Check for a specific one. 62 | /// if !books.contains("The Winds of Winter") { 63 | /// println!("We have {} books, but The Winds of Winter ain't one.", 64 | /// books.len()); 65 | /// } 66 | /// 67 | /// // Remove a book. 68 | /// books.remove("The Odyssey"); 69 | /// 70 | /// // Iterate over everything. 71 | /// for book in &books { 72 | /// println!("{}", book); 73 | /// } 74 | /// ``` 75 | /// 76 | /// The easiest way to use `HashSet` with a custom type is to derive 77 | /// [`Eq`] and [`Hash`]. We must also derive [`PartialEq`], this will in the 78 | /// future be implied by [`Eq`]. 79 | /// 80 | /// ``` 81 | /// use std::collections::HashSet; 82 | /// #[derive(Hash, Eq, PartialEq, Debug)] 83 | /// struct Viking<'a> { 84 | /// name: &'a str, 85 | /// power: usize, 86 | /// } 87 | /// 88 | /// let mut vikings = HashSet::new(); 89 | /// 90 | /// vikings.insert(Viking { name: "Einar", power: 9 }); 91 | /// vikings.insert(Viking { name: "Einar", power: 9 }); 92 | /// vikings.insert(Viking { name: "Olaf", power: 4 }); 93 | /// vikings.insert(Viking { name: "Harald", power: 8 }); 94 | /// 95 | /// // Use derived implementation to print the vikings. 96 | /// for x in &vikings { 97 | /// println!("{:?}", x); 98 | /// } 99 | /// ``` 100 | /// 101 | /// A `HashSet` with fixed list of elements can be initialized from an array: 102 | /// 103 | /// ``` 104 | /// use std::collections::HashSet; 105 | /// 106 | /// fn main() { 107 | /// let viking_names: HashSet<&str> = 108 | /// [ "Einar", "Olaf", "Harald" ].iter().cloned().collect(); 109 | /// // use the values stored in the set 110 | /// } 111 | /// ``` 112 | /// 113 | /// [`Cell`]: ../../std/cell/struct.Cell.html 114 | /// [`Eq`]: ../../std/cmp/trait.Eq.html 115 | /// [`Hash`]: ../../std/hash/trait.Hash.html 116 | /// [`HashMap`]: struct.HashMap.html 117 | /// [`PartialEq`]: ../../std/cmp/trait.PartialEq.html 118 | /// [`RefCell`]: ../../std/cell/struct.RefCell.html 119 | #[derive(Clone)] 120 | pub struct HashSet { 121 | map: HashMap, 122 | } 123 | 124 | impl HashSet { 125 | /// Creates an empty `HashSet`. 126 | /// 127 | /// The hash set is initially created with a capacity of 0, so it will not allocate until it 128 | /// is first inserted into. 129 | /// 130 | /// # Examples 131 | /// 132 | /// ``` 133 | /// use std::collections::HashSet; 134 | /// let set: HashSet = HashSet::new(); 135 | /// ``` 136 | #[inline] 137 | pub fn new() -> HashSet { 138 | HashSet { 139 | map: HashMap::new(), 140 | } 141 | } 142 | 143 | /// Creates an empty `HashSet` with the specified capacity. 144 | /// 145 | /// The hash set will be able to hold at least `capacity` elements without 146 | /// reallocating. If `capacity` is 0, the hash set will not allocate. 147 | /// 148 | /// # Examples 149 | /// 150 | /// ``` 151 | /// use std::collections::HashSet; 152 | /// let set: HashSet = HashSet::with_capacity(10); 153 | /// assert!(set.capacity() >= 10); 154 | /// ``` 155 | #[inline] 156 | pub fn with_capacity(capacity: usize) -> HashSet { 157 | HashSet { 158 | map: HashMap::with_capacity(capacity), 159 | } 160 | } 161 | } 162 | 163 | impl HashSet 164 | where 165 | T: Eq + Hash, 166 | S: BuildHasher, 167 | { 168 | /// Creates a new empty hash set which will use the given hasher to hash 169 | /// keys. 170 | /// 171 | /// The hash set is also created with the default initial capacity. 172 | /// 173 | /// Warning: `hasher` is normally randomly generated, and 174 | /// is designed to allow `HashSet`s to be resistant to attacks that 175 | /// cause many collisions and very poor performance. Setting it 176 | /// manually using this function can expose a DoS attack vector. 177 | /// 178 | /// # Examples 179 | /// 180 | /// ``` 181 | /// use std::collections::HashSet; 182 | /// use std::collections::hash_map::RandomState; 183 | /// 184 | /// let s = RandomState::new(); 185 | /// let mut set = HashSet::with_hasher(s); 186 | /// set.insert(2); 187 | /// ``` 188 | #[inline] 189 | pub fn with_hasher(hasher: S) -> HashSet { 190 | HashSet { 191 | map: HashMap::with_hasher(hasher), 192 | } 193 | } 194 | 195 | /// Creates an empty `HashSet` with with the specified capacity, using 196 | /// `hasher` to hash the keys. 197 | /// 198 | /// The hash set will be able to hold at least `capacity` elements without 199 | /// reallocating. If `capacity` is 0, the hash set will not allocate. 200 | /// 201 | /// Warning: `hasher` is normally randomly generated, and 202 | /// is designed to allow `HashSet`s to be resistant to attacks that 203 | /// cause many collisions and very poor performance. Setting it 204 | /// manually using this function can expose a DoS attack vector. 205 | /// 206 | /// # Examples 207 | /// 208 | /// ``` 209 | /// use std::collections::HashSet; 210 | /// use std::collections::hash_map::RandomState; 211 | /// 212 | /// let s = RandomState::new(); 213 | /// let mut set = HashSet::with_capacity_and_hasher(10, s); 214 | /// set.insert(1); 215 | /// ``` 216 | #[inline] 217 | pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet { 218 | HashSet { 219 | map: HashMap::with_capacity_and_hasher(capacity, hasher), 220 | } 221 | } 222 | 223 | /// Returns a reference to the set's [`BuildHasher`]. 224 | /// 225 | /// [`BuildHasher`]: ../../std/hash/trait.BuildHasher.html 226 | /// 227 | /// # Examples 228 | /// 229 | /// ``` 230 | /// use std::collections::HashSet; 231 | /// use std::collections::hash_map::RandomState; 232 | /// 233 | /// let hasher = RandomState::new(); 234 | /// let set: HashSet = HashSet::with_hasher(hasher); 235 | /// let hasher: &RandomState = set.hasher(); 236 | /// ``` 237 | pub fn hasher(&self) -> &S { 238 | self.map.hasher() 239 | } 240 | 241 | /// Returns the number of elements the set can hold without reallocating. 242 | /// 243 | /// # Examples 244 | /// 245 | /// ``` 246 | /// use std::collections::HashSet; 247 | /// let set: HashSet = HashSet::with_capacity(100); 248 | /// assert!(set.capacity() >= 100); 249 | /// ``` 250 | #[inline] 251 | pub fn capacity(&self) -> usize { 252 | self.map.capacity() 253 | } 254 | 255 | /// Reserves capacity for at least `additional` more elements to be inserted 256 | /// in the `HashSet`. The collection may reserve more space to avoid 257 | /// frequent reallocations. 258 | /// 259 | /// # Panics 260 | /// 261 | /// Panics if the new allocation size overflows `usize`. 262 | /// 263 | /// # Examples 264 | /// 265 | /// ``` 266 | /// use std::collections::HashSet; 267 | /// let mut set: HashSet = HashSet::new(); 268 | /// set.reserve(10); 269 | /// assert!(set.capacity() >= 10); 270 | /// ``` 271 | pub fn reserve(&mut self, additional: usize) { 272 | self.map.reserve(additional) 273 | } 274 | 275 | /// Shrinks the capacity of the set as much as possible. It will drop 276 | /// down as much as possible while maintaining the internal rules 277 | /// and possibly leaving some space in accordance with the resize policy. 278 | /// 279 | /// # Examples 280 | /// 281 | /// ``` 282 | /// use std::collections::HashSet; 283 | /// 284 | /// let mut set = HashSet::with_capacity(100); 285 | /// set.insert(1); 286 | /// set.insert(2); 287 | /// assert!(set.capacity() >= 100); 288 | /// set.shrink_to_fit(); 289 | /// assert!(set.capacity() >= 2); 290 | /// ``` 291 | pub fn shrink_to_fit(&mut self) { 292 | self.map.shrink_to_fit() 293 | } 294 | 295 | /// Shrinks the capacity of the set with a lower limit. It will drop 296 | /// down no lower than the supplied limit while maintaining the internal rules 297 | /// and possibly leaving some space in accordance with the resize policy. 298 | /// 299 | /// Panics if the current capacity is smaller than the supplied 300 | /// minimum capacity. 301 | /// 302 | /// # Examples 303 | /// 304 | /// ``` 305 | /// #![feature(shrink_to)] 306 | /// use std::collections::HashSet; 307 | /// 308 | /// let mut set = HashSet::with_capacity(100); 309 | /// set.insert(1); 310 | /// set.insert(2); 311 | /// assert!(set.capacity() >= 100); 312 | /// set.shrink_to(10); 313 | /// assert!(set.capacity() >= 10); 314 | /// set.shrink_to(0); 315 | /// assert!(set.capacity() >= 2); 316 | /// ``` 317 | #[inline] 318 | pub fn shrink_to(&mut self, min_capacity: usize) { 319 | self.map.shrink_to(min_capacity) 320 | } 321 | 322 | /// An iterator visiting all elements in arbitrary order. 323 | /// The iterator element type is `&'a T`. 324 | /// 325 | /// # Examples 326 | /// 327 | /// ``` 328 | /// use std::collections::HashSet; 329 | /// let mut set = HashSet::new(); 330 | /// set.insert("a"); 331 | /// set.insert("b"); 332 | /// 333 | /// // Will print in an arbitrary order. 334 | /// for x in set.iter() { 335 | /// println!("{}", x); 336 | /// } 337 | /// ``` 338 | pub fn iter(&self) -> Iter { 339 | Iter { 340 | iter: self.map.keys(), 341 | } 342 | } 343 | 344 | /// Visits the values representing the difference, 345 | /// i.e. the values that are in `self` but not in `other`. 346 | /// 347 | /// # Examples 348 | /// 349 | /// ``` 350 | /// use std::collections::HashSet; 351 | /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect(); 352 | /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect(); 353 | /// 354 | /// // Can be seen as `a - b`. 355 | /// for x in a.difference(&b) { 356 | /// println!("{}", x); // Print 1 357 | /// } 358 | /// 359 | /// let diff: HashSet<_> = a.difference(&b).collect(); 360 | /// assert_eq!(diff, [1].iter().collect()); 361 | /// 362 | /// // Note that difference is not symmetric, 363 | /// // and `b - a` means something else: 364 | /// let diff: HashSet<_> = b.difference(&a).collect(); 365 | /// assert_eq!(diff, [4].iter().collect()); 366 | /// ``` 367 | pub fn difference<'a>(&'a self, other: &'a HashSet) -> Difference<'a, T, S> { 368 | Difference { 369 | iter: self.iter(), 370 | other, 371 | } 372 | } 373 | 374 | /// Visits the values representing the symmetric difference, 375 | /// i.e. the values that are in `self` or in `other` but not in both. 376 | /// 377 | /// # Examples 378 | /// 379 | /// ``` 380 | /// use std::collections::HashSet; 381 | /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect(); 382 | /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect(); 383 | /// 384 | /// // Print 1, 4 in arbitrary order. 385 | /// for x in a.symmetric_difference(&b) { 386 | /// println!("{}", x); 387 | /// } 388 | /// 389 | /// let diff1: HashSet<_> = a.symmetric_difference(&b).collect(); 390 | /// let diff2: HashSet<_> = b.symmetric_difference(&a).collect(); 391 | /// 392 | /// assert_eq!(diff1, diff2); 393 | /// assert_eq!(diff1, [1, 4].iter().collect()); 394 | /// ``` 395 | pub fn symmetric_difference<'a>( 396 | &'a self, 397 | other: &'a HashSet, 398 | ) -> SymmetricDifference<'a, T, S> { 399 | SymmetricDifference { 400 | iter: self.difference(other).chain(other.difference(self)), 401 | } 402 | } 403 | 404 | /// Visits the values representing the intersection, 405 | /// i.e. the values that are both in `self` and `other`. 406 | /// 407 | /// # Examples 408 | /// 409 | /// ``` 410 | /// use std::collections::HashSet; 411 | /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect(); 412 | /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect(); 413 | /// 414 | /// // Print 2, 3 in arbitrary order. 415 | /// for x in a.intersection(&b) { 416 | /// println!("{}", x); 417 | /// } 418 | /// 419 | /// let intersection: HashSet<_> = a.intersection(&b).collect(); 420 | /// assert_eq!(intersection, [2, 3].iter().collect()); 421 | /// ``` 422 | pub fn intersection<'a>(&'a self, other: &'a HashSet) -> Intersection<'a, T, S> { 423 | Intersection { 424 | iter: self.iter(), 425 | other, 426 | } 427 | } 428 | 429 | /// Visits the values representing the union, 430 | /// i.e. all the values in `self` or `other`, without duplicates. 431 | /// 432 | /// # Examples 433 | /// 434 | /// ``` 435 | /// use std::collections::HashSet; 436 | /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect(); 437 | /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect(); 438 | /// 439 | /// // Print 1, 2, 3, 4 in arbitrary order. 440 | /// for x in a.union(&b) { 441 | /// println!("{}", x); 442 | /// } 443 | /// 444 | /// let union: HashSet<_> = a.union(&b).collect(); 445 | /// assert_eq!(union, [1, 2, 3, 4].iter().collect()); 446 | /// ``` 447 | pub fn union<'a>(&'a self, other: &'a HashSet) -> Union<'a, T, S> { 448 | Union { 449 | iter: self.iter().chain(other.difference(self)), 450 | } 451 | } 452 | 453 | /// Returns the number of elements in the set. 454 | /// 455 | /// # Examples 456 | /// 457 | /// ``` 458 | /// use std::collections::HashSet; 459 | /// 460 | /// let mut v = HashSet::new(); 461 | /// assert_eq!(v.len(), 0); 462 | /// v.insert(1); 463 | /// assert_eq!(v.len(), 1); 464 | /// ``` 465 | pub fn len(&self) -> usize { 466 | self.map.len() 467 | } 468 | 469 | /// Returns true if the set contains no elements. 470 | /// 471 | /// # Examples 472 | /// 473 | /// ``` 474 | /// use std::collections::HashSet; 475 | /// 476 | /// let mut v = HashSet::new(); 477 | /// assert!(v.is_empty()); 478 | /// v.insert(1); 479 | /// assert!(!v.is_empty()); 480 | /// ``` 481 | pub fn is_empty(&self) -> bool { 482 | self.map.is_empty() 483 | } 484 | 485 | /// Clears the set, returning all elements in an iterator. 486 | /// 487 | /// # Examples 488 | /// 489 | /// ``` 490 | /// use std::collections::HashSet; 491 | /// 492 | /// let mut set: HashSet<_> = [1, 2, 3].iter().cloned().collect(); 493 | /// assert!(!set.is_empty()); 494 | /// 495 | /// // print 1, 2, 3 in an arbitrary order 496 | /// for i in set.drain() { 497 | /// println!("{}", i); 498 | /// } 499 | /// 500 | /// assert!(set.is_empty()); 501 | /// ``` 502 | #[inline] 503 | pub fn drain(&mut self) -> Drain { 504 | Drain { 505 | iter: self.map.drain(), 506 | } 507 | } 508 | 509 | /// Clears the set, removing all values. 510 | /// 511 | /// # Examples 512 | /// 513 | /// ``` 514 | /// use std::collections::HashSet; 515 | /// 516 | /// let mut v = HashSet::new(); 517 | /// v.insert(1); 518 | /// v.clear(); 519 | /// assert!(v.is_empty()); 520 | /// ``` 521 | pub fn clear(&mut self) { 522 | self.map.clear() 523 | } 524 | 525 | /// Returns `true` if the set contains a value. 526 | /// 527 | /// The value may be any borrowed form of the set's value type, but 528 | /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for 529 | /// the value type. 530 | /// 531 | /// # Examples 532 | /// 533 | /// ``` 534 | /// use std::collections::HashSet; 535 | /// 536 | /// let set: HashSet<_> = [1, 2, 3].iter().cloned().collect(); 537 | /// assert_eq!(set.contains(&1), true); 538 | /// assert_eq!(set.contains(&4), false); 539 | /// ``` 540 | /// 541 | /// [`Eq`]: ../../std/cmp/trait.Eq.html 542 | /// [`Hash`]: ../../std/hash/trait.Hash.html 543 | pub fn contains(&self, value: &Q) -> bool 544 | where 545 | T: Borrow, 546 | Q: Hash + Eq, 547 | { 548 | self.map.contains_key(value) 549 | } 550 | 551 | /// Returns a reference to the value in the set, if any, that is equal to the given value. 552 | /// 553 | /// The value may be any borrowed form of the set's value type, but 554 | /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for 555 | /// the value type. 556 | /// 557 | /// # Examples 558 | /// 559 | /// ``` 560 | /// use std::collections::HashSet; 561 | /// 562 | /// let set: HashSet<_> = [1, 2, 3].iter().cloned().collect(); 563 | /// assert_eq!(set.get(&2), Some(&2)); 564 | /// assert_eq!(set.get(&4), None); 565 | /// ``` 566 | /// 567 | /// [`Eq`]: ../../std/cmp/trait.Eq.html 568 | /// [`Hash`]: ../../std/hash/trait.Hash.html 569 | pub fn get(&self, value: &Q) -> Option<&T> 570 | where 571 | T: Borrow, 572 | Q: Hash + Eq, 573 | { 574 | Recover::get(&self.map, value) 575 | } 576 | 577 | /// Returns `true` if `self` has no elements in common with `other`. 578 | /// This is equivalent to checking for an empty intersection. 579 | /// 580 | /// # Examples 581 | /// 582 | /// ``` 583 | /// use std::collections::HashSet; 584 | /// 585 | /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect(); 586 | /// let mut b = HashSet::new(); 587 | /// 588 | /// assert_eq!(a.is_disjoint(&b), true); 589 | /// b.insert(4); 590 | /// assert_eq!(a.is_disjoint(&b), true); 591 | /// b.insert(1); 592 | /// assert_eq!(a.is_disjoint(&b), false); 593 | /// ``` 594 | pub fn is_disjoint(&self, other: &HashSet) -> bool { 595 | self.iter().all(|v| !other.contains(v)) 596 | } 597 | 598 | /// Returns `true` if the set is a subset of another, 599 | /// i.e. `other` contains at least all the values in `self`. 600 | /// 601 | /// # Examples 602 | /// 603 | /// ``` 604 | /// use std::collections::HashSet; 605 | /// 606 | /// let sup: HashSet<_> = [1, 2, 3].iter().cloned().collect(); 607 | /// let mut set = HashSet::new(); 608 | /// 609 | /// assert_eq!(set.is_subset(&sup), true); 610 | /// set.insert(2); 611 | /// assert_eq!(set.is_subset(&sup), true); 612 | /// set.insert(4); 613 | /// assert_eq!(set.is_subset(&sup), false); 614 | /// ``` 615 | pub fn is_subset(&self, other: &HashSet) -> bool { 616 | self.iter().all(|v| other.contains(v)) 617 | } 618 | 619 | /// Returns `true` if the set is a superset of another, 620 | /// i.e. `self` contains at least all the values in `other`. 621 | /// 622 | /// # Examples 623 | /// 624 | /// ``` 625 | /// use std::collections::HashSet; 626 | /// 627 | /// let sub: HashSet<_> = [1, 2].iter().cloned().collect(); 628 | /// let mut set = HashSet::new(); 629 | /// 630 | /// assert_eq!(set.is_superset(&sub), false); 631 | /// 632 | /// set.insert(0); 633 | /// set.insert(1); 634 | /// assert_eq!(set.is_superset(&sub), false); 635 | /// 636 | /// set.insert(2); 637 | /// assert_eq!(set.is_superset(&sub), true); 638 | /// ``` 639 | #[inline] 640 | pub fn is_superset(&self, other: &HashSet) -> bool { 641 | other.is_subset(self) 642 | } 643 | 644 | /// Adds a value to the set. 645 | /// 646 | /// If the set did not have this value present, `true` is returned. 647 | /// 648 | /// If the set did have this value present, `false` is returned. 649 | /// 650 | /// # Examples 651 | /// 652 | /// ``` 653 | /// use std::collections::HashSet; 654 | /// 655 | /// let mut set = HashSet::new(); 656 | /// 657 | /// assert_eq!(set.insert(2), true); 658 | /// assert_eq!(set.insert(2), false); 659 | /// assert_eq!(set.len(), 1); 660 | /// ``` 661 | pub fn insert(&mut self, value: T) -> bool { 662 | self.map.insert(value, ()).is_none() 663 | } 664 | 665 | /// Adds a value to the set, replacing the existing value, if any, that is equal to the given 666 | /// one. Returns the replaced value. 667 | /// 668 | /// # Examples 669 | /// 670 | /// ``` 671 | /// use std::collections::HashSet; 672 | /// 673 | /// let mut set = HashSet::new(); 674 | /// set.insert(Vec::::new()); 675 | /// 676 | /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 0); 677 | /// set.replace(Vec::with_capacity(10)); 678 | /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 10); 679 | /// ``` 680 | pub fn replace(&mut self, value: T) -> Option { 681 | Recover::replace(&mut self.map, value) 682 | } 683 | 684 | /// Removes a value from the set. Returns `true` if the value was 685 | /// present in the set. 686 | /// 687 | /// The value may be any borrowed form of the set's value type, but 688 | /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for 689 | /// the value type. 690 | /// 691 | /// # Examples 692 | /// 693 | /// ``` 694 | /// use std::collections::HashSet; 695 | /// 696 | /// let mut set = HashSet::new(); 697 | /// 698 | /// set.insert(2); 699 | /// assert_eq!(set.remove(&2), true); 700 | /// assert_eq!(set.remove(&2), false); 701 | /// ``` 702 | /// 703 | /// [`Eq`]: ../../std/cmp/trait.Eq.html 704 | /// [`Hash`]: ../../std/hash/trait.Hash.html 705 | pub fn remove(&mut self, value: &Q) -> bool 706 | where 707 | T: Borrow, 708 | Q: Hash + Eq, 709 | { 710 | self.map.remove(value).is_some() 711 | } 712 | 713 | /// Removes and returns the value in the set, if any, that is equal to the given one. 714 | /// 715 | /// The value may be any borrowed form of the set's value type, but 716 | /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for 717 | /// the value type. 718 | /// 719 | /// # Examples 720 | /// 721 | /// ``` 722 | /// use std::collections::HashSet; 723 | /// 724 | /// let mut set: HashSet<_> = [1, 2, 3].iter().cloned().collect(); 725 | /// assert_eq!(set.take(&2), Some(2)); 726 | /// assert_eq!(set.take(&2), None); 727 | /// ``` 728 | /// 729 | /// [`Eq`]: ../../std/cmp/trait.Eq.html 730 | /// [`Hash`]: ../../std/hash/trait.Hash.html 731 | pub fn take(&mut self, value: &Q) -> Option 732 | where 733 | T: Borrow, 734 | Q: Hash + Eq, 735 | { 736 | Recover::take(&mut self.map, value) 737 | } 738 | 739 | /// Retains only the elements specified by the predicate. 740 | /// 741 | /// In other words, remove all elements `e` such that `f(&e)` returns `false`. 742 | /// 743 | /// # Examples 744 | /// 745 | /// ``` 746 | /// use std::collections::HashSet; 747 | /// 748 | /// let xs = [1,2,3,4,5,6]; 749 | /// let mut set: HashSet = xs.iter().cloned().collect(); 750 | /// set.retain(|&k| k % 2 == 0); 751 | /// assert_eq!(set.len(), 3); 752 | /// ``` 753 | pub fn retain(&mut self, mut f: F) 754 | where 755 | F: FnMut(&T) -> bool, 756 | { 757 | self.map.retain(|k, _| f(k)); 758 | } 759 | } 760 | 761 | impl PartialEq for HashSet 762 | where 763 | T: Eq + Hash, 764 | S: BuildHasher, 765 | { 766 | fn eq(&self, other: &HashSet) -> bool { 767 | if self.len() != other.len() { 768 | return false; 769 | } 770 | 771 | self.iter().all(|key| other.contains(key)) 772 | } 773 | } 774 | 775 | impl Eq for HashSet 776 | where 777 | T: Eq + Hash, 778 | S: BuildHasher, 779 | { 780 | } 781 | 782 | impl fmt::Debug for HashSet 783 | where 784 | T: Eq + Hash + fmt::Debug, 785 | S: BuildHasher, 786 | { 787 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 788 | f.debug_set().entries(self.iter()).finish() 789 | } 790 | } 791 | 792 | impl FromIterator for HashSet 793 | where 794 | T: Eq + Hash, 795 | S: BuildHasher + Default, 796 | { 797 | fn from_iter>(iter: I) -> HashSet { 798 | let mut set = HashSet::with_hasher(Default::default()); 799 | set.extend(iter); 800 | set 801 | } 802 | } 803 | 804 | impl Extend for HashSet 805 | where 806 | T: Eq + Hash, 807 | S: BuildHasher, 808 | { 809 | fn extend>(&mut self, iter: I) { 810 | self.map.extend(iter.into_iter().map(|k| (k, ()))); 811 | } 812 | } 813 | 814 | impl<'a, T, S> Extend<&'a T> for HashSet 815 | where 816 | T: 'a + Eq + Hash + Copy, 817 | S: BuildHasher, 818 | { 819 | fn extend>(&mut self, iter: I) { 820 | self.extend(iter.into_iter().cloned()); 821 | } 822 | } 823 | 824 | impl Default for HashSet 825 | where 826 | T: Eq + Hash, 827 | S: BuildHasher + Default, 828 | { 829 | /// Creates an empty `HashSet` with the `Default` value for the hasher. 830 | fn default() -> HashSet { 831 | HashSet { 832 | map: HashMap::default(), 833 | } 834 | } 835 | } 836 | 837 | impl<'a, 'b, T, S> BitOr<&'b HashSet> for &'a HashSet 838 | where 839 | T: Eq + Hash + Clone, 840 | S: BuildHasher + Default, 841 | { 842 | type Output = HashSet; 843 | 844 | /// Returns the union of `self` and `rhs` as a new `HashSet`. 845 | /// 846 | /// # Examples 847 | /// 848 | /// ``` 849 | /// use std::collections::HashSet; 850 | /// 851 | /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect(); 852 | /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect(); 853 | /// 854 | /// let set = &a | &b; 855 | /// 856 | /// let mut i = 0; 857 | /// let expected = [1, 2, 3, 4, 5]; 858 | /// for x in &set { 859 | /// assert!(expected.contains(x)); 860 | /// i += 1; 861 | /// } 862 | /// assert_eq!(i, expected.len()); 863 | /// ``` 864 | fn bitor(self, rhs: &HashSet) -> HashSet { 865 | self.union(rhs).cloned().collect() 866 | } 867 | } 868 | 869 | impl<'a, 'b, T, S> BitAnd<&'b HashSet> for &'a HashSet 870 | where 871 | T: Eq + Hash + Clone, 872 | S: BuildHasher + Default, 873 | { 874 | type Output = HashSet; 875 | 876 | /// Returns the intersection of `self` and `rhs` as a new `HashSet`. 877 | /// 878 | /// # Examples 879 | /// 880 | /// ``` 881 | /// use std::collections::HashSet; 882 | /// 883 | /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect(); 884 | /// let b: HashSet<_> = vec![2, 3, 4].into_iter().collect(); 885 | /// 886 | /// let set = &a & &b; 887 | /// 888 | /// let mut i = 0; 889 | /// let expected = [2, 3]; 890 | /// for x in &set { 891 | /// assert!(expected.contains(x)); 892 | /// i += 1; 893 | /// } 894 | /// assert_eq!(i, expected.len()); 895 | /// ``` 896 | fn bitand(self, rhs: &HashSet) -> HashSet { 897 | self.intersection(rhs).cloned().collect() 898 | } 899 | } 900 | 901 | impl<'a, 'b, T, S> BitXor<&'b HashSet> for &'a HashSet 902 | where 903 | T: Eq + Hash + Clone, 904 | S: BuildHasher + Default, 905 | { 906 | type Output = HashSet; 907 | 908 | /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet`. 909 | /// 910 | /// # Examples 911 | /// 912 | /// ``` 913 | /// use std::collections::HashSet; 914 | /// 915 | /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect(); 916 | /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect(); 917 | /// 918 | /// let set = &a ^ &b; 919 | /// 920 | /// let mut i = 0; 921 | /// let expected = [1, 2, 4, 5]; 922 | /// for x in &set { 923 | /// assert!(expected.contains(x)); 924 | /// i += 1; 925 | /// } 926 | /// assert_eq!(i, expected.len()); 927 | /// ``` 928 | fn bitxor(self, rhs: &HashSet) -> HashSet { 929 | self.symmetric_difference(rhs).cloned().collect() 930 | } 931 | } 932 | 933 | impl<'a, 'b, T, S> Sub<&'b HashSet> for &'a HashSet 934 | where 935 | T: Eq + Hash + Clone, 936 | S: BuildHasher + Default, 937 | { 938 | type Output = HashSet; 939 | 940 | /// Returns the difference of `self` and `rhs` as a new `HashSet`. 941 | /// 942 | /// # Examples 943 | /// 944 | /// ``` 945 | /// use std::collections::HashSet; 946 | /// 947 | /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect(); 948 | /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect(); 949 | /// 950 | /// let set = &a - &b; 951 | /// 952 | /// let mut i = 0; 953 | /// let expected = [1, 2]; 954 | /// for x in &set { 955 | /// assert!(expected.contains(x)); 956 | /// i += 1; 957 | /// } 958 | /// assert_eq!(i, expected.len()); 959 | /// ``` 960 | fn sub(self, rhs: &HashSet) -> HashSet { 961 | self.difference(rhs).cloned().collect() 962 | } 963 | } 964 | 965 | /// An iterator over the items of a `HashSet`. 966 | /// 967 | /// This `struct` is created by the [`iter`] method on [`HashSet`]. 968 | /// See its documentation for more. 969 | /// 970 | /// [`HashSet`]: struct.HashSet.html 971 | /// [`iter`]: struct.HashSet.html#method.iter 972 | pub struct Iter<'a, K: 'a> { 973 | iter: Keys<'a, K, ()>, 974 | } 975 | 976 | /// An owning iterator over the items of a `HashSet`. 977 | /// 978 | /// This `struct` is created by the [`into_iter`] method on [`HashSet`][`HashSet`] 979 | /// (provided by the `IntoIterator` trait). See its documentation for more. 980 | /// 981 | /// [`HashSet`]: struct.HashSet.html 982 | /// [`into_iter`]: struct.HashSet.html#method.into_iter 983 | pub struct IntoIter { 984 | iter: map::IntoIter, 985 | } 986 | 987 | /// A draining iterator over the items of a `HashSet`. 988 | /// 989 | /// This `struct` is created by the [`drain`] method on [`HashSet`]. 990 | /// See its documentation for more. 991 | /// 992 | /// [`HashSet`]: struct.HashSet.html 993 | /// [`drain`]: struct.HashSet.html#method.drain 994 | pub struct Drain<'a, K: 'a> { 995 | iter: map::Drain<'a, K, ()>, 996 | } 997 | 998 | /// A lazy iterator producing elements in the intersection of `HashSet`s. 999 | /// 1000 | /// This `struct` is created by the [`intersection`] method on [`HashSet`]. 1001 | /// See its documentation for more. 1002 | /// 1003 | /// [`HashSet`]: struct.HashSet.html 1004 | /// [`intersection`]: struct.HashSet.html#method.intersection 1005 | pub struct Intersection<'a, T: 'a, S: 'a> { 1006 | // iterator of the first set 1007 | iter: Iter<'a, T>, 1008 | // the second set 1009 | other: &'a HashSet, 1010 | } 1011 | 1012 | /// A lazy iterator producing elements in the difference of `HashSet`s. 1013 | /// 1014 | /// This `struct` is created by the [`difference`] method on [`HashSet`]. 1015 | /// See its documentation for more. 1016 | /// 1017 | /// [`HashSet`]: struct.HashSet.html 1018 | /// [`difference`]: struct.HashSet.html#method.difference 1019 | pub struct Difference<'a, T: 'a, S: 'a> { 1020 | // iterator of the first set 1021 | iter: Iter<'a, T>, 1022 | // the second set 1023 | other: &'a HashSet, 1024 | } 1025 | 1026 | /// A lazy iterator producing elements in the symmetric difference of `HashSet`s. 1027 | /// 1028 | /// This `struct` is created by the [`symmetric_difference`] method on 1029 | /// [`HashSet`]. See its documentation for more. 1030 | /// 1031 | /// [`HashSet`]: struct.HashSet.html 1032 | /// [`symmetric_difference`]: struct.HashSet.html#method.symmetric_difference 1033 | pub struct SymmetricDifference<'a, T: 'a, S: 'a> { 1034 | iter: Chain, Difference<'a, T, S>>, 1035 | } 1036 | 1037 | /// A lazy iterator producing elements in the union of `HashSet`s. 1038 | /// 1039 | /// This `struct` is created by the [`union`] method on [`HashSet`]. 1040 | /// See its documentation for more. 1041 | /// 1042 | /// [`HashSet`]: struct.HashSet.html 1043 | /// [`union`]: struct.HashSet.html#method.union 1044 | pub struct Union<'a, T: 'a, S: 'a> { 1045 | iter: Chain, Difference<'a, T, S>>, 1046 | } 1047 | 1048 | impl<'a, T, S> IntoIterator for &'a HashSet 1049 | where 1050 | T: Eq + Hash, 1051 | S: BuildHasher, 1052 | { 1053 | type Item = &'a T; 1054 | type IntoIter = Iter<'a, T>; 1055 | 1056 | fn into_iter(self) -> Iter<'a, T> { 1057 | self.iter() 1058 | } 1059 | } 1060 | 1061 | impl IntoIterator for HashSet 1062 | where 1063 | T: Eq + Hash, 1064 | S: BuildHasher, 1065 | { 1066 | type Item = T; 1067 | type IntoIter = IntoIter; 1068 | 1069 | /// Creates a consuming iterator, that is, one that moves each value out 1070 | /// of the set in arbitrary order. The set cannot be used after calling 1071 | /// this. 1072 | /// 1073 | /// # Examples 1074 | /// 1075 | /// ``` 1076 | /// use std::collections::HashSet; 1077 | /// let mut set = HashSet::new(); 1078 | /// set.insert("a".to_string()); 1079 | /// set.insert("b".to_string()); 1080 | /// 1081 | /// // Not possible to collect to a Vec with a regular `.iter()`. 1082 | /// let v: Vec = set.into_iter().collect(); 1083 | /// 1084 | /// // Will print in an arbitrary order. 1085 | /// for x in &v { 1086 | /// println!("{}", x); 1087 | /// } 1088 | /// ``` 1089 | fn into_iter(self) -> IntoIter { 1090 | IntoIter { 1091 | iter: self.map.into_iter(), 1092 | } 1093 | } 1094 | } 1095 | 1096 | impl<'a, K> Clone for Iter<'a, K> { 1097 | fn clone(&self) -> Iter<'a, K> { 1098 | Iter { 1099 | iter: self.iter.clone(), 1100 | } 1101 | } 1102 | } 1103 | impl<'a, K> Iterator for Iter<'a, K> { 1104 | type Item = &'a K; 1105 | 1106 | fn next(&mut self) -> Option<&'a K> { 1107 | self.iter.next() 1108 | } 1109 | fn size_hint(&self) -> (usize, Option) { 1110 | self.iter.size_hint() 1111 | } 1112 | } 1113 | impl<'a, K> ExactSizeIterator for Iter<'a, K> { 1114 | fn len(&self) -> usize { 1115 | self.iter.len() 1116 | } 1117 | } 1118 | impl<'a, K> FusedIterator for Iter<'a, K> {} 1119 | 1120 | impl<'a, K: fmt::Debug> fmt::Debug for Iter<'a, K> { 1121 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1122 | f.debug_list().entries(self.clone()).finish() 1123 | } 1124 | } 1125 | 1126 | impl Iterator for IntoIter { 1127 | type Item = K; 1128 | 1129 | fn next(&mut self) -> Option { 1130 | self.iter.next().map(|(k, _)| k) 1131 | } 1132 | fn size_hint(&self) -> (usize, Option) { 1133 | self.iter.size_hint() 1134 | } 1135 | } 1136 | impl ExactSizeIterator for IntoIter { 1137 | fn len(&self) -> usize { 1138 | self.iter.len() 1139 | } 1140 | } 1141 | impl FusedIterator for IntoIter {} 1142 | 1143 | impl fmt::Debug for IntoIter { 1144 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1145 | let entries_iter = self.iter.inner.iter().map(|(k, _)| k); 1146 | f.debug_list().entries(entries_iter).finish() 1147 | } 1148 | } 1149 | 1150 | impl<'a, K> Iterator for Drain<'a, K> { 1151 | type Item = K; 1152 | 1153 | fn next(&mut self) -> Option { 1154 | self.iter.next().map(|(k, _)| k) 1155 | } 1156 | fn size_hint(&self) -> (usize, Option) { 1157 | self.iter.size_hint() 1158 | } 1159 | } 1160 | impl<'a, K> ExactSizeIterator for Drain<'a, K> { 1161 | fn len(&self) -> usize { 1162 | self.iter.len() 1163 | } 1164 | } 1165 | impl<'a, K> FusedIterator for Drain<'a, K> {} 1166 | 1167 | impl<'a, K: fmt::Debug> fmt::Debug for Drain<'a, K> { 1168 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1169 | let entries_iter = self.iter.inner.iter().map(|(k, _)| k); 1170 | f.debug_list().entries(entries_iter).finish() 1171 | } 1172 | } 1173 | 1174 | impl<'a, T, S> Clone for Intersection<'a, T, S> { 1175 | fn clone(&self) -> Intersection<'a, T, S> { 1176 | Intersection { 1177 | iter: self.iter.clone(), 1178 | ..*self 1179 | } 1180 | } 1181 | } 1182 | 1183 | impl<'a, T, S> Iterator for Intersection<'a, T, S> 1184 | where 1185 | T: Eq + Hash, 1186 | S: BuildHasher, 1187 | { 1188 | type Item = &'a T; 1189 | 1190 | fn next(&mut self) -> Option<&'a T> { 1191 | loop { 1192 | let elt = self.iter.next()?; 1193 | if self.other.contains(elt) { 1194 | return Some(elt); 1195 | } 1196 | } 1197 | } 1198 | 1199 | fn size_hint(&self) -> (usize, Option) { 1200 | let (_, upper) = self.iter.size_hint(); 1201 | (0, upper) 1202 | } 1203 | } 1204 | 1205 | impl<'a, T, S> fmt::Debug for Intersection<'a, T, S> 1206 | where 1207 | T: fmt::Debug + Eq + Hash, 1208 | S: BuildHasher, 1209 | { 1210 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1211 | f.debug_list().entries(self.clone()).finish() 1212 | } 1213 | } 1214 | 1215 | impl<'a, T, S> FusedIterator for Intersection<'a, T, S> 1216 | where 1217 | T: Eq + Hash, 1218 | S: BuildHasher, 1219 | { 1220 | } 1221 | 1222 | impl<'a, T, S> Clone for Difference<'a, T, S> { 1223 | fn clone(&self) -> Difference<'a, T, S> { 1224 | Difference { 1225 | iter: self.iter.clone(), 1226 | ..*self 1227 | } 1228 | } 1229 | } 1230 | 1231 | impl<'a, T, S> Iterator for Difference<'a, T, S> 1232 | where 1233 | T: Eq + Hash, 1234 | S: BuildHasher, 1235 | { 1236 | type Item = &'a T; 1237 | 1238 | fn next(&mut self) -> Option<&'a T> { 1239 | loop { 1240 | let elt = self.iter.next()?; 1241 | if !self.other.contains(elt) { 1242 | return Some(elt); 1243 | } 1244 | } 1245 | } 1246 | 1247 | fn size_hint(&self) -> (usize, Option) { 1248 | let (_, upper) = self.iter.size_hint(); 1249 | (0, upper) 1250 | } 1251 | } 1252 | 1253 | impl<'a, T, S> FusedIterator for Difference<'a, T, S> 1254 | where 1255 | T: Eq + Hash, 1256 | S: BuildHasher, 1257 | { 1258 | } 1259 | 1260 | impl<'a, T, S> fmt::Debug for Difference<'a, T, S> 1261 | where 1262 | T: fmt::Debug + Eq + Hash, 1263 | S: BuildHasher, 1264 | { 1265 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1266 | f.debug_list().entries(self.clone()).finish() 1267 | } 1268 | } 1269 | 1270 | impl<'a, T, S> Clone for SymmetricDifference<'a, T, S> { 1271 | fn clone(&self) -> SymmetricDifference<'a, T, S> { 1272 | SymmetricDifference { 1273 | iter: self.iter.clone(), 1274 | } 1275 | } 1276 | } 1277 | 1278 | impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S> 1279 | where 1280 | T: Eq + Hash, 1281 | S: BuildHasher, 1282 | { 1283 | type Item = &'a T; 1284 | 1285 | fn next(&mut self) -> Option<&'a T> { 1286 | self.iter.next() 1287 | } 1288 | fn size_hint(&self) -> (usize, Option) { 1289 | self.iter.size_hint() 1290 | } 1291 | } 1292 | 1293 | impl<'a, T, S> FusedIterator for SymmetricDifference<'a, T, S> 1294 | where 1295 | T: Eq + Hash, 1296 | S: BuildHasher, 1297 | { 1298 | } 1299 | 1300 | impl<'a, T, S> fmt::Debug for SymmetricDifference<'a, T, S> 1301 | where 1302 | T: fmt::Debug + Eq + Hash, 1303 | S: BuildHasher, 1304 | { 1305 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1306 | f.debug_list().entries(self.clone()).finish() 1307 | } 1308 | } 1309 | 1310 | impl<'a, T, S> Clone for Union<'a, T, S> { 1311 | fn clone(&self) -> Union<'a, T, S> { 1312 | Union { 1313 | iter: self.iter.clone(), 1314 | } 1315 | } 1316 | } 1317 | 1318 | impl<'a, T, S> FusedIterator for Union<'a, T, S> 1319 | where 1320 | T: Eq + Hash, 1321 | S: BuildHasher, 1322 | { 1323 | } 1324 | 1325 | impl<'a, T, S> fmt::Debug for Union<'a, T, S> 1326 | where 1327 | T: fmt::Debug + Eq + Hash, 1328 | S: BuildHasher, 1329 | { 1330 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1331 | f.debug_list().entries(self.clone()).finish() 1332 | } 1333 | } 1334 | 1335 | impl<'a, T, S> Iterator for Union<'a, T, S> 1336 | where 1337 | T: Eq + Hash, 1338 | S: BuildHasher, 1339 | { 1340 | type Item = &'a T; 1341 | 1342 | fn next(&mut self) -> Option<&'a T> { 1343 | self.iter.next() 1344 | } 1345 | fn size_hint(&self) -> (usize, Option) { 1346 | self.iter.size_hint() 1347 | } 1348 | } 1349 | 1350 | #[allow(dead_code)] 1351 | fn assert_covariance() { 1352 | fn set<'new>(v: HashSet<&'static str>) -> HashSet<&'new str> { 1353 | v 1354 | } 1355 | fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> { 1356 | v 1357 | } 1358 | fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> { 1359 | v 1360 | } 1361 | fn difference<'a, 'new>( 1362 | v: Difference<'a, &'static str, RandomState>, 1363 | ) -> Difference<'a, &'new str, RandomState> { 1364 | v 1365 | } 1366 | fn symmetric_difference<'a, 'new>( 1367 | v: SymmetricDifference<'a, &'static str, RandomState>, 1368 | ) -> SymmetricDifference<'a, &'new str, RandomState> { 1369 | v 1370 | } 1371 | fn intersection<'a, 'new>( 1372 | v: Intersection<'a, &'static str, RandomState>, 1373 | ) -> Intersection<'a, &'new str, RandomState> { 1374 | v 1375 | } 1376 | fn union<'a, 'new>( 1377 | v: Union<'a, &'static str, RandomState>, 1378 | ) -> Union<'a, &'new str, RandomState> { 1379 | v 1380 | } 1381 | fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { 1382 | d 1383 | } 1384 | } 1385 | -------------------------------------------------------------------------------- /src/table.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | use alloc::{handle_alloc_error, Alloc, Global, Layout, LayoutErr}; 12 | use collections::CollectionAllocErr; 13 | use core::hash::{BuildHasher, Hash, Hasher}; 14 | use core::hint; 15 | use core::marker; 16 | use core::mem; 17 | use core::mem::{needs_drop, size_of}; 18 | use core::ops::{Deref, DerefMut}; 19 | use core::ptr::{self, NonNull, Unique}; 20 | 21 | use self::BucketState::*; 22 | 23 | /// Integer type used for stored hash values. 24 | /// 25 | /// No more than bit_width(usize) bits are needed to select a bucket. 26 | /// 27 | /// The most significant bit is ours to use for tagging `SafeHash`. 28 | /// 29 | /// (Even if we could have usize::MAX bytes allocated for buckets, 30 | /// each bucket stores at least a `HashUint`, so there can be no more than 31 | /// usize::MAX / size_of(usize) buckets.) 32 | type HashUint = usize; 33 | 34 | const EMPTY_BUCKET: HashUint = 0; 35 | const EMPTY: usize = 1; 36 | 37 | /// Special `Unique` that uses the lower bit of the pointer 38 | /// to expose a boolean tag. 39 | /// Note: when the pointer is initialized to EMPTY `.ptr()` will return 40 | /// null and the tag functions shouldn't be used. 41 | struct TaggedHashUintPtr(Unique); 42 | 43 | impl TaggedHashUintPtr { 44 | #[inline] 45 | unsafe fn new(ptr: *mut HashUint) -> Self { 46 | debug_assert!(ptr as usize & 1 == 0 || ptr as usize == EMPTY as usize); 47 | TaggedHashUintPtr(Unique::new_unchecked(ptr)) 48 | } 49 | 50 | #[inline] 51 | fn set_tag(&mut self, value: bool) { 52 | let mut usize_ptr = self.0.as_ptr() as usize; 53 | unsafe { 54 | if value { 55 | usize_ptr |= 1; 56 | } else { 57 | usize_ptr &= !1; 58 | } 59 | self.0 = Unique::new_unchecked(usize_ptr as *mut HashUint) 60 | } 61 | } 62 | 63 | #[inline] 64 | fn tag(&self) -> bool { 65 | (self.0.as_ptr() as usize) & 1 == 1 66 | } 67 | 68 | #[inline] 69 | fn ptr(&self) -> *mut HashUint { 70 | (self.0.as_ptr() as usize & !1) as *mut HashUint 71 | } 72 | } 73 | 74 | /// The raw hashtable, providing safe-ish access to the unzipped and highly 75 | /// optimized arrays of hashes, and key-value pairs. 76 | /// 77 | /// This design is a lot faster than the naive 78 | /// `Vec>`, because we don't pay for the overhead of an 79 | /// option on every element, and we get a generally more cache-aware design. 80 | /// 81 | /// Essential invariants of this structure: 82 | /// 83 | /// - if t.hashes[i] == EMPTY_BUCKET, then `Bucket::at_index(&t, i).raw` 84 | /// points to 'undefined' contents. Don't read from it. This invariant is 85 | /// enforced outside this module with the `EmptyBucket`, `FullBucket`, 86 | /// and `SafeHash` types. 87 | /// 88 | /// - An `EmptyBucket` is only constructed at an index with 89 | /// a hash of EMPTY_BUCKET. 90 | /// 91 | /// - A `FullBucket` is only constructed at an index with a 92 | /// non-EMPTY_BUCKET hash. 93 | /// 94 | /// - A `SafeHash` is only constructed for non-`EMPTY_BUCKET` hash. We get 95 | /// around hashes of zero by changing them to 0x8000_0000_0000_0000, 96 | /// which will likely map to the same bucket, while not being confused 97 | /// with "empty". 98 | /// 99 | /// - Both "arrays represented by pointers" are the same length: 100 | /// `capacity`. This is set at creation and never changes. The arrays 101 | /// are unzipped and are more cache aware (scanning through 8 hashes 102 | /// brings in at most 2 cache lines, since they're all right beside each 103 | /// other). This layout may waste space in padding such as in a map from 104 | /// u64 to u8, but is a more cache conscious layout as the key-value pairs 105 | /// are only very shortly probed and the desired value will be in the same 106 | /// or next cache line. 107 | /// 108 | /// You can kind of think of this module/data structure as a safe wrapper 109 | /// around just the "table" part of the hashtable. It enforces some 110 | /// invariants at the type level and employs some performance trickery, 111 | /// but in general is just a tricked out `Vec>`. 112 | /// 113 | /// The hashtable also exposes a special boolean tag. The tag defaults to false 114 | /// when the RawTable is created and is accessible with the `tag` and `set_tag` 115 | /// functions. 116 | pub struct RawTable { 117 | capacity_mask: usize, 118 | size: usize, 119 | hashes: TaggedHashUintPtr, 120 | 121 | // Because K/V do not appear directly in any of the types in the struct, 122 | // inform rustc that in fact instances of K and V are reachable from here. 123 | marker: marker::PhantomData<(K, V)>, 124 | } 125 | 126 | // An unsafe view of a RawTable bucket 127 | // Valid indexes are within [0..table_capacity) 128 | pub struct RawBucket { 129 | hash_start: *mut HashUint, 130 | // We use *const to ensure covariance with respect to K and V 131 | pair_start: *const (K, V), 132 | idx: usize, 133 | _marker: marker::PhantomData<(K, V)>, 134 | } 135 | 136 | impl Copy for RawBucket {} 137 | impl Clone for RawBucket { 138 | fn clone(&self) -> RawBucket { 139 | *self 140 | } 141 | } 142 | 143 | pub struct Bucket { 144 | raw: RawBucket, 145 | table: M, 146 | } 147 | 148 | impl Copy for Bucket {} 149 | impl Clone for Bucket { 150 | fn clone(&self) -> Bucket { 151 | *self 152 | } 153 | } 154 | 155 | pub struct EmptyBucket { 156 | raw: RawBucket, 157 | table: M, 158 | } 159 | 160 | pub struct FullBucket { 161 | raw: RawBucket, 162 | table: M, 163 | } 164 | 165 | pub type FullBucketMut<'table, K, V> = FullBucket>; 166 | 167 | pub enum BucketState { 168 | Empty(EmptyBucket), 169 | Full(FullBucket), 170 | } 171 | 172 | // A GapThenFull encapsulates the state of two consecutive buckets at once. 173 | // The first bucket, called the gap, is known to be empty. 174 | // The second bucket is full. 175 | pub struct GapThenFull { 176 | gap: EmptyBucket, 177 | full: FullBucket, 178 | } 179 | 180 | /// A hash that is not zero, since we use a hash of zero to represent empty 181 | /// buckets. 182 | #[derive(PartialEq, Copy, Clone)] 183 | pub struct SafeHash { 184 | hash: HashUint, 185 | } 186 | 187 | impl SafeHash { 188 | /// Peek at the hash value, which is guaranteed to be non-zero. 189 | #[inline(always)] 190 | pub fn inspect(&self) -> HashUint { 191 | self.hash 192 | } 193 | 194 | #[inline(always)] 195 | pub fn new(hash: u64) -> Self { 196 | // We need to avoid 0 in order to prevent collisions with 197 | // EMPTY_HASH. We can maintain our precious uniform distribution 198 | // of initial indexes by unconditionally setting the MSB, 199 | // effectively reducing the hashes by one bit. 200 | // 201 | // Truncate hash to fit in `HashUint`. 202 | let hash_bits = size_of::() * 8; 203 | SafeHash { 204 | hash: (1 << (hash_bits - 1)) | (hash as HashUint), 205 | } 206 | } 207 | } 208 | 209 | /// We need to remove hashes of 0. That's reserved for empty buckets. 210 | /// This function wraps up `hash_keyed` to be the only way outside this 211 | /// module to generate a SafeHash. 212 | pub fn make_hash(hash_state: &S, t: &T) -> SafeHash 213 | where 214 | T: Hash, 215 | S: BuildHasher, 216 | { 217 | let mut state = hash_state.build_hasher(); 218 | t.hash(&mut state); 219 | SafeHash::new(state.finish()) 220 | } 221 | 222 | // `replace` casts a `*HashUint` to a `*SafeHash`. Since we statically 223 | // ensure that a `FullBucket` points to an index with a non-zero hash, 224 | // and a `SafeHash` is just a `HashUint` with a different name, this is 225 | // safe. 226 | // 227 | // This test ensures that a `SafeHash` really IS the same size as a 228 | // `HashUint`. If you need to change the size of `SafeHash` (and 229 | // consequently made this test fail), `replace` needs to be 230 | // modified to no longer assume this. 231 | #[test] 232 | fn can_alias_safehash_as_hash() { 233 | assert_eq!(size_of::(), size_of::()) 234 | } 235 | 236 | // RawBucket methods are unsafe as it's possible to 237 | // make a RawBucket point to invalid memory using safe code. 238 | impl RawBucket { 239 | unsafe fn hash(&self) -> *mut HashUint { 240 | self.hash_start.offset(self.idx as isize) 241 | } 242 | unsafe fn pair(&self) -> *mut (K, V) { 243 | self.pair_start.offset(self.idx as isize) as *mut (K, V) 244 | } 245 | unsafe fn hash_pair(&self) -> (*mut HashUint, *mut (K, V)) { 246 | (self.hash(), self.pair()) 247 | } 248 | } 249 | 250 | // Buckets hold references to the table. 251 | impl FullBucket { 252 | /// Borrow a reference to the table. 253 | pub fn table(&self) -> &M { 254 | &self.table 255 | } 256 | /// Borrow a mutable reference to the table. 257 | pub fn table_mut(&mut self) -> &mut M { 258 | &mut self.table 259 | } 260 | /// Move out the reference to the table. 261 | pub fn into_table(self) -> M { 262 | self.table 263 | } 264 | /// Get the raw index. 265 | pub fn index(&self) -> usize { 266 | self.raw.idx 267 | } 268 | /// Get the raw bucket. 269 | pub fn raw(&self) -> RawBucket { 270 | self.raw 271 | } 272 | } 273 | 274 | impl EmptyBucket { 275 | /// Borrow a reference to the table. 276 | pub fn table(&self) -> &M { 277 | &self.table 278 | } 279 | /// Borrow a mutable reference to the table. 280 | pub fn table_mut(&mut self) -> &mut M { 281 | &mut self.table 282 | } 283 | } 284 | 285 | impl Bucket { 286 | /// Get the raw index. 287 | pub fn index(&self) -> usize { 288 | self.raw.idx 289 | } 290 | /// get the table. 291 | pub fn into_table(self) -> M { 292 | self.table 293 | } 294 | } 295 | 296 | impl Deref for FullBucket 297 | where 298 | M: Deref>, 299 | { 300 | type Target = RawTable; 301 | fn deref(&self) -> &RawTable { 302 | &self.table 303 | } 304 | } 305 | 306 | /// `Put` is implemented for types which provide access to a table and cannot be invalidated 307 | /// by filling a bucket. A similar implementation for `Take` is possible. 308 | pub trait Put { 309 | unsafe fn borrow_table_mut(&mut self) -> &mut RawTable; 310 | } 311 | 312 | impl<'t, K, V> Put for &'t mut RawTable { 313 | unsafe fn borrow_table_mut(&mut self) -> &mut RawTable { 314 | *self 315 | } 316 | } 317 | 318 | impl Put for Bucket 319 | where 320 | M: Put, 321 | { 322 | unsafe fn borrow_table_mut(&mut self) -> &mut RawTable { 323 | self.table.borrow_table_mut() 324 | } 325 | } 326 | 327 | impl Put for FullBucket 328 | where 329 | M: Put, 330 | { 331 | unsafe fn borrow_table_mut(&mut self) -> &mut RawTable { 332 | self.table.borrow_table_mut() 333 | } 334 | } 335 | 336 | impl>> Bucket { 337 | pub fn new(table: M, hash: SafeHash) -> Bucket { 338 | Bucket::at_index(table, hash.inspect() as usize) 339 | } 340 | 341 | pub fn new_from(r: RawBucket, t: M) -> Bucket { 342 | Bucket { raw: r, table: t } 343 | } 344 | 345 | pub fn at_index(table: M, ib_index: usize) -> Bucket { 346 | // if capacity is 0, then the RawBucket will be populated with bogus pointers. 347 | // This is an uncommon case though, so avoid it in release builds. 348 | debug_assert!( 349 | table.capacity() > 0, 350 | "Table should have capacity at this point" 351 | ); 352 | let ib_index = ib_index & table.capacity_mask; 353 | Bucket { 354 | raw: table.raw_bucket_at(ib_index), 355 | table, 356 | } 357 | } 358 | 359 | pub fn first(table: M) -> Bucket { 360 | Bucket { 361 | raw: table.raw_bucket_at(0), 362 | table, 363 | } 364 | } 365 | 366 | // "So a few of the first shall be last: for many be called, 367 | // but few chosen." 368 | // 369 | // We'll most likely encounter a few buckets at the beginning that 370 | // have their initial buckets near the end of the table. They were 371 | // placed at the beginning as the probe wrapped around the table 372 | // during insertion. We must skip forward to a bucket that won't 373 | // get reinserted too early and won't unfairly steal others spot. 374 | // This eliminates the need for robin hood. 375 | pub fn head_bucket(table: M) -> Bucket { 376 | let mut bucket = Bucket::first(table); 377 | 378 | loop { 379 | bucket = match bucket.peek() { 380 | Full(full) => { 381 | if full.displacement() == 0 { 382 | // This bucket occupies its ideal spot. 383 | // It indicates the start of another "cluster". 384 | bucket = full.into_bucket(); 385 | break; 386 | } 387 | // Leaving this bucket in the last cluster for later. 388 | full.into_bucket() 389 | } 390 | Empty(b) => { 391 | // Encountered a hole between clusters. 392 | b.into_bucket() 393 | } 394 | }; 395 | bucket.next(); 396 | } 397 | bucket 398 | } 399 | 400 | /// Reads a bucket at a given index, returning an enum indicating whether 401 | /// it's initialized or not. You need to match on this enum to get 402 | /// the appropriate types to call most of the other functions in 403 | /// this module. 404 | pub fn peek(self) -> BucketState { 405 | match unsafe { *self.raw.hash() } { 406 | EMPTY_BUCKET => Empty(EmptyBucket { 407 | raw: self.raw, 408 | table: self.table, 409 | }), 410 | _ => Full(FullBucket { 411 | raw: self.raw, 412 | table: self.table, 413 | }), 414 | } 415 | } 416 | 417 | /// Modifies the bucket in place to make it point to the next slot. 418 | pub fn next(&mut self) { 419 | self.raw.idx = self.raw.idx.wrapping_add(1) & self.table.capacity_mask; 420 | } 421 | 422 | /// Modifies the bucket in place to make it point to the previous slot. 423 | pub fn prev(&mut self) { 424 | self.raw.idx = self.raw.idx.wrapping_sub(1) & self.table.capacity_mask; 425 | } 426 | } 427 | 428 | impl>> EmptyBucket { 429 | #[inline] 430 | pub fn next(self) -> Bucket { 431 | let mut bucket = self.into_bucket(); 432 | bucket.next(); 433 | bucket 434 | } 435 | 436 | #[inline] 437 | pub fn into_bucket(self) -> Bucket { 438 | Bucket { 439 | raw: self.raw, 440 | table: self.table, 441 | } 442 | } 443 | 444 | pub fn gap_peek(self) -> Result, Bucket> { 445 | let gap = EmptyBucket { 446 | raw: self.raw, 447 | table: (), 448 | }; 449 | 450 | match self.next().peek() { 451 | Full(bucket) => Ok(GapThenFull { gap, full: bucket }), 452 | Empty(e) => Err(e.into_bucket()), 453 | } 454 | } 455 | } 456 | 457 | impl EmptyBucket 458 | where 459 | M: Put, 460 | { 461 | /// Puts given key and value pair, along with the key's hash, 462 | /// into this bucket in the hashtable. Note how `self` is 'moved' into 463 | /// this function, because this slot will no longer be empty when 464 | /// we return! A `FullBucket` is returned for later use, pointing to 465 | /// the newly-filled slot in the hashtable. 466 | /// 467 | /// Use `make_hash` to construct a `SafeHash` to pass to this function. 468 | pub fn put(mut self, hash: SafeHash, key: K, value: V) -> FullBucket { 469 | unsafe { 470 | *self.raw.hash() = hash.inspect(); 471 | ptr::write(self.raw.pair(), (key, value)); 472 | 473 | self.table.borrow_table_mut().size += 1; 474 | } 475 | 476 | FullBucket { 477 | raw: self.raw, 478 | table: self.table, 479 | } 480 | } 481 | } 482 | 483 | impl>> FullBucket { 484 | #[inline] 485 | pub fn next(self) -> Bucket { 486 | let mut bucket = self.into_bucket(); 487 | bucket.next(); 488 | bucket 489 | } 490 | 491 | #[inline] 492 | pub fn into_bucket(self) -> Bucket { 493 | Bucket { 494 | raw: self.raw, 495 | table: self.table, 496 | } 497 | } 498 | 499 | /// Duplicates the current position. This can be useful for operations 500 | /// on two or more buckets. 501 | pub fn stash(self) -> FullBucket { 502 | FullBucket { 503 | raw: self.raw, 504 | table: self, 505 | } 506 | } 507 | 508 | /// Get the distance between this bucket and the 'ideal' location 509 | /// as determined by the key's hash stored in it. 510 | /// 511 | /// In the cited blog posts above, this is called the "distance to 512 | /// initial bucket", or DIB. Also known as "probe count". 513 | pub fn displacement(&self) -> usize { 514 | // Calculates the distance one has to travel when going from 515 | // `hash mod capacity` onwards to `idx mod capacity`, wrapping around 516 | // if the destination is not reached before the end of the table. 517 | (self.raw.idx.wrapping_sub(self.hash().inspect() as usize)) & self.table.capacity_mask 518 | } 519 | 520 | #[inline] 521 | pub fn hash(&self) -> SafeHash { 522 | unsafe { 523 | SafeHash { 524 | hash: *self.raw.hash(), 525 | } 526 | } 527 | } 528 | 529 | /// Gets references to the key and value at a given index. 530 | pub fn read(&self) -> (&K, &V) { 531 | unsafe { 532 | let pair_ptr = self.raw.pair(); 533 | (&(*pair_ptr).0, &(*pair_ptr).1) 534 | } 535 | } 536 | } 537 | 538 | // We take a mutable reference to the table instead of accepting anything that 539 | // implements `DerefMut` to prevent fn `take` from being called on `stash`ed 540 | // buckets. 541 | impl<'t, K, V> FullBucket> { 542 | /// Removes this bucket's key and value from the hashtable. 543 | /// 544 | /// This works similarly to `put`, building an `EmptyBucket` out of the 545 | /// taken bucket. 546 | pub fn take(self) -> (EmptyBucket>, K, V) { 547 | self.table.size -= 1; 548 | 549 | unsafe { 550 | *self.raw.hash() = EMPTY_BUCKET; 551 | let (k, v) = ptr::read(self.raw.pair()); 552 | ( 553 | EmptyBucket { 554 | raw: self.raw, 555 | table: self.table, 556 | }, 557 | k, 558 | v, 559 | ) 560 | } 561 | } 562 | } 563 | 564 | // This use of `Put` is misleading and restrictive, but safe and sufficient for our use cases 565 | // where `M` is a full bucket or table reference type with mutable access to the table. 566 | impl FullBucket 567 | where 568 | M: Put, 569 | { 570 | pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) { 571 | unsafe { 572 | let old_hash = ptr::replace(self.raw.hash() as *mut SafeHash, h); 573 | let (old_key, old_val) = ptr::replace(self.raw.pair(), (k, v)); 574 | 575 | (old_hash, old_key, old_val) 576 | } 577 | } 578 | } 579 | 580 | impl FullBucket 581 | where 582 | M: Deref> + DerefMut, 583 | { 584 | /// Gets mutable references to the key and value at a given index. 585 | pub fn read_mut(&mut self) -> (&mut K, &mut V) { 586 | unsafe { 587 | let pair_ptr = self.raw.pair(); 588 | (&mut (*pair_ptr).0, &mut (*pair_ptr).1) 589 | } 590 | } 591 | } 592 | 593 | impl<'t, K, V, M> FullBucket 594 | where 595 | M: Deref> + 't, 596 | { 597 | /// Exchange a bucket state for immutable references into the table. 598 | /// Because the underlying reference to the table is also consumed, 599 | /// no further changes to the structure of the table are possible; 600 | /// in exchange for this, the returned references have a longer lifetime 601 | /// than the references returned by `read()`. 602 | pub fn into_refs(self) -> (&'t K, &'t V) { 603 | unsafe { 604 | let pair_ptr = self.raw.pair(); 605 | (&(*pair_ptr).0, &(*pair_ptr).1) 606 | } 607 | } 608 | } 609 | 610 | impl<'t, K, V, M> FullBucket 611 | where 612 | M: Deref> + DerefMut + 't, 613 | { 614 | /// This works similarly to `into_refs`, exchanging a bucket state 615 | /// for mutable references into the table. 616 | pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) { 617 | unsafe { 618 | let pair_ptr = self.raw.pair(); 619 | (&mut (*pair_ptr).0, &mut (*pair_ptr).1) 620 | } 621 | } 622 | } 623 | 624 | impl GapThenFull 625 | where 626 | M: Deref>, 627 | { 628 | #[inline] 629 | pub fn full(&self) -> &FullBucket { 630 | &self.full 631 | } 632 | 633 | pub fn into_table(self) -> M { 634 | self.full.into_table() 635 | } 636 | 637 | pub fn shift(mut self) -> Result, Bucket> { 638 | unsafe { 639 | let (gap_hash, gap_pair) = self.gap.raw.hash_pair(); 640 | let (full_hash, full_pair) = self.full.raw.hash_pair(); 641 | *gap_hash = mem::replace(&mut *full_hash, EMPTY_BUCKET); 642 | ptr::copy_nonoverlapping(full_pair, gap_pair, 1); 643 | } 644 | 645 | let FullBucket { raw: prev_raw, .. } = self.full; 646 | 647 | match self.full.next().peek() { 648 | Full(bucket) => { 649 | self.gap.raw = prev_raw; 650 | 651 | self.full = bucket; 652 | 653 | Ok(self) 654 | } 655 | Empty(b) => Err(b.into_bucket()), 656 | } 657 | } 658 | } 659 | 660 | // Returns a Layout which describes the allocation required for a hash table, 661 | // and the offset of the array of (key, value) pairs in the allocation. 662 | fn calculate_layout(capacity: usize) -> Result<(Layout, usize), LayoutErr> { 663 | let hashes = Layout::array::(capacity)?; 664 | let pairs = Layout::array::<(K, V)>(capacity)?; 665 | hashes.extend(pairs).map(|(layout, _)| { 666 | // LLVM seems to have trouble properly const-propagating pairs.align(), 667 | // possibly due to the use of NonZeroUsize. This little hack allows it 668 | // to generate optimal code. 669 | // 670 | // See https://github.com/rust-lang/rust/issues/51346 for more details. 671 | ( 672 | layout, 673 | hashes.size() + hashes.padding_needed_for(mem::align_of::<(K, V)>()), 674 | ) 675 | }) 676 | } 677 | 678 | pub(crate) enum Fallibility { 679 | Fallible, 680 | Infallible, 681 | } 682 | 683 | use self::Fallibility::*; 684 | 685 | impl RawTable { 686 | /// Does not initialize the buckets. The caller should ensure they, 687 | /// at the very least, set every hash to EMPTY_BUCKET. 688 | /// Returns an error if it cannot allocate or capacity overflows. 689 | unsafe fn new_uninitialized_internal( 690 | capacity: usize, 691 | fallibility: Fallibility, 692 | ) -> Result, CollectionAllocErr> { 693 | if capacity == 0 { 694 | return Ok(RawTable { 695 | size: 0, 696 | capacity_mask: capacity.wrapping_sub(1), 697 | hashes: TaggedHashUintPtr::new(EMPTY as *mut HashUint), 698 | marker: marker::PhantomData, 699 | }); 700 | } 701 | 702 | // Allocating hashmaps is a little tricky. We need to allocate two 703 | // arrays, but since we know their sizes and alignments up front, 704 | // we just allocate a single array, and then have the subarrays 705 | // point into it. 706 | let (layout, _) = calculate_layout::(capacity)?; 707 | let buffer = Global.alloc(layout).map_err(|e| match fallibility { 708 | Infallible => handle_alloc_error(layout), 709 | Fallible => e, 710 | })?; 711 | 712 | Ok(RawTable { 713 | capacity_mask: capacity.wrapping_sub(1), 714 | size: 0, 715 | hashes: TaggedHashUintPtr::new(buffer.cast().as_ptr()), 716 | marker: marker::PhantomData, 717 | }) 718 | } 719 | 720 | /// Does not initialize the buckets. The caller should ensure they, 721 | /// at the very least, set every hash to EMPTY_BUCKET. 722 | unsafe fn new_uninitialized(capacity: usize) -> RawTable { 723 | match Self::new_uninitialized_internal(capacity, Infallible) { 724 | Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"), 725 | Err(CollectionAllocErr::AllocErr) => unreachable!(), 726 | Ok(table) => table, 727 | } 728 | } 729 | 730 | fn raw_bucket_at(&self, index: usize) -> RawBucket { 731 | let (_, pairs_offset) = calculate_layout::(self.capacity()) 732 | .unwrap_or_else(|_| unsafe { hint::unreachable_unchecked() }); 733 | let buffer = self.hashes.ptr() as *mut u8; 734 | unsafe { 735 | RawBucket { 736 | hash_start: buffer as *mut HashUint, 737 | pair_start: buffer.add(pairs_offset) as *const (K, V), 738 | idx: index, 739 | _marker: marker::PhantomData, 740 | } 741 | } 742 | } 743 | 744 | fn new_internal( 745 | capacity: usize, 746 | fallibility: Fallibility, 747 | ) -> Result, CollectionAllocErr> { 748 | unsafe { 749 | let ret = RawTable::new_uninitialized_internal(capacity, fallibility)?; 750 | ptr::write_bytes(ret.hashes.ptr(), 0, capacity); 751 | Ok(ret) 752 | } 753 | } 754 | 755 | /// Tries to create a new raw table from a given capacity. If it cannot allocate, 756 | /// it returns with AllocErr. 757 | pub fn try_new(capacity: usize) -> Result, CollectionAllocErr> { 758 | Self::new_internal(capacity, Fallible) 759 | } 760 | 761 | /// Creates a new raw table from a given capacity. All buckets are 762 | /// initially empty. 763 | pub fn new(capacity: usize) -> RawTable { 764 | match Self::new_internal(capacity, Infallible) { 765 | Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"), 766 | Err(CollectionAllocErr::AllocErr) => unreachable!(), 767 | Ok(table) => table, 768 | } 769 | } 770 | 771 | /// The hashtable's capacity, similar to a vector's. 772 | pub fn capacity(&self) -> usize { 773 | self.capacity_mask.wrapping_add(1) 774 | } 775 | 776 | /// The number of elements ever `put` in the hashtable, minus the number 777 | /// of elements ever `take`n. 778 | pub fn size(&self) -> usize { 779 | self.size 780 | } 781 | 782 | fn raw_buckets(&self) -> RawBuckets { 783 | RawBuckets { 784 | raw: self.raw_bucket_at(0), 785 | elems_left: self.size, 786 | marker: marker::PhantomData, 787 | } 788 | } 789 | 790 | pub fn iter(&self) -> Iter { 791 | Iter { 792 | iter: self.raw_buckets(), 793 | } 794 | } 795 | 796 | pub fn iter_mut(&mut self) -> IterMut { 797 | IterMut { 798 | iter: self.raw_buckets(), 799 | _marker: marker::PhantomData, 800 | } 801 | } 802 | 803 | pub fn into_iter(self) -> IntoIter { 804 | let RawBuckets { 805 | raw, elems_left, .. 806 | } = self.raw_buckets(); 807 | // Replace the marker regardless of lifetime bounds on parameters. 808 | IntoIter { 809 | iter: RawBuckets { 810 | raw, 811 | elems_left, 812 | marker: marker::PhantomData, 813 | }, 814 | table: self, 815 | } 816 | } 817 | 818 | pub fn drain(&mut self) -> Drain { 819 | let RawBuckets { 820 | raw, elems_left, .. 821 | } = self.raw_buckets(); 822 | // Replace the marker regardless of lifetime bounds on parameters. 823 | Drain { 824 | iter: RawBuckets { 825 | raw, 826 | elems_left, 827 | marker: marker::PhantomData, 828 | }, 829 | table: NonNull::from(self), 830 | marker: marker::PhantomData, 831 | } 832 | } 833 | 834 | /// Drops buckets in reverse order. It leaves the table in an inconsistent 835 | /// state and should only be used for dropping the table's remaining 836 | /// entries. It's used in the implementation of Drop. 837 | unsafe fn rev_drop_buckets(&mut self) { 838 | // initialize the raw bucket past the end of the table 839 | let mut raw = self.raw_bucket_at(self.capacity()); 840 | let mut elems_left = self.size; 841 | 842 | while elems_left != 0 { 843 | raw.idx -= 1; 844 | 845 | if *raw.hash() != EMPTY_BUCKET { 846 | elems_left -= 1; 847 | ptr::drop_in_place(raw.pair()); 848 | } 849 | } 850 | } 851 | 852 | /// Set the table tag 853 | pub fn set_tag(&mut self, value: bool) { 854 | self.hashes.set_tag(value) 855 | } 856 | 857 | /// Get the table tag 858 | pub fn tag(&self) -> bool { 859 | self.hashes.tag() 860 | } 861 | } 862 | 863 | /// A raw iterator. The basis for some other iterators in this module. Although 864 | /// this interface is safe, it's not used outside this module. 865 | struct RawBuckets<'a, K, V> { 866 | raw: RawBucket, 867 | elems_left: usize, 868 | 869 | // Strictly speaking, this should be &'a (K,V), but that would 870 | // require that K:'a, and we often use RawBuckets<'static...> for 871 | // move iterations, so that messes up a lot of other things. So 872 | // just use `&'a (K,V)` as this is not a publicly exposed type 873 | // anyway. 874 | marker: marker::PhantomData<&'a ()>, 875 | } 876 | 877 | // FIXME(#26925) Remove in favor of `#[derive(Clone)]` 878 | impl<'a, K, V> Clone for RawBuckets<'a, K, V> { 879 | fn clone(&self) -> RawBuckets<'a, K, V> { 880 | RawBuckets { 881 | raw: self.raw, 882 | elems_left: self.elems_left, 883 | marker: marker::PhantomData, 884 | } 885 | } 886 | } 887 | 888 | impl<'a, K, V> Iterator for RawBuckets<'a, K, V> { 889 | type Item = RawBucket; 890 | 891 | fn next(&mut self) -> Option> { 892 | if self.elems_left == 0 { 893 | return None; 894 | } 895 | 896 | loop { 897 | unsafe { 898 | let item = self.raw; 899 | self.raw.idx += 1; 900 | if *item.hash() != EMPTY_BUCKET { 901 | self.elems_left -= 1; 902 | return Some(item); 903 | } 904 | } 905 | } 906 | } 907 | 908 | fn size_hint(&self) -> (usize, Option) { 909 | (self.elems_left, Some(self.elems_left)) 910 | } 911 | } 912 | 913 | impl<'a, K, V> ExactSizeIterator for RawBuckets<'a, K, V> { 914 | fn len(&self) -> usize { 915 | self.elems_left 916 | } 917 | } 918 | 919 | /// Iterator over shared references to entries in a table. 920 | pub struct Iter<'a, K: 'a, V: 'a> { 921 | iter: RawBuckets<'a, K, V>, 922 | } 923 | 924 | unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {} 925 | unsafe impl<'a, K: Sync, V: Sync> Send for Iter<'a, K, V> {} 926 | 927 | // FIXME(#26925) Remove in favor of `#[derive(Clone)]` 928 | impl<'a, K, V> Clone for Iter<'a, K, V> { 929 | fn clone(&self) -> Iter<'a, K, V> { 930 | Iter { 931 | iter: self.iter.clone(), 932 | } 933 | } 934 | } 935 | 936 | /// Iterator over mutable references to entries in a table. 937 | pub struct IterMut<'a, K: 'a, V: 'a> { 938 | iter: RawBuckets<'a, K, V>, 939 | // To ensure invariance with respect to V 940 | _marker: marker::PhantomData<&'a mut V>, 941 | } 942 | 943 | unsafe impl<'a, K: Sync, V: Sync> Sync for IterMut<'a, K, V> {} 944 | // Both K: Sync and K: Send are correct for IterMut's Send impl, 945 | // but Send is the more useful bound 946 | unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {} 947 | 948 | impl<'a, K: 'a, V: 'a> IterMut<'a, K, V> { 949 | pub fn iter(&self) -> Iter { 950 | Iter { 951 | iter: self.iter.clone(), 952 | } 953 | } 954 | } 955 | 956 | /// Iterator over the entries in a table, consuming the table. 957 | pub struct IntoIter { 958 | table: RawTable, 959 | iter: RawBuckets<'static, K, V>, 960 | } 961 | 962 | unsafe impl Sync for IntoIter {} 963 | unsafe impl Send for IntoIter {} 964 | 965 | impl IntoIter { 966 | pub fn iter(&self) -> Iter { 967 | Iter { 968 | iter: self.iter.clone(), 969 | } 970 | } 971 | } 972 | 973 | /// Iterator over the entries in a table, clearing the table. 974 | pub struct Drain<'a, K: 'a, V: 'a> { 975 | table: NonNull>, 976 | iter: RawBuckets<'static, K, V>, 977 | marker: marker::PhantomData<&'a RawTable>, 978 | } 979 | 980 | unsafe impl<'a, K: Sync, V: Sync> Sync for Drain<'a, K, V> {} 981 | unsafe impl<'a, K: Send, V: Send> Send for Drain<'a, K, V> {} 982 | 983 | impl<'a, K, V> Drain<'a, K, V> { 984 | pub fn iter(&self) -> Iter { 985 | Iter { 986 | iter: self.iter.clone(), 987 | } 988 | } 989 | } 990 | 991 | impl<'a, K, V> Iterator for Iter<'a, K, V> { 992 | type Item = (&'a K, &'a V); 993 | 994 | fn next(&mut self) -> Option<(&'a K, &'a V)> { 995 | self.iter.next().map(|raw| unsafe { 996 | let pair_ptr = raw.pair(); 997 | (&(*pair_ptr).0, &(*pair_ptr).1) 998 | }) 999 | } 1000 | 1001 | fn size_hint(&self) -> (usize, Option) { 1002 | self.iter.size_hint() 1003 | } 1004 | } 1005 | 1006 | impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> { 1007 | fn len(&self) -> usize { 1008 | self.iter.len() 1009 | } 1010 | } 1011 | 1012 | impl<'a, K, V> Iterator for IterMut<'a, K, V> { 1013 | type Item = (&'a K, &'a mut V); 1014 | 1015 | fn next(&mut self) -> Option<(&'a K, &'a mut V)> { 1016 | self.iter.next().map(|raw| unsafe { 1017 | let pair_ptr = raw.pair(); 1018 | (&(*pair_ptr).0, &mut (*pair_ptr).1) 1019 | }) 1020 | } 1021 | 1022 | fn size_hint(&self) -> (usize, Option) { 1023 | self.iter.size_hint() 1024 | } 1025 | } 1026 | 1027 | impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> { 1028 | fn len(&self) -> usize { 1029 | self.iter.len() 1030 | } 1031 | } 1032 | 1033 | impl Iterator for IntoIter { 1034 | type Item = (SafeHash, K, V); 1035 | 1036 | fn next(&mut self) -> Option<(SafeHash, K, V)> { 1037 | self.iter.next().map(|raw| { 1038 | self.table.size -= 1; 1039 | unsafe { 1040 | let (k, v) = ptr::read(raw.pair()); 1041 | (SafeHash { hash: *raw.hash() }, k, v) 1042 | } 1043 | }) 1044 | } 1045 | 1046 | fn size_hint(&self) -> (usize, Option) { 1047 | self.iter.size_hint() 1048 | } 1049 | } 1050 | 1051 | impl ExactSizeIterator for IntoIter { 1052 | fn len(&self) -> usize { 1053 | self.iter().len() 1054 | } 1055 | } 1056 | 1057 | impl<'a, K, V> Iterator for Drain<'a, K, V> { 1058 | type Item = (SafeHash, K, V); 1059 | 1060 | #[inline] 1061 | fn next(&mut self) -> Option<(SafeHash, K, V)> { 1062 | self.iter.next().map(|raw| unsafe { 1063 | self.table.as_mut().size -= 1; 1064 | let (k, v) = ptr::read(raw.pair()); 1065 | ( 1066 | SafeHash { 1067 | hash: ptr::replace(&mut *raw.hash(), EMPTY_BUCKET), 1068 | }, 1069 | k, 1070 | v, 1071 | ) 1072 | }) 1073 | } 1074 | 1075 | fn size_hint(&self) -> (usize, Option) { 1076 | self.iter.size_hint() 1077 | } 1078 | } 1079 | 1080 | impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> { 1081 | fn len(&self) -> usize { 1082 | self.iter.len() 1083 | } 1084 | } 1085 | 1086 | impl<'a, K: 'a, V: 'a> Drop for Drain<'a, K, V> { 1087 | fn drop(&mut self) { 1088 | self.for_each(drop); 1089 | } 1090 | } 1091 | 1092 | impl Clone for RawTable { 1093 | fn clone(&self) -> RawTable { 1094 | unsafe { 1095 | let cap = self.capacity(); 1096 | let mut new_ht = RawTable::new_uninitialized(cap); 1097 | 1098 | let mut new_buckets = new_ht.raw_bucket_at(0); 1099 | let mut buckets = self.raw_bucket_at(0); 1100 | while buckets.idx < cap { 1101 | *new_buckets.hash() = *buckets.hash(); 1102 | if *new_buckets.hash() != EMPTY_BUCKET { 1103 | let pair_ptr = buckets.pair(); 1104 | let kv = ((*pair_ptr).0.clone(), (*pair_ptr).1.clone()); 1105 | ptr::write(new_buckets.pair(), kv); 1106 | } 1107 | buckets.idx += 1; 1108 | new_buckets.idx += 1; 1109 | } 1110 | 1111 | new_ht.size = self.size(); 1112 | new_ht.set_tag(self.tag()); 1113 | 1114 | new_ht 1115 | } 1116 | } 1117 | } 1118 | 1119 | unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable { 1120 | fn drop(&mut self) { 1121 | if self.capacity() == 0 { 1122 | return; 1123 | } 1124 | 1125 | // This is done in reverse because we've likely partially taken 1126 | // some elements out with `.into_iter()` from the front. 1127 | // Check if the size is 0, so we don't do a useless scan when 1128 | // dropping empty tables such as on resize. 1129 | // Also avoid double drop of elements that have been already moved out. 1130 | unsafe { 1131 | if needs_drop::<(K, V)>() { 1132 | // avoid linear runtime for types that don't need drop 1133 | self.rev_drop_buckets(); 1134 | } 1135 | } 1136 | 1137 | let (layout, _) = calculate_layout::(self.capacity()) 1138 | .unwrap_or_else(|_| unsafe { hint::unreachable_unchecked() }); 1139 | unsafe { 1140 | Global.dealloc(NonNull::new_unchecked(self.hashes.ptr()).cast(), layout); 1141 | // Remember how everything was allocated out of one buffer 1142 | // during initialization? We only need one call to free here. 1143 | } 1144 | } 1145 | } 1146 | --------------------------------------------------------------------------------