mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
No bug - Revendor rust dependencies
This commit is contained in:
parent
9cd350ab4e
commit
47d56b8748
1
third_party/rust/ordermap/.cargo-checksum.json
vendored
Normal file
1
third_party/rust/ordermap/.cargo-checksum.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"files":{".travis.yml":"0600e977b88280afee20ce3b56e64bf240038c2e180c8b9e1e02d34f7d61a654","Cargo.toml":"0635c91ee09336945616a8cbf2a96d7d7f39aed78ec42c7d8008a60f1e6bbac7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"ecc269ef87fd38a1d98e30bfac9ba964a9dbd9315c3770fed98d4d7cb5882055","README.rst":"d7208219bafe64ad6bb4b1ffee5b43bb14002b84d0a0b41c9fce7db3352c83fe","benches/bench.rs":"9540fa56aa5ac2cf16ff78b7f9614ca1f4e231d857f7e05b994f90d5feaf9e95","benches/faststring.rs":"e230bb2d39f1de301fc82a6fd458078f7a3fdf80ead9b8db8af2831383201320","src/equivalent.rs":"4d07c0ae8c8ff405fdbb45e6c891158d3fdcfedd47001e4cec090c79b5c56564","src/lib.rs":"0112d05df2a0ea9071e4313f1c3a8ec043cad133d3377946da2f5bf66eb7e201","src/macros.rs":"0ff93b574d8d441d3235cc76d9d142a13b2e9a9e4ce8313b7eaa0476380a4379","src/mutable_keys.rs":"29d372733ab270eb2da22c2702d12ec603c66430cb809adbeddb8ec7110749fc","src/serde.rs":"bc1f91dab9edf627c98815896b1be76e3ebc4360be0684d8f5e4ac21090b3b7a","src/set.rs":"21607e53e6aafa8fd3e34166fe034f7a76c02708fe5a2ce8c7f2c2100e60d215","src/util.rs":"331f80b48387878caa01ab9cfd43927ea0c15129c6beb755d6b40abc6ada900f","tests/equivalent_trait.rs":"3f48a3e1e0df163db99249ce1d4b7654904371e4cac996a71e36b74569df11f9","tests/quick.rs":"1b18d947ffa731417c808fe1cd469fd0d1df65b0c5f28936d6c9347772f52d3a","tests/serde.rs":"b67153585905357ea190a4f2692aef93479f501a00501521335d91cbcbe35a04","tests/tests.rs":"bc72e84efc79f47bbb17c1cb594c5290290691051ee298942a1911a55d3b94f1"},"package":"a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"}
|
22
third_party/rust/ordermap/.travis.yml
vendored
Normal file
22
third_party/rust/ordermap/.travis.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
language: rust
|
||||
sudo: false
|
||||
matrix:
|
||||
include:
|
||||
- rust: 1.18.0
|
||||
- rust: stable
|
||||
env:
|
||||
- FEATURES='serde-1'
|
||||
- rust: beta
|
||||
- rust: nightly
|
||||
- rust: nightly
|
||||
env:
|
||||
- FEATURES='test_low_transition_point'
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
script:
|
||||
- |
|
||||
cargo build --verbose --features "$FEATURES" &&
|
||||
cargo test --verbose --features "$FEATURES" &&
|
||||
cargo test --release --verbose --features "$FEATURES" &&
|
||||
cargo doc --verbose --features "$FEATURES"
|
58
third_party/rust/ordermap/Cargo.toml
vendored
Normal file
58
third_party/rust/ordermap/Cargo.toml
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g. crates.io) dependencies
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
# editing this file be aware that the upstream Cargo.toml
|
||||
# will likely look very different (and much more reasonable)
|
||||
|
||||
[package]
|
||||
name = "ordermap"
|
||||
version = "0.3.5"
|
||||
authors = ["bluss"]
|
||||
description = "A hash table with consistent order and fast iteration."
|
||||
documentation = "https://docs.rs/ordermap/"
|
||||
keywords = ["hashmap"]
|
||||
categories = ["data-structures"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/bluss/ordermap"
|
||||
[package.metadata.docs.rs]
|
||||
features = ["serde-1"]
|
||||
|
||||
[package.metadata.release]
|
||||
no-dev-version = true
|
||||
[profile.bench]
|
||||
debug = true
|
||||
|
||||
[lib]
|
||||
bench = false
|
||||
[dependencies.serde]
|
||||
version = "1.0"
|
||||
optional = true
|
||||
[dev-dependencies.fnv]
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.itertools]
|
||||
version = "0.7.0"
|
||||
|
||||
[dev-dependencies.lazy_static]
|
||||
version = "1"
|
||||
|
||||
[dev-dependencies.quickcheck]
|
||||
version = "0.6"
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.rand]
|
||||
version = "0.4"
|
||||
|
||||
[dev-dependencies.serde_test]
|
||||
version = "1.0.5"
|
||||
|
||||
[features]
|
||||
serde-1 = ["serde"]
|
||||
test_debug = []
|
||||
test_low_transition_point = []
|
201
third_party/rust/ordermap/LICENSE-APACHE
vendored
Normal file
201
third_party/rust/ordermap/LICENSE-APACHE
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
25
third_party/rust/ordermap/LICENSE-MIT
vendored
Normal file
25
third_party/rust/ordermap/LICENSE-MIT
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
Copyright (c) 2016--2017
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
226
third_party/rust/ordermap/README.rst
vendored
Normal file
226
third_party/rust/ordermap/README.rst
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
|
||||
Awesome hash table implementation in just Rust (stable, no unsafe code).
|
||||
|
||||
Please read the `API documentation here`__
|
||||
|
||||
__ https://docs.rs/ordermap/
|
||||
|
||||
|build_status|_ |crates|_
|
||||
|
||||
.. |crates| image:: https://img.shields.io/crates/v/ordermap.svg
|
||||
.. _crates: https://crates.io/crates/ordermap
|
||||
|
||||
.. |build_status| image:: https://travis-ci.org/bluss/ordermap.svg
|
||||
.. _build_status: https://travis-ci.org/bluss/ordermap
|
||||
|
||||
|
||||
Background
|
||||
==========
|
||||
|
||||
This was inspired by Python 3.6's new dict implementation (which remembers
|
||||
the insertion order and is fast to iterate, and is compact in memory).
|
||||
|
||||
Some of those features were translated to Rust, and some were not. The result
|
||||
was ordermap, a hash table that has following properties:
|
||||
|
||||
- Order is **independent of hash function** and hash values of keys.
|
||||
- Fast to iterate.
|
||||
- Indexed in compact space.
|
||||
- Preserves insertion order **as long** as you don't call ``.remove()``.
|
||||
- Uses robin hood hashing just like Rust's libstd ``HashMap``.
|
||||
|
||||
- It's the usual backwards shift deletion, but only on the index vector, so
|
||||
it's cheaper because it's moving less memory around.
|
||||
|
||||
Does not implement (Yet)
|
||||
------------------------
|
||||
|
||||
- ``.reserve()`` exists but does not have a complete implementation
|
||||
|
||||
Performance
|
||||
-----------
|
||||
|
||||
``OrderMap`` derives a couple of performance facts directly from how it is constructed,
|
||||
which is roughly:
|
||||
|
||||
Two vectors, the first, sparse, with hashes and key-value indices, and the
|
||||
second, dense, the key-value pairs.
|
||||
|
||||
- Iteration is very fast since it is on the dense key-values.
|
||||
- Removal is fast since it moves memory areas only in the first vector,
|
||||
and uses a single swap in the second vector.
|
||||
- Lookup is fast-ish because the hashes and indices are densely stored.
|
||||
Lookup also is slow-ish since hashes and key-value pairs are stored in
|
||||
separate places. (Visible when cpu caches size is limiting.)
|
||||
|
||||
- In practice, ``OrderMap`` has been tested out as the hashmap in rustc in PR45282_ and
|
||||
the performance was roughly on par across the whole workload.
|
||||
- If you want the properties of ``OrderMap``, or its strongest performance points
|
||||
fits your workload, it might be the best hash table implementation.
|
||||
|
||||
.. _PR45282: https://github.com/rust-lang/rust/pull/45282
|
||||
|
||||
Interesting Features
|
||||
--------------------
|
||||
|
||||
- Insertion order is preserved (``.swap_remove()`` perturbs the order, like the method name says).
|
||||
- Implements ``.pop() -> Option<(K, V)>`` in O(1) time.
|
||||
- ``OrderMap::new()`` is empty and uses no allocation until you insert something.
|
||||
- Lookup key-value pairs by index and vice versa.
|
||||
- No ``unsafe``.
|
||||
- Supports ``IndexMut``.
|
||||
|
||||
|
||||
Where to go from here?
|
||||
----------------------
|
||||
|
||||
- Ideas and PRs for how to implement insertion-order preserving remove (for example tombstones)
|
||||
are welcome. The plan is to split the crate into two hash table implementations
|
||||
a) the current compact index space version and b) the full insertion order version.
|
||||
|
||||
|
||||
Ideas that we already did
|
||||
-------------------------
|
||||
|
||||
- It can be an *indexable* ordered map in the current fashion
|
||||
(This was implemented in 0.2.0, for potential use as a graph datastructure).
|
||||
|
||||
- Idea for more cache efficient lookup (This was implemented in 0.1.2).
|
||||
|
||||
Current ``indices: Vec<Pos>``. ``Pos`` is interpreted as ``(u32, u32)`` more
|
||||
or less when ``.raw_capacity()`` fits in 32 bits. ``Pos`` then stores both the lower
|
||||
half of the hash and the entry index.
|
||||
This means that the hash values in ``Bucket`` don't need to be accessed
|
||||
while scanning for an entry.
|
||||
|
||||
|
||||
Recent Changes
|
||||
==============
|
||||
|
||||
- 0.3.5
|
||||
|
||||
- Documentation improvements
|
||||
|
||||
- 0.3.4
|
||||
|
||||
- The ``.retain()`` methods for ``OrderMap`` and ``OrderSet`` now
|
||||
traverse the elements in order, and the retained elements **keep their order**
|
||||
- Added new methods ``.sort_by()``, ``.sort_keys()`` to ``OrderMap`` and
|
||||
``.sort_by()``, ``.sort()`` to ``OrderSet``. These methods allow you to
|
||||
sort the maps in place efficiently.
|
||||
|
||||
- 0.3.3
|
||||
|
||||
- Document insertion behaviour better by @lucab
|
||||
- Updated dependences (no feature changes) by @ignatenkobrain
|
||||
|
||||
- 0.3.2
|
||||
|
||||
- Add ``OrderSet`` by @cuviper!
|
||||
- ``OrderMap::drain`` is now (too) a double ended iterator.
|
||||
|
||||
- 0.3.1
|
||||
|
||||
- In all ordermap iterators, forward the ``collect`` method to the underlying
|
||||
iterator as well.
|
||||
- Add crates.io categories.
|
||||
|
||||
- 0.3.0
|
||||
|
||||
- The methods ``get_pair``, ``get_pair_index`` were both replaced by
|
||||
``get_full`` (and the same for the mutable case).
|
||||
- Method ``swap_remove_pair`` replaced by ``swap_remove_full``.
|
||||
- Add trait ``MutableKeys`` for opt-in mutable key access. Mutable key access
|
||||
is only possible through the methods of this extension trait.
|
||||
- Add new trait ``Equivalent`` for key equivalence. This extends the
|
||||
``Borrow`` trait mechanism for ``OrderMap::get`` in a backwards compatible
|
||||
way, just some minor type inference related issues may become apparent.
|
||||
See `#10`__ for more information.
|
||||
- Implement ``Extend<(&K, &V)>`` by @xfix.
|
||||
|
||||
__ https://github.com/bluss/ordermap/pull/10
|
||||
|
||||
- 0.2.13
|
||||
|
||||
- Fix deserialization to support custom hashers by @Techcable.
|
||||
- Add methods ``.index()`` on the entry types by @garro95.
|
||||
|
||||
- 0.2.12
|
||||
|
||||
- Add methods ``.with_hasher()``, ``.hasher()``.
|
||||
|
||||
- 0.2.11
|
||||
|
||||
- Support ``ExactSizeIterator`` for the iterators. By @Binero.
|
||||
- Use ``Box<[Pos]>`` internally, saving a word in the ``OrderMap`` struct.
|
||||
- Serde support, with crate feature ``"serde-1"``. By @xfix.
|
||||
|
||||
- 0.2.10
|
||||
|
||||
- Add iterator ``.drain(..)`` by @stevej.
|
||||
|
||||
- 0.2.9
|
||||
|
||||
- Add method ``.is_empty()`` by @overvenus.
|
||||
- Implement ``PartialEq, Eq`` by @overvenus.
|
||||
- Add method ``.sorted_by()``.
|
||||
|
||||
- 0.2.8
|
||||
|
||||
- Add iterators ``.values()`` and ``.values_mut()``.
|
||||
- Fix compatibility with 32-bit platforms.
|
||||
|
||||
- 0.2.7
|
||||
|
||||
- Add ``.retain()``.
|
||||
|
||||
- 0.2.6
|
||||
|
||||
- Add ``OccupiedEntry::remove_entry`` and other minor entry methods,
|
||||
so that it now has all the features of ``HashMap``'s entries.
|
||||
|
||||
- 0.2.5
|
||||
|
||||
- Improved ``.pop()`` slightly.
|
||||
|
||||
- 0.2.4
|
||||
|
||||
- Improved performance of ``.insert()`` (`#3`__) by @pczarn.
|
||||
|
||||
__ https://github.com/bluss/ordermap/pull/3
|
||||
|
||||
- 0.2.3
|
||||
|
||||
- Generalize ``Entry`` for now, so that it works on hashmaps with non-default
|
||||
hasher. However, there's a lingering compat issue since libstd ``HashMap``
|
||||
does not parameterize its entries by the hasher (``S`` typarm).
|
||||
- Special case some iterator methods like ``.nth()``.
|
||||
|
||||
- 0.2.2
|
||||
|
||||
- Disable the verbose ``Debug`` impl by default.
|
||||
|
||||
- 0.2.1
|
||||
|
||||
- Fix doc links and clarify docs.
|
||||
|
||||
- 0.2.0
|
||||
|
||||
- Add more ``HashMap`` methods & compat with its API.
|
||||
- Experimental support for ``.entry()`` (the simplest parts of the API).
|
||||
- Add ``.reserve()`` (placeholder impl).
|
||||
- Add ``.remove()`` as synonym for ``.swap_remove()``.
|
||||
- Changed ``.insert()`` to swap value if the entry already exists, and
|
||||
return ``Option``.
|
||||
- Experimental support as an *indexed* hash map! Added methods
|
||||
``.get_index()``, ``.get_index_mut()``, ``.swap_remove_index()``,
|
||||
``.get_pair_index()``, ``.get_pair_index_mut()``.
|
||||
|
||||
- 0.1.2
|
||||
|
||||
- Implement the 32/32 split idea for ``Pos`` which improves cache utilization
|
||||
and lookup performance.
|
||||
|
||||
- 0.1.1
|
||||
|
||||
- Initial release.
|
745
third_party/rust/ordermap/benches/bench.rs
vendored
Normal file
745
third_party/rust/ordermap/benches/bench.rs
vendored
Normal file
@ -0,0 +1,745 @@
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
extern crate rand;
|
||||
extern crate fnv;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
use std::hash::Hash;
|
||||
use fnv::FnvHasher;
|
||||
use std::hash::BuildHasherDefault;
|
||||
type FnvBuilder = BuildHasherDefault<FnvHasher>;
|
||||
|
||||
use test::Bencher;
|
||||
use test::black_box;
|
||||
|
||||
extern crate ordermap;
|
||||
|
||||
use ordermap::OrderMap;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use rand::{weak_rng, Rng};
|
||||
|
||||
#[bench]
|
||||
fn new_hashmap(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
HashMap::<String, String>::new()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn new_orderedmap(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
OrderMap::<String, String>::new()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn with_capacity_10e5_hashmap(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
HashMap::<String, String>::with_capacity(10_000)
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn with_capacity_10e5_orderedmap(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
OrderMap::<String, String>::with_capacity(10_000)
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_hashmap_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
b.iter(|| {
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
for x in 0..c {
|
||||
map.insert(x, ());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_orderedmap_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
b.iter(|| {
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
for x in 0..c {
|
||||
map.insert(x, ());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_hashmap_string_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
b.iter(|| {
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
for x in 0..c {
|
||||
map.insert(x.to_string(), ());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_orderedmap_string_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
b.iter(|| {
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
for x in 0..c {
|
||||
map.insert(x.to_string(), ());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_hashmap_str_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let ss = Vec::from_iter((0..c).map(|x| x.to_string()));
|
||||
b.iter(|| {
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
for key in &ss {
|
||||
map.insert(&key[..], ());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_orderedmap_str_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let ss = Vec::from_iter((0..c).map(|x| x.to_string()));
|
||||
b.iter(|| {
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
for key in &ss {
|
||||
map.insert(&key[..], ());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_hashmap_int_bigvalue_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let value = [0u64; 10];
|
||||
b.iter(|| {
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
for i in 0..c {
|
||||
map.insert(i, value);
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_orderedmap_int_bigvalue_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let value = [0u64; 10];
|
||||
b.iter(|| {
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
for i in 0..c {
|
||||
map.insert(i, value);
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_hashmap_100_000(b: &mut Bencher) {
|
||||
let c = 100_000;
|
||||
b.iter(|| {
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
for x in 0..c {
|
||||
map.insert(x, ());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_orderedmap_100_000(b: &mut Bencher) {
|
||||
let c = 100_000;
|
||||
b.iter(|| {
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
for x in 0..c {
|
||||
map.insert(x, ());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_hashmap_150(b: &mut Bencher) {
|
||||
let c = 150;
|
||||
b.iter(|| {
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
for x in 0..c {
|
||||
map.insert(x, ());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_orderedmap_150(b: &mut Bencher) {
|
||||
let c = 150;
|
||||
b.iter(|| {
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
for x in 0..c {
|
||||
map.insert(x, ());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn entry_hashmap_150(b: &mut Bencher) {
|
||||
let c = 150;
|
||||
b.iter(|| {
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
for x in 0..c {
|
||||
map.entry(x).or_insert(());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn entry_orderedmap_150(b: &mut Bencher) {
|
||||
let c = 150;
|
||||
b.iter(|| {
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
for x in 0..c {
|
||||
map.entry(x).or_insert(());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn iter_sum_hashmap_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
let len = c - c/10;
|
||||
for x in 0..len {
|
||||
map.insert(x, ());
|
||||
}
|
||||
assert_eq!(map.len(), len);
|
||||
b.iter(|| {
|
||||
map.keys().sum::<usize>()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn iter_sum_orderedmap_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
let len = c - c/10;
|
||||
for x in 0..len {
|
||||
map.insert(x, ());
|
||||
}
|
||||
assert_eq!(map.len(), len);
|
||||
b.iter(|| {
|
||||
map.keys().sum::<usize>()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn iter_black_box_hashmap_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
let len = c - c/10;
|
||||
for x in 0..len {
|
||||
map.insert(x, ());
|
||||
}
|
||||
assert_eq!(map.len(), len);
|
||||
b.iter(|| {
|
||||
for &key in map.keys() {
|
||||
black_box(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn iter_black_box_orderedmap_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
let len = c - c/10;
|
||||
for x in 0..len {
|
||||
map.insert(x, ());
|
||||
}
|
||||
assert_eq!(map.len(), len);
|
||||
b.iter(|| {
|
||||
for &key in map.keys() {
|
||||
black_box(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn shuffled_keys<I>(iter: I) -> Vec<I::Item>
|
||||
where I: IntoIterator
|
||||
{
|
||||
let mut v = Vec::from_iter(iter);
|
||||
let mut rng = weak_rng();
|
||||
rng.shuffle(&mut v);
|
||||
v
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn lookup_hashmap_10_000_exist(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
let keys = shuffled_keys(0..c);
|
||||
for &key in &keys {
|
||||
map.insert(key, 1);
|
||||
}
|
||||
b.iter(|| {
|
||||
let mut found = 0;
|
||||
for key in 5000..c {
|
||||
found += map.get(&key).is_some() as i32;
|
||||
}
|
||||
found
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn lookup_hashmap_10_000_noexist(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
let keys = shuffled_keys(0..c);
|
||||
for &key in &keys {
|
||||
map.insert(key, 1);
|
||||
}
|
||||
b.iter(|| {
|
||||
let mut found = 0;
|
||||
for key in c..15000 {
|
||||
found += map.get(&key).is_some() as i32;
|
||||
}
|
||||
found
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn lookup_orderedmap_10_000_exist(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
let keys = shuffled_keys(0..c);
|
||||
for &key in &keys {
|
||||
map.insert(key, 1);
|
||||
}
|
||||
b.iter(|| {
|
||||
let mut found = 0;
|
||||
for key in 5000..c {
|
||||
found += map.get(&key).is_some() as i32;
|
||||
}
|
||||
found
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn lookup_orderedmap_10_000_noexist(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
let keys = shuffled_keys(0..c);
|
||||
for &key in &keys {
|
||||
map.insert(key, 1);
|
||||
}
|
||||
b.iter(|| {
|
||||
let mut found = 0;
|
||||
for key in c..15000 {
|
||||
found += map.get(&key).is_some() as i32;
|
||||
}
|
||||
found
|
||||
});
|
||||
}
|
||||
|
||||
// number of items to look up
|
||||
const LOOKUP_MAP_SIZE: u32 = 100_000_u32;
|
||||
const LOOKUP_SAMPLE_SIZE: u32 = 5000;
|
||||
const SORT_MAP_SIZE: usize = 10_000;
|
||||
|
||||
|
||||
// use lazy_static so that comparison benchmarks use the exact same inputs
|
||||
lazy_static! {
|
||||
static ref KEYS: Vec<u32> = {
|
||||
shuffled_keys(0..LOOKUP_MAP_SIZE)
|
||||
};
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref HMAP_100K: HashMap<u32, u32> = {
|
||||
let c = LOOKUP_MAP_SIZE;
|
||||
let mut map = HashMap::with_capacity(c as usize);
|
||||
let keys = &*KEYS;
|
||||
for &key in keys {
|
||||
map.insert(key, key);
|
||||
}
|
||||
map
|
||||
};
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref OMAP_100K: OrderMap<u32, u32> = {
|
||||
let c = LOOKUP_MAP_SIZE;
|
||||
let mut map = OrderMap::with_capacity(c as usize);
|
||||
let keys = &*KEYS;
|
||||
for &key in keys {
|
||||
map.insert(key, key);
|
||||
}
|
||||
map
|
||||
};
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref OMAP_SORT_U32: OrderMap<u32, u32> = {
|
||||
let mut map = OrderMap::with_capacity(SORT_MAP_SIZE);
|
||||
for &key in &KEYS[..SORT_MAP_SIZE] {
|
||||
map.insert(key, key);
|
||||
}
|
||||
map
|
||||
};
|
||||
}
|
||||
lazy_static! {
|
||||
static ref OMAP_SORT_S: OrderMap<String, String> = {
|
||||
let mut map = OrderMap::with_capacity(SORT_MAP_SIZE);
|
||||
for &key in &KEYS[..SORT_MAP_SIZE] {
|
||||
map.insert(format!("{:^16x}", &key), String::new());
|
||||
}
|
||||
map
|
||||
};
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn lookup_hashmap_100_000_multi(b: &mut Bencher) {
|
||||
let map = &*HMAP_100K;
|
||||
b.iter(|| {
|
||||
let mut found = 0;
|
||||
for key in 0..LOOKUP_SAMPLE_SIZE {
|
||||
found += map.get(&key).is_some() as u32;
|
||||
}
|
||||
found
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#[bench]
|
||||
fn lookup_ordermap_100_000_multi(b: &mut Bencher) {
|
||||
let map = &*OMAP_100K;
|
||||
b.iter(|| {
|
||||
let mut found = 0;
|
||||
for key in 0..LOOKUP_SAMPLE_SIZE {
|
||||
found += map.get(&key).is_some() as u32;
|
||||
}
|
||||
found
|
||||
});
|
||||
}
|
||||
|
||||
// inorder: Test looking up keys in the same order as they were inserted
|
||||
#[bench]
|
||||
fn lookup_hashmap_100_000_inorder_multi(b: &mut Bencher) {
|
||||
let map = &*HMAP_100K;
|
||||
let keys = &*KEYS;
|
||||
b.iter(|| {
|
||||
let mut found = 0;
|
||||
for key in &keys[0..LOOKUP_SAMPLE_SIZE as usize] {
|
||||
found += map.get(key).is_some() as u32;
|
||||
}
|
||||
found
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#[bench]
|
||||
fn lookup_ordermap_100_000_inorder_multi(b: &mut Bencher) {
|
||||
let map = &*OMAP_100K;
|
||||
let keys = &*KEYS;
|
||||
b.iter(|| {
|
||||
let mut found = 0;
|
||||
for key in &keys[0..LOOKUP_SAMPLE_SIZE as usize] {
|
||||
found += map.get(key).is_some() as u32;
|
||||
}
|
||||
found
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn lookup_hashmap_100_000_single(b: &mut Bencher) {
|
||||
let map = &*HMAP_100K;
|
||||
let mut iter = (0..LOOKUP_MAP_SIZE + LOOKUP_SAMPLE_SIZE).cycle();
|
||||
b.iter(|| {
|
||||
let key = iter.next().unwrap();
|
||||
map.get(&key).is_some()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#[bench]
|
||||
fn lookup_ordermap_100_000_single(b: &mut Bencher) {
|
||||
let map = &*OMAP_100K;
|
||||
let mut iter = (0..LOOKUP_MAP_SIZE + LOOKUP_SAMPLE_SIZE).cycle();
|
||||
b.iter(|| {
|
||||
let key = iter.next().unwrap();
|
||||
map.get(&key).is_some()
|
||||
});
|
||||
}
|
||||
|
||||
const GROW_SIZE: usize = 100_000;
|
||||
type GrowKey = u32;
|
||||
|
||||
// Test grow/resize without preallocation
|
||||
#[bench]
|
||||
fn grow_fnv_hashmap_100_000(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let mut map: HashMap<_, _, FnvBuilder> = HashMap::default();
|
||||
for x in 0..GROW_SIZE {
|
||||
map.insert(x as GrowKey, x as GrowKey);
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn grow_fnv_ordermap_100_000(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let mut map: OrderMap<_, _, FnvBuilder> = OrderMap::default();
|
||||
for x in 0..GROW_SIZE {
|
||||
map.insert(x as GrowKey, x as GrowKey);
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const MERGE: u64 = 10_000;
|
||||
#[bench]
|
||||
fn hashmap_merge_simple(b: &mut Bencher) {
|
||||
let first_map: HashMap<u64, _> = (0..MERGE).map(|i| (i, ())).collect();
|
||||
let second_map: HashMap<u64, _> = (MERGE..MERGE * 2).map(|i| (i, ())).collect();
|
||||
b.iter(|| {
|
||||
let mut merged = first_map.clone();
|
||||
merged.extend(second_map.iter().map(|(&k, &v)| (k, v)));
|
||||
merged
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn hashmap_merge_shuffle(b: &mut Bencher) {
|
||||
let first_map: HashMap<u64, _> = (0..MERGE).map(|i| (i, ())).collect();
|
||||
let second_map: HashMap<u64, _> = (MERGE..MERGE * 2).map(|i| (i, ())).collect();
|
||||
let mut v = Vec::new();
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| {
|
||||
let mut merged = first_map.clone();
|
||||
v.extend(second_map.iter().map(|(&k, &v)| (k, v)));
|
||||
rng.shuffle(&mut v);
|
||||
merged.extend(v.drain(..));
|
||||
|
||||
merged
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn ordermap_merge_simple(b: &mut Bencher) {
|
||||
let first_map: OrderMap<u64, _> = (0..MERGE).map(|i| (i, ())).collect();
|
||||
let second_map: OrderMap<u64, _> = (MERGE..MERGE * 2).map(|i| (i, ())).collect();
|
||||
b.iter(|| {
|
||||
let mut merged = first_map.clone();
|
||||
merged.extend(second_map.iter().map(|(&k, &v)| (k, v)));
|
||||
merged
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn ordermap_merge_shuffle(b: &mut Bencher) {
|
||||
let first_map: OrderMap<u64, _> = (0..MERGE).map(|i| (i, ())).collect();
|
||||
let second_map: OrderMap<u64, _> = (MERGE..MERGE * 2).map(|i| (i, ())).collect();
|
||||
let mut v = Vec::new();
|
||||
let mut rng = weak_rng();
|
||||
b.iter(|| {
|
||||
let mut merged = first_map.clone();
|
||||
v.extend(second_map.iter().map(|(&k, &v)| (k, v)));
|
||||
rng.shuffle(&mut v);
|
||||
merged.extend(v.drain(..));
|
||||
|
||||
merged
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn remove_ordermap_100_000(b: &mut Bencher) {
|
||||
let map = OMAP_100K.clone();
|
||||
let mut keys = Vec::from_iter(map.keys().cloned());
|
||||
weak_rng().shuffle(&mut keys);
|
||||
|
||||
b.iter(|| {
|
||||
let mut map = map.clone();
|
||||
for key in &keys {
|
||||
map.remove(key).is_some();
|
||||
}
|
||||
assert_eq!(map.len(), 0);
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn pop_ordermap_100_000(b: &mut Bencher) {
|
||||
let map = OMAP_100K.clone();
|
||||
|
||||
b.iter(|| {
|
||||
let mut map = map.clone();
|
||||
while map.len() > 0 {
|
||||
map.pop();
|
||||
}
|
||||
assert_eq!(map.len(), 0);
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn few_retain_ordermap_100_000(b: &mut Bencher) {
|
||||
let map = OMAP_100K.clone();
|
||||
|
||||
b.iter(|| {
|
||||
let mut map = map.clone();
|
||||
map.retain(|k, _| *k % 7 == 0);
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn few_retain_hashmap_100_000(b: &mut Bencher) {
|
||||
let map = HMAP_100K.clone();
|
||||
|
||||
b.iter(|| {
|
||||
let mut map = map.clone();
|
||||
map.retain(|k, _| *k % 7 == 0);
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn half_retain_ordermap_100_000(b: &mut Bencher) {
|
||||
let map = OMAP_100K.clone();
|
||||
|
||||
b.iter(|| {
|
||||
let mut map = map.clone();
|
||||
map.retain(|k, _| *k % 2 == 0);
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn half_retain_hashmap_100_000(b: &mut Bencher) {
|
||||
let map = HMAP_100K.clone();
|
||||
|
||||
b.iter(|| {
|
||||
let mut map = map.clone();
|
||||
map.retain(|k, _| *k % 2 == 0);
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn many_retain_ordermap_100_000(b: &mut Bencher) {
|
||||
let map = OMAP_100K.clone();
|
||||
|
||||
b.iter(|| {
|
||||
let mut map = map.clone();
|
||||
map.retain(|k, _| *k % 100 != 0);
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn many_retain_hashmap_100_000(b: &mut Bencher) {
|
||||
let map = HMAP_100K.clone();
|
||||
|
||||
b.iter(|| {
|
||||
let mut map = map.clone();
|
||||
map.retain(|k, _| *k % 100 != 0);
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// simple sort impl for comparison
|
||||
pub fn simple_sort<K: Ord + Hash, V>(m: &mut OrderMap<K, V>) {
|
||||
let mut ordered: Vec<_> = m.drain(..).collect();
|
||||
ordered.sort_by(|left, right| left.0.cmp(&right.0));
|
||||
m.extend(ordered);
|
||||
}
|
||||
|
||||
|
||||
#[bench]
|
||||
fn ordermap_sort_s(b: &mut Bencher) {
|
||||
let map = OMAP_SORT_S.clone();
|
||||
|
||||
// there's a map clone there, but it's still useful to profile this
|
||||
b.iter(|| {
|
||||
let mut map = map.clone();
|
||||
map.sort_keys();
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn ordermap_simple_sort_s(b: &mut Bencher) {
|
||||
let map = OMAP_SORT_S.clone();
|
||||
|
||||
// there's a map clone there, but it's still useful to profile this
|
||||
b.iter(|| {
|
||||
let mut map = map.clone();
|
||||
simple_sort(&mut map);
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn ordermap_sort_u32(b: &mut Bencher) {
|
||||
let map = OMAP_SORT_U32.clone();
|
||||
|
||||
// there's a map clone there, but it's still useful to profile this
|
||||
b.iter(|| {
|
||||
let mut map = map.clone();
|
||||
map.sort_keys();
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn ordermap_simple_sort_u32(b: &mut Bencher) {
|
||||
let map = OMAP_SORT_U32.clone();
|
||||
|
||||
// there's a map clone there, but it's still useful to profile this
|
||||
b.iter(|| {
|
||||
let mut map = map.clone();
|
||||
simple_sort(&mut map);
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
// measure the fixed overhead of cloning in sort benchmarks
|
||||
#[bench]
|
||||
fn ordermap_clone_for_sort_s(b: &mut Bencher) {
|
||||
let map = OMAP_SORT_S.clone();
|
||||
|
||||
b.iter(|| {
|
||||
map.clone()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn ordermap_clone_for_sort_u32(b: &mut Bencher) {
|
||||
let map = OMAP_SORT_U32.clone();
|
||||
|
||||
b.iter(|| {
|
||||
map.clone()
|
||||
});
|
||||
}
|
||||
|
183
third_party/rust/ordermap/benches/faststring.rs
vendored
Normal file
183
third_party/rust/ordermap/benches/faststring.rs
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
extern crate rand;
|
||||
extern crate lazy_static;
|
||||
|
||||
use test::Bencher;
|
||||
|
||||
extern crate ordermap;
|
||||
|
||||
use ordermap::OrderMap;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use rand::{weak_rng, Rng};
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use std::ops::Deref;
|
||||
use std::mem;
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||
pub struct OneShot<T: ?Sized>(pub T);
|
||||
|
||||
impl Hash for OneShot<str>
|
||||
{
|
||||
fn hash<H: Hasher>(&self, h: &mut H) {
|
||||
h.write(self.0.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S> From<&'a S> for &'a OneShot<str>
|
||||
where S: AsRef<str>
|
||||
{
|
||||
fn from(s: &'a S) -> Self {
|
||||
let s: &str = s.as_ref();
|
||||
unsafe {
|
||||
mem::transmute(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for OneShot<String>
|
||||
{
|
||||
fn hash<H: Hasher>(&self, h: &mut H) {
|
||||
h.write(self.0.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<OneShot<str>> for OneShot<String>
|
||||
{
|
||||
fn borrow(&self) -> &OneShot<str> {
|
||||
<&OneShot<str>>::from(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for OneShot<T>
|
||||
{
|
||||
type Target = T;
|
||||
fn deref(&self) -> &T {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn shuffled_keys<I>(iter: I) -> Vec<I::Item>
|
||||
where I: IntoIterator
|
||||
{
|
||||
let mut v = Vec::from_iter(iter);
|
||||
let mut rng = weak_rng();
|
||||
rng.shuffle(&mut v);
|
||||
v
|
||||
}
|
||||
|
||||
|
||||
#[bench]
|
||||
fn insert_hashmap_string_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
b.iter(|| {
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
for x in 0..c {
|
||||
map.insert(x.to_string(), ());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_hashmap_string_oneshot_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
b.iter(|| {
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
for x in 0..c {
|
||||
map.insert(OneShot(x.to_string()), ());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn insert_orderedmap_string_10_000(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
b.iter(|| {
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
for x in 0..c {
|
||||
map.insert(x.to_string(), ());
|
||||
}
|
||||
map
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn lookup_hashmap_10_000_exist_string(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
let keys = shuffled_keys(0..c);
|
||||
for &key in &keys {
|
||||
map.insert(key.to_string(), 1);
|
||||
}
|
||||
let lookups = (5000..c).map(|x| x.to_string()).collect::<Vec<_>>();
|
||||
b.iter(|| {
|
||||
let mut found = 0;
|
||||
for key in &lookups {
|
||||
found += map.get(key).is_some() as i32;
|
||||
}
|
||||
found
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn lookup_hashmap_10_000_exist_string_oneshot(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let mut map = HashMap::with_capacity(c);
|
||||
let keys = shuffled_keys(0..c);
|
||||
for &key in &keys {
|
||||
map.insert(OneShot(key.to_string()), 1);
|
||||
}
|
||||
let lookups = (5000..c).map(|x| OneShot(x.to_string())).collect::<Vec<_>>();
|
||||
b.iter(|| {
|
||||
let mut found = 0;
|
||||
for key in &lookups {
|
||||
found += map.get(key).is_some() as i32;
|
||||
}
|
||||
found
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn lookup_ordermap_10_000_exist_string(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
let keys = shuffled_keys(0..c);
|
||||
for &key in &keys {
|
||||
map.insert(key.to_string(), 1);
|
||||
}
|
||||
let lookups = (5000..c).map(|x| x.to_string()).collect::<Vec<_>>();
|
||||
b.iter(|| {
|
||||
let mut found = 0;
|
||||
for key in &lookups {
|
||||
found += map.get(key).is_some() as i32;
|
||||
}
|
||||
found
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn lookup_ordermap_10_000_exist_string_oneshot(b: &mut Bencher) {
|
||||
let c = 10_000;
|
||||
let mut map = OrderMap::with_capacity(c);
|
||||
let keys = shuffled_keys(0..c);
|
||||
for &key in &keys {
|
||||
map.insert(OneShot(key.to_string()), 1);
|
||||
}
|
||||
let lookups = (5000..c).map(|x| OneShot(x.to_string())).collect::<Vec<_>>();
|
||||
b.iter(|| {
|
||||
let mut found = 0;
|
||||
for key in &lookups {
|
||||
found += map.get(key).is_some() as i32;
|
||||
}
|
||||
found
|
||||
});
|
||||
}
|
27
third_party/rust/ordermap/src/equivalent.rs
vendored
Normal file
27
third_party/rust/ordermap/src/equivalent.rs
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
use std::borrow::Borrow;
|
||||
|
||||
/// Key equivalence trait.
|
||||
///
|
||||
/// This trait allows hash table lookup to be customized.
|
||||
/// It has one blanket implementation that uses the regular `Borrow` solution,
|
||||
/// just like `HashMap` and `BTreeMap` do, so that you can pass `&str` to lookup
|
||||
/// into a map with `String` keys and so on.
|
||||
///
|
||||
/// # Contract
|
||||
///
|
||||
/// The implementor **must** hash like `K`, if it is hashable.
|
||||
pub trait Equivalent<K: ?Sized> {
|
||||
/// Compare self to `key` and return `true` if they are equal.
|
||||
fn equivalent(&self, key: &K) -> bool;
|
||||
}
|
||||
|
||||
impl<Q: ?Sized, K: ?Sized> Equivalent<K> for Q
|
||||
where Q: Eq,
|
||||
K: Borrow<Q>,
|
||||
{
|
||||
#[inline]
|
||||
fn equivalent(&self, key: &K) -> bool {
|
||||
*self == *key.borrow()
|
||||
}
|
||||
}
|
1877
third_party/rust/ordermap/src/lib.rs
vendored
Normal file
1877
third_party/rust/ordermap/src/lib.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
122
third_party/rust/ordermap/src/macros.rs
vendored
Normal file
122
third_party/rust/ordermap/src/macros.rs
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
|
||||
#[macro_export]
|
||||
/// Create an `OrderMap` from a list of key-value pairs
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```
|
||||
/// #[macro_use] extern crate ordermap;
|
||||
/// # fn main() {
|
||||
///
|
||||
/// let map = ordermap!{
|
||||
/// "a" => 1,
|
||||
/// "b" => 2,
|
||||
/// };
|
||||
/// assert_eq!(map["a"], 1);
|
||||
/// assert_eq!(map["b"], 2);
|
||||
/// assert_eq!(map.get("c"), None);
|
||||
///
|
||||
/// // "a" is the first key
|
||||
/// assert_eq!(map.keys().next(), Some(&"a"));
|
||||
/// # }
|
||||
/// ```
|
||||
macro_rules! ordermap {
|
||||
(@single $($x:tt)*) => (());
|
||||
(@count $($rest:expr),*) => (<[()]>::len(&[$(ordermap!(@single $rest)),*]));
|
||||
|
||||
($($key:expr => $value:expr,)+) => { ordermap!($($key => $value),+) };
|
||||
($($key:expr => $value:expr),*) => {
|
||||
{
|
||||
let _cap = ordermap!(@count $($key),*);
|
||||
let mut _map = $crate::OrderMap::with_capacity(_cap);
|
||||
$(
|
||||
_map.insert($key, $value);
|
||||
)*
|
||||
_map
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
/// Create an `OrderSet` from a list of values
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```
|
||||
/// #[macro_use] extern crate ordermap;
|
||||
/// # fn main() {
|
||||
///
|
||||
/// let set = orderset!{
|
||||
/// "a",
|
||||
/// "b",
|
||||
/// };
|
||||
/// assert!(set.contains("a"));
|
||||
/// assert!(set.contains("b"));
|
||||
/// assert!(!set.contains("c"));
|
||||
///
|
||||
/// // "a" is the first value
|
||||
/// assert_eq!(set.iter().next(), Some(&"a"));
|
||||
/// # }
|
||||
/// ```
|
||||
macro_rules! orderset {
|
||||
(@single $($x:tt)*) => (());
|
||||
(@count $($rest:expr),*) => (<[()]>::len(&[$(orderset!(@single $rest)),*]));
|
||||
|
||||
($($value:expr,)+) => { orderset!($($value),+) };
|
||||
($($value:expr),*) => {
|
||||
{
|
||||
let _cap = orderset!(@count $($value),*);
|
||||
let mut _set = $crate::OrderSet::with_capacity(_cap);
|
||||
$(
|
||||
_set.insert($value);
|
||||
)*
|
||||
_set
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// generate all the Iterator methods by just forwarding to the underlying
|
||||
// self.iter and mapping its element.
|
||||
macro_rules! iterator_methods {
|
||||
// $map_elt is the mapping function from the underlying iterator's element
|
||||
// same mapping function for both options and iterators
|
||||
($map_elt:expr) => {
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.iter.next().map($map_elt)
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
|
||||
fn count(self) -> usize {
|
||||
self.iter.len()
|
||||
}
|
||||
|
||||
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
||||
self.iter.nth(n).map($map_elt)
|
||||
}
|
||||
|
||||
fn last(mut self) -> Option<Self::Item> {
|
||||
self.next_back()
|
||||
}
|
||||
|
||||
fn collect<C>(self) -> C
|
||||
where C: FromIterator<Self::Item>
|
||||
{
|
||||
// NB: forwarding this directly to standard iterators will
|
||||
// allow it to leverage unstable traits like `TrustedLen`.
|
||||
self.iter.map($map_elt).collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! double_ended_iterator_methods {
|
||||
// $map_elt is the mapping function from the underlying iterator's element
|
||||
// same mapping function for both options and iterators
|
||||
($map_elt:expr) => {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
self.iter.next_back().map($map_elt)
|
||||
}
|
||||
}
|
||||
}
|
76
third_party/rust/ordermap/src/mutable_keys.rs
vendored
Normal file
76
third_party/rust/ordermap/src/mutable_keys.rs
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
use std::hash::Hash;
|
||||
use std::hash::BuildHasher;
|
||||
|
||||
use super::{OrderMap, Equivalent};
|
||||
|
||||
pub struct PrivateMarker { }
|
||||
|
||||
/// Opt-in mutable access to keys.
|
||||
///
|
||||
/// These methods expose `&mut K`, mutable references to the key as it is stored
|
||||
/// in the map.
|
||||
/// You are allowed to modify the keys in the hashmap **if the modifcation
|
||||
/// does not change the key’s hash and equality**.
|
||||
///
|
||||
/// If keys are modified erronously, you can no longer look them up.
|
||||
/// This is sound (memory safe) but a logical error hazard (just like
|
||||
/// implementing PartialEq, Eq, or Hash incorrectly would be).
|
||||
///
|
||||
/// `use` this trait to enable its methods for `OrderMap`.
|
||||
pub trait MutableKeys {
|
||||
type Key;
|
||||
type Value;
|
||||
|
||||
/// Return item index, mutable reference to key and value
|
||||
fn get_full_mut2<Q: ?Sized>(&mut self, key: &Q)
|
||||
-> Option<(usize, &mut Self::Key, &mut Self::Value)>
|
||||
where Q: Hash + Equivalent<Self::Key>;
|
||||
|
||||
/// Scan through each key-value pair in the map and keep those where the
|
||||
/// closure `keep` returns `true`.
|
||||
///
|
||||
/// The elements are visited in order, and remaining elements keep their
|
||||
/// order.
|
||||
///
|
||||
/// Computes in **O(n)** time (average).
|
||||
fn retain2<F>(&mut self, keep: F)
|
||||
where F: FnMut(&mut Self::Key, &mut Self::Value) -> bool;
|
||||
|
||||
/// This method is not useful in itself – it is there to “seal” the trait
|
||||
/// for external implementation, so that we can add methods without
|
||||
/// causing breaking changes.
|
||||
fn __private_marker(&self) -> PrivateMarker;
|
||||
}
|
||||
|
||||
/// Opt-in mutable access to keys.
|
||||
///
|
||||
/// See [`MutableKeys`](trait.MutableKeys.html) for more information.
|
||||
impl<K, V, S> MutableKeys for OrderMap<K, V, S>
|
||||
where K: Eq + Hash,
|
||||
S: BuildHasher,
|
||||
{
|
||||
type Key = K;
|
||||
type Value = V;
|
||||
fn get_full_mut2<Q: ?Sized>(&mut self, key: &Q)
|
||||
-> Option<(usize, &mut K, &mut V)>
|
||||
where Q: Hash + Equivalent<K>,
|
||||
{
|
||||
if let Some((_, found)) = self.find(key) {
|
||||
let entry = &mut self.entries[found];
|
||||
Some((found, &mut entry.key, &mut entry.value))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn retain2<F>(&mut self, keep: F)
|
||||
where F: FnMut(&mut K, &mut V) -> bool,
|
||||
{
|
||||
self.retain_mut(keep)
|
||||
}
|
||||
|
||||
fn __private_marker(&self) -> PrivateMarker {
|
||||
PrivateMarker { }
|
||||
}
|
||||
}
|
123
third_party/rust/ordermap/src/serde.rs
vendored
Normal file
123
third_party/rust/ordermap/src/serde.rs
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
|
||||
extern crate serde;
|
||||
|
||||
use self::serde::ser::{Serialize, Serializer, SerializeMap, SerializeSeq};
|
||||
use self::serde::de::{Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
|
||||
|
||||
use std::fmt::{self, Formatter};
|
||||
use std::hash::{BuildHasher, Hash};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use OrderMap;
|
||||
|
||||
/// Requires crate feature `"serde-1"`
|
||||
impl<K, V, S> Serialize for OrderMap<K, V, S>
|
||||
where K: Serialize + Hash + Eq,
|
||||
V: Serialize,
|
||||
S: BuildHasher
|
||||
{
|
||||
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
|
||||
where T: Serializer
|
||||
{
|
||||
let mut map_serializer = try!(serializer.serialize_map(Some(self.len())));
|
||||
for (key, value) in self {
|
||||
try!(map_serializer.serialize_entry(key, value));
|
||||
}
|
||||
map_serializer.end()
|
||||
}
|
||||
}
|
||||
|
||||
struct OrderMapVisitor<K, V, S>(PhantomData<(K, V, S)>);
|
||||
|
||||
impl<'de, K, V, S> Visitor<'de> for OrderMapVisitor<K, V, S>
|
||||
where K: Deserialize<'de> + Eq + Hash,
|
||||
V: Deserialize<'de>,
|
||||
S: Default + BuildHasher
|
||||
{
|
||||
type Value = OrderMap<K, V, S>;
|
||||
|
||||
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
|
||||
write!(formatter, "a map")
|
||||
}
|
||||
|
||||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||
where A: MapAccess<'de>
|
||||
{
|
||||
let mut values = OrderMap::with_capacity_and_hasher(map.size_hint().unwrap_or(0), S::default());
|
||||
|
||||
while let Some((key, value)) = try!(map.next_entry()) {
|
||||
values.insert(key, value);
|
||||
}
|
||||
|
||||
Ok(values)
|
||||
}
|
||||
}
|
||||
|
||||
/// Requires crate feature `"serde-1"`
|
||||
impl<'de, K, V, S> Deserialize<'de> for OrderMap<K, V, S>
|
||||
where K: Deserialize<'de> + Eq + Hash,
|
||||
V: Deserialize<'de>,
|
||||
S: Default + BuildHasher
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where D: Deserializer<'de>
|
||||
{
|
||||
deserializer.deserialize_map(OrderMapVisitor(PhantomData))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
use OrderSet;
|
||||
|
||||
/// Requires crate feature `"serde-1"`
|
||||
impl<T, S> Serialize for OrderSet<T, S>
|
||||
where T: Serialize + Hash + Eq,
|
||||
S: BuildHasher
|
||||
{
|
||||
fn serialize<Se>(&self, serializer: Se) -> Result<Se::Ok, Se::Error>
|
||||
where Se: Serializer
|
||||
{
|
||||
let mut set_serializer = try!(serializer.serialize_seq(Some(self.len())));
|
||||
for value in self {
|
||||
try!(set_serializer.serialize_element(value));
|
||||
}
|
||||
set_serializer.end()
|
||||
}
|
||||
}
|
||||
|
||||
struct OrderSetVisitor<T, S>(PhantomData<(T, S)>);
|
||||
|
||||
impl<'de, T, S> Visitor<'de> for OrderSetVisitor<T, S>
|
||||
where T: Deserialize<'de> + Eq + Hash,
|
||||
S: Default + BuildHasher
|
||||
{
|
||||
type Value = OrderSet<T, S>;
|
||||
|
||||
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
|
||||
write!(formatter, "a set")
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where A: SeqAccess<'de>
|
||||
{
|
||||
let mut values = OrderSet::with_capacity_and_hasher(seq.size_hint().unwrap_or(0), S::default());
|
||||
|
||||
while let Some(value) = try!(seq.next_element()) {
|
||||
values.insert(value);
|
||||
}
|
||||
|
||||
Ok(values)
|
||||
}
|
||||
}
|
||||
|
||||
/// Requires crate feature `"serde-1"`
|
||||
impl<'de, T, S> Deserialize<'de> for OrderSet<T, S>
|
||||
where T: Deserialize<'de> + Eq + Hash,
|
||||
S: Default + BuildHasher
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where D: Deserializer<'de>
|
||||
{
|
||||
deserializer.deserialize_seq(OrderSetVisitor(PhantomData))
|
||||
}
|
||||
}
|
1136
third_party/rust/ordermap/src/set.rs
vendored
Normal file
1136
third_party/rust/ordermap/src/set.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
17
third_party/rust/ordermap/src/util.rs
vendored
Normal file
17
third_party/rust/ordermap/src/util.rs
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
use std::iter::Enumerate;
|
||||
use std::mem::size_of;
|
||||
|
||||
pub fn third<A, B, C>(t: (A, B, C)) -> C { t.2 }
|
||||
|
||||
pub fn enumerate<I>(iterable: I) -> Enumerate<I::IntoIter>
|
||||
where I: IntoIterator
|
||||
{
|
||||
iterable.into_iter().enumerate()
|
||||
}
|
||||
|
||||
/// return the number of steps from a to b
|
||||
pub fn ptrdistance<T>(a: *const T, b: *const T) -> usize {
|
||||
debug_assert!(a as usize <= b as usize);
|
||||
(b as usize - a as usize) / size_of::<T>()
|
||||
}
|
55
third_party/rust/ordermap/tests/equivalent_trait.rs
vendored
Normal file
55
third_party/rust/ordermap/tests/equivalent_trait.rs
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
#[macro_use] extern crate ordermap;
|
||||
|
||||
use ordermap::Equivalent;
|
||||
|
||||
use std::hash::Hash;
|
||||
|
||||
#[derive(Debug, Hash)]
|
||||
pub struct Pair<A, B>(pub A, pub B);
|
||||
|
||||
impl<A, B, C, D> PartialEq<(A, B)> for Pair<C, D>
|
||||
where C: PartialEq<A>,
|
||||
D: PartialEq<B>,
|
||||
{
|
||||
fn eq(&self, rhs: &(A, B)) -> bool {
|
||||
self.0 == rhs.0 &&
|
||||
self.1 == rhs.1 &&
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B, X> Equivalent<X> for Pair<A, B>
|
||||
where Pair<A, B>: PartialEq<X>,
|
||||
A: Hash + Eq,
|
||||
B: Hash + Eq,
|
||||
{
|
||||
fn equivalent(&self, other: &X) -> bool {
|
||||
*self == *other
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lookup() {
|
||||
let s = String::from;
|
||||
let map = ordermap! {
|
||||
(s("a"), s("b")) => 1,
|
||||
(s("a"), s("x")) => 2,
|
||||
};
|
||||
|
||||
assert!(map.contains_key(&Pair("a", "b")));
|
||||
assert!(!map.contains_key(&Pair("b", "a")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_string_str() {
|
||||
let s = String::from;
|
||||
let mut map = ordermap! {
|
||||
s("a") => 1, s("b") => 2,
|
||||
s("x") => 3, s("y") => 4,
|
||||
};
|
||||
|
||||
assert!(map.contains_key("a"));
|
||||
assert!(!map.contains_key("z"));
|
||||
assert_eq!(map.remove("b"), Some(2));
|
||||
}
|
365
third_party/rust/ordermap/tests/quick.rs
vendored
Normal file
365
third_party/rust/ordermap/tests/quick.rs
vendored
Normal file
@ -0,0 +1,365 @@
|
||||
|
||||
extern crate ordermap;
|
||||
extern crate itertools;
|
||||
#[macro_use]
|
||||
extern crate quickcheck;
|
||||
|
||||
extern crate fnv;
|
||||
|
||||
use ordermap::OrderMap;
|
||||
use itertools::Itertools;
|
||||
|
||||
use quickcheck::Arbitrary;
|
||||
use quickcheck::Gen;
|
||||
|
||||
use fnv::FnvHasher;
|
||||
use std::hash::{BuildHasher, BuildHasherDefault};
|
||||
type FnvBuilder = BuildHasherDefault<FnvHasher>;
|
||||
type OrderMapFnv<K, V> = OrderMap<K, V, FnvBuilder>;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::collections::HashMap;
|
||||
use std::iter::FromIterator;
|
||||
use std::hash::Hash;
|
||||
use std::fmt::Debug;
|
||||
use std::ops::Deref;
|
||||
use std::cmp::min;
|
||||
|
||||
|
||||
use ordermap::Entry as OEntry;
|
||||
use std::collections::hash_map::Entry as HEntry;
|
||||
|
||||
|
||||
fn set<'a, T: 'a, I>(iter: I) -> HashSet<T>
|
||||
where I: IntoIterator<Item=&'a T>,
|
||||
T: Copy + Hash + Eq
|
||||
{
|
||||
iter.into_iter().cloned().collect()
|
||||
}
|
||||
|
||||
fn ordermap<'a, T: 'a, I>(iter: I) -> OrderMap<T, ()>
|
||||
where I: IntoIterator<Item=&'a T>,
|
||||
T: Copy + Hash + Eq,
|
||||
{
|
||||
OrderMap::from_iter(iter.into_iter().cloned().map(|k| (k, ())))
|
||||
}
|
||||
|
||||
quickcheck! {
|
||||
fn contains(insert: Vec<u32>) -> bool {
|
||||
let mut map = OrderMap::new();
|
||||
for &key in &insert {
|
||||
map.insert(key, ());
|
||||
}
|
||||
insert.iter().all(|&key| map.get(&key).is_some())
|
||||
}
|
||||
|
||||
fn contains_not(insert: Vec<u8>, not: Vec<u8>) -> bool {
|
||||
let mut map = OrderMap::new();
|
||||
for &key in &insert {
|
||||
map.insert(key, ());
|
||||
}
|
||||
let nots = &set(¬) - &set(&insert);
|
||||
nots.iter().all(|&key| map.get(&key).is_none())
|
||||
}
|
||||
|
||||
fn insert_remove(insert: Vec<u8>, remove: Vec<u8>) -> bool {
|
||||
let mut map = OrderMap::new();
|
||||
for &key in &insert {
|
||||
map.insert(key, ());
|
||||
}
|
||||
for &key in &remove {
|
||||
map.swap_remove(&key);
|
||||
}
|
||||
let elements = &set(&insert) - &set(&remove);
|
||||
map.len() == elements.len() && map.iter().count() == elements.len() &&
|
||||
elements.iter().all(|k| map.get(k).is_some())
|
||||
}
|
||||
|
||||
fn insertion_order(insert: Vec<u32>) -> bool {
|
||||
let mut map = OrderMap::new();
|
||||
for &key in &insert {
|
||||
map.insert(key, ());
|
||||
}
|
||||
itertools::assert_equal(insert.iter().unique(), map.keys());
|
||||
true
|
||||
}
|
||||
|
||||
fn pop(insert: Vec<u8>) -> bool {
|
||||
let mut map = OrderMap::new();
|
||||
for &key in &insert {
|
||||
map.insert(key, ());
|
||||
}
|
||||
let mut pops = Vec::new();
|
||||
while let Some((key, _v)) = map.pop() {
|
||||
pops.push(key);
|
||||
}
|
||||
pops.reverse();
|
||||
|
||||
itertools::assert_equal(insert.iter().unique(), &pops);
|
||||
true
|
||||
}
|
||||
|
||||
fn with_cap(cap: usize) -> bool {
|
||||
let map: OrderMap<u8, u8> = OrderMap::with_capacity(cap);
|
||||
println!("wish: {}, got: {} (diff: {})", cap, map.capacity(), map.capacity() as isize - cap as isize);
|
||||
map.capacity() >= cap
|
||||
}
|
||||
|
||||
fn drain(insert: Vec<u8>) -> bool {
|
||||
let mut map = OrderMap::new();
|
||||
for &key in &insert {
|
||||
map.insert(key, ());
|
||||
}
|
||||
let mut clone = map.clone();
|
||||
let drained = clone.drain(..);
|
||||
for (key, _) in drained {
|
||||
map.remove(&key);
|
||||
}
|
||||
map.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
use Op::*;
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum Op<K, V> {
|
||||
Add(K, V),
|
||||
Remove(K),
|
||||
AddEntry(K, V),
|
||||
RemoveEntry(K),
|
||||
}
|
||||
|
||||
impl<K, V> Arbitrary for Op<K, V>
|
||||
where K: Arbitrary,
|
||||
V: Arbitrary,
|
||||
{
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Self {
|
||||
match g.gen::<u32>() % 4 {
|
||||
0 => Add(K::arbitrary(g), V::arbitrary(g)),
|
||||
1 => AddEntry(K::arbitrary(g), V::arbitrary(g)),
|
||||
2 => Remove(K::arbitrary(g)),
|
||||
_ => RemoveEntry(K::arbitrary(g)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn do_ops<K, V, S>(ops: &[Op<K, V>], a: &mut OrderMap<K, V, S>, b: &mut HashMap<K, V>)
|
||||
where K: Hash + Eq + Clone,
|
||||
V: Clone,
|
||||
S: BuildHasher,
|
||||
{
|
||||
for op in ops {
|
||||
match *op {
|
||||
Add(ref k, ref v) => {
|
||||
a.insert(k.clone(), v.clone());
|
||||
b.insert(k.clone(), v.clone());
|
||||
}
|
||||
AddEntry(ref k, ref v) => {
|
||||
a.entry(k.clone()).or_insert(v.clone());
|
||||
b.entry(k.clone()).or_insert(v.clone());
|
||||
}
|
||||
Remove(ref k) => {
|
||||
a.swap_remove(k);
|
||||
b.remove(k);
|
||||
}
|
||||
RemoveEntry(ref k) => {
|
||||
match a.entry(k.clone()) {
|
||||
OEntry::Occupied(ent) => { ent.remove_entry(); },
|
||||
_ => { }
|
||||
}
|
||||
match b.entry(k.clone()) {
|
||||
HEntry::Occupied(ent) => { ent.remove_entry(); },
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
}
|
||||
//println!("{:?}", a);
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_maps_equivalent<K, V>(a: &OrderMap<K, V>, b: &HashMap<K, V>) -> bool
|
||||
where K: Hash + Eq + Debug,
|
||||
V: Eq + Debug,
|
||||
{
|
||||
assert_eq!(a.len(), b.len());
|
||||
assert_eq!(a.iter().next().is_some(), b.iter().next().is_some());
|
||||
for key in a.keys() {
|
||||
assert!(b.contains_key(key), "b does not contain {:?}", key);
|
||||
}
|
||||
for key in b.keys() {
|
||||
assert!(a.get(key).is_some(), "a does not contain {:?}", key);
|
||||
}
|
||||
for key in a.keys() {
|
||||
assert_eq!(a[key], b[key]);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
quickcheck! {
|
||||
fn operations_i8(ops: Large<Vec<Op<i8, i8>>>) -> bool {
|
||||
let mut map = OrderMap::new();
|
||||
let mut reference = HashMap::new();
|
||||
do_ops(&ops, &mut map, &mut reference);
|
||||
assert_maps_equivalent(&map, &reference)
|
||||
}
|
||||
|
||||
fn operations_string(ops: Vec<Op<Alpha, i8>>) -> bool {
|
||||
let mut map = OrderMap::new();
|
||||
let mut reference = HashMap::new();
|
||||
do_ops(&ops, &mut map, &mut reference);
|
||||
assert_maps_equivalent(&map, &reference)
|
||||
}
|
||||
|
||||
fn keys_values(ops: Large<Vec<Op<i8, i8>>>) -> bool {
|
||||
let mut map = OrderMap::new();
|
||||
let mut reference = HashMap::new();
|
||||
do_ops(&ops, &mut map, &mut reference);
|
||||
let mut visit = OrderMap::new();
|
||||
for (k, v) in map.keys().zip(map.values()) {
|
||||
assert_eq!(&map[k], v);
|
||||
assert!(!visit.contains_key(k));
|
||||
visit.insert(*k, *v);
|
||||
}
|
||||
assert_eq!(visit.len(), reference.len());
|
||||
true
|
||||
}
|
||||
|
||||
fn keys_values_mut(ops: Large<Vec<Op<i8, i8>>>) -> bool {
|
||||
let mut map = OrderMap::new();
|
||||
let mut reference = HashMap::new();
|
||||
do_ops(&ops, &mut map, &mut reference);
|
||||
let mut visit = OrderMap::new();
|
||||
let keys = Vec::from_iter(map.keys().cloned());
|
||||
for (k, v) in keys.iter().zip(map.values_mut()) {
|
||||
assert_eq!(&reference[k], v);
|
||||
assert!(!visit.contains_key(k));
|
||||
visit.insert(*k, *v);
|
||||
}
|
||||
assert_eq!(visit.len(), reference.len());
|
||||
true
|
||||
}
|
||||
|
||||
fn equality(ops1: Vec<Op<i8, i8>>, removes: Vec<usize>) -> bool {
|
||||
let mut map = OrderMap::new();
|
||||
let mut reference = HashMap::new();
|
||||
do_ops(&ops1, &mut map, &mut reference);
|
||||
let mut ops2 = ops1.clone();
|
||||
for &r in &removes {
|
||||
if !ops2.is_empty() {
|
||||
let i = r % ops2.len();
|
||||
ops2.remove(i);
|
||||
}
|
||||
}
|
||||
let mut map2 = OrderMapFnv::default();
|
||||
let mut reference2 = HashMap::new();
|
||||
do_ops(&ops2, &mut map2, &mut reference2);
|
||||
assert_eq!(map == map2, reference == reference2);
|
||||
true
|
||||
}
|
||||
|
||||
fn retain_ordered(keys: Large<Vec<i8>>, remove: Large<Vec<i8>>) -> () {
|
||||
let mut map = ordermap(keys.iter());
|
||||
let initial_map = map.clone(); // deduplicated in-order input
|
||||
let remove_map = ordermap(remove.iter());
|
||||
let keys_s = set(keys.iter());
|
||||
let remove_s = set(remove.iter());
|
||||
let answer = &keys_s - &remove_s;
|
||||
map.retain(|k, _| !remove_map.contains_key(k));
|
||||
|
||||
// check the values
|
||||
assert_eq!(map.len(), answer.len());
|
||||
for key in &answer {
|
||||
assert!(map.contains_key(key));
|
||||
}
|
||||
// check the order
|
||||
itertools::assert_equal(map.keys(), initial_map.keys().filter(|&k| !remove_map.contains_key(k)));
|
||||
}
|
||||
|
||||
fn sort_1(keyvals: Large<Vec<(i8, i8)>>) -> () {
|
||||
let mut map: OrderMap<_, _> = OrderMap::from_iter(keyvals.to_vec());
|
||||
let mut answer = keyvals.0;
|
||||
answer.sort_by_key(|t| t.0);
|
||||
|
||||
// reverse dedup: Because OrderMap::from_iter keeps the last value for
|
||||
// identical keys
|
||||
answer.reverse();
|
||||
answer.dedup_by_key(|t| t.0);
|
||||
answer.reverse();
|
||||
|
||||
map.sort_by(|k1, _, k2, _| Ord::cmp(k1, k2));
|
||||
|
||||
// check it contains all the values it should
|
||||
for &(key, val) in &answer {
|
||||
assert_eq!(map[&key], val);
|
||||
}
|
||||
|
||||
// check the order
|
||||
|
||||
let mapv = Vec::from_iter(map);
|
||||
assert_eq!(answer, mapv);
|
||||
|
||||
}
|
||||
|
||||
fn sort_2(keyvals: Large<Vec<(i8, i8)>>) -> () {
|
||||
let mut map: OrderMap<_, _> = OrderMap::from_iter(keyvals.to_vec());
|
||||
map.sort_by(|_, v1, _, v2| Ord::cmp(v1, v2));
|
||||
assert_sorted_by_key(map, |t| t.1);
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_sorted_by_key<I, Key, X>(iterable: I, key: Key)
|
||||
where I: IntoIterator,
|
||||
I::Item: Ord + Clone + Debug,
|
||||
Key: Fn(&I::Item) -> X,
|
||||
X: Ord,
|
||||
{
|
||||
let input = Vec::from_iter(iterable);
|
||||
let mut sorted = input.clone();
|
||||
sorted.sort_by_key(key);
|
||||
assert_eq!(input, sorted);
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
struct Alpha(String);
|
||||
|
||||
impl Deref for Alpha {
|
||||
type Target = String;
|
||||
fn deref(&self) -> &String { &self.0 }
|
||||
}
|
||||
|
||||
const ALPHABET: &'static [u8] = b"abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
impl Arbitrary for Alpha {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Self {
|
||||
let len = g.next_u32() % g.size() as u32;
|
||||
let len = min(len, 16);
|
||||
Alpha((0..len).map(|_| {
|
||||
ALPHABET[g.next_u32() as usize % ALPHABET.len()] as char
|
||||
}).collect())
|
||||
}
|
||||
|
||||
fn shrink(&self) -> Box<Iterator<Item=Self>> {
|
||||
Box::new((**self).shrink().map(Alpha))
|
||||
}
|
||||
}
|
||||
|
||||
/// quickcheck Arbitrary adaptor -- make a larger vec
|
||||
#[derive(Clone, Debug)]
|
||||
struct Large<T>(T);
|
||||
|
||||
impl<T> Deref for Large<T> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &T { &self.0 }
|
||||
}
|
||||
|
||||
impl<T> Arbitrary for Large<Vec<T>>
|
||||
where T: Arbitrary
|
||||
{
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> Self {
|
||||
let len = g.next_u32() % (g.size() * 10) as u32;
|
||||
Large((0..len).map(|_| T::arbitrary(g)).collect())
|
||||
}
|
||||
|
||||
fn shrink(&self) -> Box<Iterator<Item=Self>> {
|
||||
Box::new((**self).shrink().map(Large))
|
||||
}
|
||||
}
|
59
third_party/rust/ordermap/tests/serde.rs
vendored
Normal file
59
third_party/rust/ordermap/tests/serde.rs
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
#![cfg(feature = "serde-1")]
|
||||
|
||||
#[macro_use]
|
||||
extern crate ordermap;
|
||||
extern crate serde_test;
|
||||
extern crate fnv;
|
||||
|
||||
use serde_test::{Token, assert_tokens};
|
||||
|
||||
#[test]
|
||||
fn test_serde() {
|
||||
let map = ordermap! { 1 => 2, 3 => 4 };
|
||||
assert_tokens(&map,
|
||||
&[Token::Map { len: Some(2) },
|
||||
Token::I32(1),
|
||||
Token::I32(2),
|
||||
Token::I32(3),
|
||||
Token::I32(4),
|
||||
Token::MapEnd]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serde_set() {
|
||||
let set = orderset! { 1, 2, 3, 4 };
|
||||
assert_tokens(&set,
|
||||
&[Token::Seq { len: Some(4) },
|
||||
Token::I32(1),
|
||||
Token::I32(2),
|
||||
Token::I32(3),
|
||||
Token::I32(4),
|
||||
Token::SeqEnd]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serde_fnv_hasher() {
|
||||
let mut map: ::ordermap::OrderMap<i32, i32, ::fnv::FnvBuildHasher> = Default::default();
|
||||
map.insert(1, 2);
|
||||
map.insert(3, 4);
|
||||
assert_tokens(&map,
|
||||
&[Token::Map { len: Some(2) },
|
||||
Token::I32(1),
|
||||
Token::I32(2),
|
||||
Token::I32(3),
|
||||
Token::I32(4),
|
||||
Token::MapEnd]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serde_map_fnv_hasher() {
|
||||
let mut set: ::ordermap::OrderSet<i32, ::fnv::FnvBuildHasher> = Default::default();
|
||||
set.extend(1..5);
|
||||
assert_tokens(&set,
|
||||
&[Token::Seq { len: Some(4) },
|
||||
Token::I32(1),
|
||||
Token::I32(2),
|
||||
Token::I32(3),
|
||||
Token::I32(4),
|
||||
Token::SeqEnd]);
|
||||
}
|
32
third_party/rust/ordermap/tests/tests.rs
vendored
Normal file
32
third_party/rust/ordermap/tests/tests.rs
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
#[macro_use]
|
||||
extern crate ordermap;
|
||||
extern crate itertools;
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_sort() {
|
||||
let m = ordermap! {
|
||||
1 => 2,
|
||||
7 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
};
|
||||
|
||||
itertools::assert_equal(m.sorted_by(|_k1, v1, _k2, v2| v1.cmp(v2)),
|
||||
vec![(7, 1), (1, 2), (2, 2), (3, 3)]);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_sort_set() {
|
||||
let s = orderset! {
|
||||
1,
|
||||
7,
|
||||
2,
|
||||
3,
|
||||
};
|
||||
|
||||
itertools::assert_equal(s.sorted_by(|v1, v2| v1.cmp(v2)),
|
||||
vec![1, 2, 3, 7]);
|
||||
}
|
8
toolkit/library/gtest/rust/Cargo.lock
generated
8
toolkit/library/gtest/rust/Cargo.lock
generated
@ -632,6 +632,7 @@ name = "hashglobe"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -752,6 +753,7 @@ dependencies = [
|
||||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashglobe 0.1.0",
|
||||
"ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"selectors 0.19.0",
|
||||
"servo_arc 0.1.0",
|
||||
"smallbitvec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -941,6 +943,11 @@ dependencies = [
|
||||
"unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordermap"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "owning_ref"
|
||||
version = "0.3.3"
|
||||
@ -1748,6 +1755,7 @@ dependencies = [
|
||||
"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
|
||||
"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d"
|
||||
"checksum ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da12c96037889ae0be29dd2bdd260e5a62a7df24e6466d5a15bb8131c1c200a8"
|
||||
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
|
||||
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
|
||||
"checksum parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "37f364e2ce5efa24c7d0b6646d5bb61145551a0112f107ffd7499f1a3e322fbd"
|
||||
"checksum parking_lot_core 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6c677d78851950b3aec390e681a411f78cc250cba277d4f578758a377f727970"
|
||||
|
8
toolkit/library/rust/Cargo.lock
generated
8
toolkit/library/rust/Cargo.lock
generated
@ -630,6 +630,7 @@ name = "hashglobe"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -750,6 +751,7 @@ dependencies = [
|
||||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashglobe 0.1.0",
|
||||
"ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"selectors 0.19.0",
|
||||
"servo_arc 0.1.0",
|
||||
"smallbitvec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -928,6 +930,11 @@ dependencies = [
|
||||
"unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordermap"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "owning_ref"
|
||||
version = "0.3.3"
|
||||
@ -1750,6 +1757,7 @@ dependencies = [
|
||||
"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
|
||||
"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d"
|
||||
"checksum ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da12c96037889ae0be29dd2bdd260e5a62a7df24e6466d5a15bb8131c1c200a8"
|
||||
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
|
||||
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
|
||||
"checksum parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "37f364e2ce5efa24c7d0b6646d5bb61145551a0112f107ffd7499f1a3e322fbd"
|
||||
"checksum parking_lot_core 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6c677d78851950b3aec390e681a411f78cc250cba277d4f578758a377f727970"
|
||||
|
Loading…
Reference in New Issue
Block a user