diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /vendor/phf | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | vendor/phf/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | vendor/phf/Cargo.toml | 49 | ||||
-rw-r--r-- | vendor/phf/src/lib.rs | 157 | ||||
-rw-r--r-- | vendor/phf/src/map.rs | 301 | ||||
-rw-r--r-- | vendor/phf/src/ordered_map.rs | 312 | ||||
-rw-r--r-- | vendor/phf/src/ordered_set.rs | 170 | ||||
-rw-r--r-- | vendor/phf/src/set.rs | 147 | ||||
-rw-r--r-- | vendor/phf_codegen/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | vendor/phf_codegen/Cargo.toml | 25 | ||||
-rw-r--r-- | vendor/phf_codegen/src/lib.rs | 486 | ||||
-rw-r--r-- | vendor/phf_generator/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | vendor/phf_generator/Cargo.lock | 679 | ||||
-rw-r--r-- | vendor/phf_generator/Cargo.toml | 40 | ||||
-rw-r--r-- | vendor/phf_generator/benches/benches.rs | 58 | ||||
-rw-r--r-- | vendor/phf_generator/src/bin/gen_hash_test.rs | 20 | ||||
-rw-r--r-- | vendor/phf_generator/src/lib.rs | 105 | ||||
-rw-r--r-- | vendor/phf_shared/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | vendor/phf_shared/Cargo.toml | 39 | ||||
-rw-r--r-- | vendor/phf_shared/src/lib.rs | 421 |
19 files changed, 3013 insertions, 0 deletions
diff --git a/vendor/phf/.cargo-checksum.json b/vendor/phf/.cargo-checksum.json new file mode 100644 index 000000000..7c54676c1 --- /dev/null +++ b/vendor/phf/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"29149d1a0e11a422264675eb6229a7827acf187d1c5f8cc4b9c1cb2bf4ac9ae4","src/lib.rs":"a4d7dede221bdc3d69939a066a058e1a627e57777f7beab1baa93e452eb8fe67","src/map.rs":"755c39145d701560be45c731e81f9e3e60c884d00d1b6dea8e4614f9278a9d88","src/ordered_map.rs":"0b18597047bd5c782ccd4b2f54122e88cd020f930aa6f1436c3c5819d729decf","src/ordered_set.rs":"0ed66947623c8a79b1ad2c206ef5a13af701f95c0f36544ab986c9617e2a24a3","src/set.rs":"065a501930c4667877168b99aeca00007dd222865bafc26451cbc9fdf08ad7e6"},"package":"fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"}
\ No newline at end of file diff --git a/vendor/phf/Cargo.toml b/vendor/phf/Cargo.toml new file mode 100644 index 000000000..ca2ce9893 --- /dev/null +++ b/vendor/phf/Cargo.toml @@ -0,0 +1,49 @@ +# 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 are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "phf" +version = "0.10.1" +authors = ["Steven Fackler <sfackler@gmail.com>"] +description = "Runtime support for perfect hash function data structures" +readme = "../README.md" +license = "MIT" +repository = "https://github.com/sfackler/rust-phf" +[package.metadata.docs.rs] +features = ["macros"] + +[lib] +name = "phf" +path = "src/lib.rs" +test = false +[dependencies.phf_macros] +version = "0.10.0" +optional = true + +[dependencies.phf_shared] +version = "0.10.0" +default-features = false + +[dependencies.proc-macro-hack] +version = "0.5.4" +optional = true + +[dependencies.serde] +version = "1.0" +optional = true + +[features] +default = ["std"] +macros = ["phf_macros", "proc-macro-hack"] +std = ["phf_shared/std"] +uncased = ["phf_shared/uncased"] +unicase = ["phf_shared/unicase"] diff --git a/vendor/phf/src/lib.rs b/vendor/phf/src/lib.rs new file mode 100644 index 000000000..e60f524b0 --- /dev/null +++ b/vendor/phf/src/lib.rs @@ -0,0 +1,157 @@ +//! Rust-PHF is a library to generate efficient lookup tables at compile time using +//! [perfect hash functions](http://en.wikipedia.org/wiki/Perfect_hash_function). +//! +//! It currently uses the +//! [CHD algorithm](http://cmph.sourceforge.net/papers/esa09.pdf) and can generate +//! a 100,000 entry map in roughly .4 seconds. By default statistics are not +//! produced, but if you set the environment variable `PHF_STATS` it will issue +//! a compiler note about how long it took. +//! +//! MSRV (minimum supported rust version) is Rust 1.46. +//! +//! ## Usage +//! +//! PHF data structures can be constructed via either the procedural +//! macros in the `phf_macros` crate or code generation supported by the +//! `phf_codegen` crate. If you prefer macros, you can easily use them by +//! enabling the `macros` feature of the `phf` crate, like: +//! +//!```toml +//! [dependencies] +//! phf = { version = "0.10", features = ["macros"] } +//! ``` +//! +//! To compile the `phf` crate with a dependency on +//! libcore instead of libstd, enabling use in environments where libstd +//! will not work, set `default-features = false` for the dependency: +//! +//! ```toml +//! [dependencies] +//! # to use `phf` in `no_std` environments +//! phf = { version = "0.10", default-features = false } +//! ``` +//! +//! ## Example (with the `macros` feature enabled) +//! +//! ```rust +//! use phf::phf_map; +//! +//! #[derive(Clone)] +//! pub enum Keyword { +//! Loop, +//! Continue, +//! Break, +//! Fn, +//! Extern, +//! } +//! +//! static KEYWORDS: phf::Map<&'static str, Keyword> = phf_map! { +//! "loop" => Keyword::Loop, +//! "continue" => Keyword::Continue, +//! "break" => Keyword::Break, +//! "fn" => Keyword::Fn, +//! "extern" => Keyword::Extern, +//! }; +//! +//! pub fn parse_keyword(keyword: &str) -> Option<Keyword> { +//! KEYWORDS.get(keyword).cloned() +//! } +//! ``` +//! +//! Alternatively, you can use the [`phf_codegen`] crate to generate PHF datatypes +//! in a build script. +//! +//! [`phf_codegen`]: https://docs.rs/phf_codegen +//! +//! ## Note +//! +//! Currently, the macro syntax has some limitations and may not +//! work as you want. See [#183] or [#196] for example. +//! +//! [#183]: https://github.com/rust-phf/rust-phf/issues/183 +//! [#196]: https://github.com/rust-phf/rust-phf/issues/196 + +#![doc(html_root_url = "https://docs.rs/phf/0.10")] +#![warn(missing_docs)] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "std")] +extern crate std as core; + +#[cfg(feature = "macros")] +/// Macro to create a `static` (compile-time) [`Map`]. +/// +/// Requires the `macros` feature. +/// +/// Supported key expressions are: +/// - literals: bools, (byte) strings, bytes, chars, and integers (these must have a type suffix) +/// - arrays of `u8` integers +/// - `UniCase::unicode(string)` or `UniCase::ascii(string)` if the `unicase` feature is enabled +/// +/// # Example +/// +/// ``` +/// use phf::{phf_map, Map}; +/// +/// static MY_MAP: Map<&'static str, u32> = phf_map! { +/// "hello" => 1, +/// "world" => 2, +/// }; +/// +/// fn main () { +/// assert_eq!(MY_MAP["hello"], 1); +/// } +/// ``` +#[proc_macro_hack::proc_macro_hack] +pub use phf_macros::phf_map; + +#[cfg(feature = "macros")] +/// Macro to create a `static` (compile-time) [`OrderedMap`]. +/// +/// Requires the `macros` feature. Same usage as [`phf_map`]. +#[proc_macro_hack::proc_macro_hack] +pub use phf_macros::phf_ordered_map; + +#[cfg(feature = "macros")] +/// Macro to create a `static` (compile-time) [`Set`]. +/// +/// Requires the `macros` feature. +/// +/// # Example +/// +/// ``` +/// use phf::{phf_set, Set}; +/// +/// static MY_SET: Set<&'static str> = phf_set! { +/// "hello world", +/// "hola mundo", +/// }; +/// +/// fn main () { +/// assert!(MY_SET.contains("hello world")); +/// } +/// ``` +#[proc_macro_hack::proc_macro_hack] +pub use phf_macros::phf_set; + +#[cfg(feature = "macros")] +/// Macro to create a `static` (compile-time) [`OrderedSet`]. +/// +/// Requires the `macros` feature. Same usage as [`phf_set`]. +#[proc_macro_hack::proc_macro_hack] +pub use phf_macros::phf_ordered_set; + +#[doc(inline)] +pub use self::map::Map; +#[doc(inline)] +pub use self::ordered_map::OrderedMap; +#[doc(inline)] +pub use self::ordered_set::OrderedSet; +#[doc(inline)] +pub use self::set::Set; +pub use phf_shared::PhfHash; + +pub mod map; +pub mod ordered_map; +pub mod ordered_set; +pub mod set; diff --git a/vendor/phf/src/map.rs b/vendor/phf/src/map.rs new file mode 100644 index 000000000..5b74445c1 --- /dev/null +++ b/vendor/phf/src/map.rs @@ -0,0 +1,301 @@ +//! An immutable map constructed at compile time. +use core::fmt; +use core::iter::FusedIterator; +use core::iter::IntoIterator; +use core::ops::Index; +use core::slice; +use phf_shared::{self, HashKey, PhfBorrow, PhfHash}; +#[cfg(feature = "serde")] +use serde::ser::{Serialize, SerializeMap, Serializer}; + +/// An immutable map constructed at compile time. +/// +/// ## Note +/// +/// The fields of this struct are public so that they may be initialized by the +/// `phf_map!` macro and code generation. They are subject to change at any +/// time and should never be accessed directly. +pub struct Map<K: 'static, V: 'static> { + #[doc(hidden)] + pub key: HashKey, + #[doc(hidden)] + pub disps: &'static [(u32, u32)], + #[doc(hidden)] + pub entries: &'static [(K, V)], +} + +impl<K, V> fmt::Debug for Map<K, V> +where + K: fmt::Debug, + V: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_map().entries(self.entries()).finish() + } +} + +impl<'a, K, V, T: ?Sized> Index<&'a T> for Map<K, V> +where + T: Eq + PhfHash, + K: PhfBorrow<T>, +{ + type Output = V; + + fn index(&self, k: &'a T) -> &V { + self.get(k).expect("invalid key") + } +} + +impl<K, V> Map<K, V> { + /// Returns the number of entries in the `Map`. + #[inline] + pub const fn len(&self) -> usize { + self.entries.len() + } + + /// Returns true if the `Map` is empty. + #[inline] + pub const fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Determines if `key` is in the `Map`. + pub fn contains_key<T: ?Sized>(&self, key: &T) -> bool + where + T: Eq + PhfHash, + K: PhfBorrow<T>, + { + self.get(key).is_some() + } + + /// Returns a reference to the value that `key` maps to. + pub fn get<T: ?Sized>(&self, key: &T) -> Option<&V> + where + T: Eq + PhfHash, + K: PhfBorrow<T>, + { + self.get_entry(key).map(|e| e.1) + } + + /// Returns a reference to the map's internal static instance of the given + /// key. + /// + /// This can be useful for interning schemes. + pub fn get_key<T: ?Sized>(&self, key: &T) -> Option<&K> + where + T: Eq + PhfHash, + K: PhfBorrow<T>, + { + self.get_entry(key).map(|e| e.0) + } + + /// Like `get`, but returns both the key and the value. + pub fn get_entry<T: ?Sized>(&self, key: &T) -> Option<(&K, &V)> + where + T: Eq + PhfHash, + K: PhfBorrow<T>, + { + if self.disps.is_empty() { + return None; + } //Prevent panic on empty map + let hashes = phf_shared::hash(key, &self.key); + let index = phf_shared::get_index(&hashes, &*self.disps, self.entries.len()); + let entry = &self.entries[index as usize]; + let b: &T = entry.0.borrow(); + if b == key { + Some((&entry.0, &entry.1)) + } else { + None + } + } + + /// Returns an iterator over the key/value pairs in the map. + /// + /// Entries are returned in an arbitrary but fixed order. + pub fn entries(&self) -> Entries<'_, K, V> { + Entries { + iter: self.entries.iter(), + } + } + + /// Returns an iterator over the keys in the map. + /// + /// Keys are returned in an arbitrary but fixed order. + pub fn keys(&self) -> Keys<'_, K, V> { + Keys { + iter: self.entries(), + } + } + + /// Returns an iterator over the values in the map. + /// + /// Values are returned in an arbitrary but fixed order. + pub fn values(&self) -> Values<'_, K, V> { + Values { + iter: self.entries(), + } + } +} + +impl<'a, K, V> IntoIterator for &'a Map<K, V> { + type Item = (&'a K, &'a V); + type IntoIter = Entries<'a, K, V>; + + fn into_iter(self) -> Entries<'a, K, V> { + self.entries() + } +} + +/// An iterator over the key/value pairs in a `Map`. +pub struct Entries<'a, K, V> { + iter: slice::Iter<'a, (K, V)>, +} + +impl<'a, K, V> Clone for Entries<'a, K, V> { + #[inline] + fn clone(&self) -> Self { + Self { + iter: self.iter.clone(), + } + } +} + +impl<'a, K, V> fmt::Debug for Entries<'a, K, V> +where + K: fmt::Debug, + V: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list().entries(self.clone()).finish() + } +} + +impl<'a, K, V> Iterator for Entries<'a, K, V> { + type Item = (&'a K, &'a V); + + fn next(&mut self) -> Option<(&'a K, &'a V)> { + self.iter.next().map(|&(ref k, ref v)| (k, v)) + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } +} + +impl<'a, K, V> DoubleEndedIterator for Entries<'a, K, V> { + fn next_back(&mut self) -> Option<(&'a K, &'a V)> { + self.iter.next_back().map(|e| (&e.0, &e.1)) + } +} + +impl<'a, K, V> ExactSizeIterator for Entries<'a, K, V> {} + +impl<'a, K, V> FusedIterator for Entries<'a, K, V> {} + +/// An iterator over the keys in a `Map`. +pub struct Keys<'a, K, V> { + iter: Entries<'a, K, V>, +} + +impl<'a, K, V> Clone for Keys<'a, K, V> { + #[inline] + fn clone(&self) -> Self { + Self { + iter: self.iter.clone(), + } + } +} + +impl<'a, K, V> fmt::Debug for Keys<'a, K, V> +where + K: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list().entries(self.clone()).finish() + } +} + +impl<'a, K, V> Iterator for Keys<'a, K, V> { + type Item = &'a K; + + fn next(&mut self) -> Option<&'a K> { + self.iter.next().map(|e| e.0) + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } +} + +impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> { + fn next_back(&mut self) -> Option<&'a K> { + self.iter.next_back().map(|e| e.0) + } +} + +impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {} + +impl<'a, K, V> FusedIterator for Keys<'a, K, V> {} + +/// An iterator over the values in a `Map`. +pub struct Values<'a, K, V> { + iter: Entries<'a, K, V>, +} + +impl<'a, K, V> Clone for Values<'a, K, V> { + #[inline] + fn clone(&self) -> Self { + Self { + iter: self.iter.clone(), + } + } +} + +impl<'a, K, V> fmt::Debug for Values<'a, K, V> +where + V: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list().entries(self.clone()).finish() + } +} + +impl<'a, K, V> Iterator for Values<'a, K, V> { + type Item = &'a V; + + fn next(&mut self) -> Option<&'a V> { + self.iter.next().map(|e| e.1) + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } +} + +impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> { + fn next_back(&mut self) -> Option<&'a V> { + self.iter.next_back().map(|e| e.1) + } +} + +impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {} + +impl<'a, K, V> FusedIterator for Values<'a, K, V> {} + +#[cfg(feature = "serde")] +impl<K, V> Serialize for Map<K, V> +where + K: Serialize, + V: Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let mut map = serializer.serialize_map(Some(self.len()))?; + for (k, v) in self.entries() { + map.serialize_entry(k, v)?; + } + map.end() + } +} diff --git a/vendor/phf/src/ordered_map.rs b/vendor/phf/src/ordered_map.rs new file mode 100644 index 000000000..c8d5ac59b --- /dev/null +++ b/vendor/phf/src/ordered_map.rs @@ -0,0 +1,312 @@ +//! An order-preserving immutable map constructed at compile time. +use core::fmt; +use core::iter::FusedIterator; +use core::iter::IntoIterator; +use core::ops::Index; +use core::slice; +use phf_shared::{self, HashKey, PhfBorrow, PhfHash}; + +/// An order-preserving immutable map constructed at compile time. +/// +/// Unlike a `Map`, iteration order is guaranteed to match the definition +/// order. +/// +/// ## Note +/// +/// The fields of this struct are public so that they may be initialized by the +/// `phf_ordered_map!` macro and code generation. They are subject to change at +/// any time and should never be accessed directly. +pub struct OrderedMap<K: 'static, V: 'static> { + #[doc(hidden)] + pub key: HashKey, + #[doc(hidden)] + pub disps: &'static [(u32, u32)], + #[doc(hidden)] + pub idxs: &'static [usize], + #[doc(hidden)] + pub entries: &'static [(K, V)], +} + +impl<K, V> fmt::Debug for OrderedMap<K, V> +where + K: fmt::Debug, + V: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_map().entries(self.entries()).finish() + } +} + +impl<'a, K, V, T: ?Sized> Index<&'a T> for OrderedMap<K, V> +where + T: Eq + PhfHash, + K: PhfBorrow<T>, +{ + type Output = V; + + fn index(&self, k: &'a T) -> &V { + self.get(k).expect("invalid key") + } +} + +impl<K, V> OrderedMap<K, V> { + /// Returns the number of entries in the `OrderedMap`. + #[inline] + pub const fn len(&self) -> usize { + self.entries.len() + } + + /// Returns true if the `OrderedMap` is empty. + #[inline] + pub const fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Returns a reference to the value that `key` maps to. + pub fn get<T: ?Sized>(&self, key: &T) -> Option<&V> + where + T: Eq + PhfHash, + K: PhfBorrow<T>, + { + self.get_entry(key).map(|e| e.1) + } + + /// Returns a reference to the map's internal static instance of the given + /// key. + /// + /// This can be useful for interning schemes. + pub fn get_key<T: ?Sized>(&self, key: &T) -> Option<&K> + where + T: Eq + PhfHash, + K: PhfBorrow<T>, + { + self.get_entry(key).map(|e| e.0) + } + + /// Determines if `key` is in the `OrderedMap`. + pub fn contains_key<T: ?Sized>(&self, key: &T) -> bool + where + T: Eq + PhfHash, + K: PhfBorrow<T>, + { + self.get(key).is_some() + } + + /// Returns the index of the key within the list used to initialize + /// the ordered map. + pub fn get_index<T: ?Sized>(&self, key: &T) -> Option<usize> + where + T: Eq + PhfHash, + K: PhfBorrow<T>, + { + self.get_internal(key).map(|(i, _)| i) + } + + /// Returns references to both the key and values at an index + /// within the list used to initialize the ordered map. See `.get_index(key)`. + pub fn index(&self, index: usize) -> Option<(&K, &V)> { + self.entries.get(index).map(|&(ref k, ref v)| (k, v)) + } + + /// Like `get`, but returns both the key and the value. + pub fn get_entry<T: ?Sized>(&self, key: &T) -> Option<(&K, &V)> + where + T: Eq + PhfHash, + K: PhfBorrow<T>, + { + self.get_internal(key).map(|(_, e)| e) + } + + fn get_internal<T: ?Sized>(&self, key: &T) -> Option<(usize, (&K, &V))> + where + T: Eq + PhfHash, + K: PhfBorrow<T>, + { + if self.disps.is_empty() { + return None; + } //Prevent panic on empty map + let hashes = phf_shared::hash(key, &self.key); + let idx_index = phf_shared::get_index(&hashes, &*self.disps, self.idxs.len()); + let idx = self.idxs[idx_index as usize]; + let entry = &self.entries[idx]; + + let b: &T = entry.0.borrow(); + if b == key { + Some((idx, (&entry.0, &entry.1))) + } else { + None + } + } + + /// Returns an iterator over the key/value pairs in the map. + /// + /// Entries are returned in the same order in which they were defined. + pub fn entries(&self) -> Entries<'_, K, V> { + Entries { + iter: self.entries.iter(), + } + } + + /// Returns an iterator over the keys in the map. + /// + /// Keys are returned in the same order in which they were defined. + pub fn keys(&self) -> Keys<'_, K, V> { + Keys { + iter: self.entries(), + } + } + + /// Returns an iterator over the values in the map. + /// + /// Values are returned in the same order in which they were defined. + pub fn values(&self) -> Values<'_, K, V> { + Values { + iter: self.entries(), + } + } +} + +impl<'a, K, V> IntoIterator for &'a OrderedMap<K, V> { + type Item = (&'a K, &'a V); + type IntoIter = Entries<'a, K, V>; + + fn into_iter(self) -> Entries<'a, K, V> { + self.entries() + } +} + +/// An iterator over the entries in a `OrderedMap`. +pub struct Entries<'a, K, V> { + iter: slice::Iter<'a, (K, V)>, +} + +impl<'a, K, V> Clone for Entries<'a, K, V> { + #[inline] + fn clone(&self) -> Self { + Self { + iter: self.iter.clone(), + } + } +} + +impl<'a, K, V> fmt::Debug for Entries<'a, K, V> +where + K: fmt::Debug, + V: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list().entries(self.clone()).finish() + } +} + +impl<'a, K, V> Iterator for Entries<'a, K, V> { + type Item = (&'a K, &'a V); + + fn next(&mut self) -> Option<(&'a K, &'a V)> { + self.iter.next().map(|e| (&e.0, &e.1)) + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } +} + +impl<'a, K, V> DoubleEndedIterator for Entries<'a, K, V> { + fn next_back(&mut self) -> Option<(&'a K, &'a V)> { + self.iter.next_back().map(|e| (&e.0, &e.1)) + } +} + +impl<'a, K, V> ExactSizeIterator for Entries<'a, K, V> {} + +impl<'a, K, V> FusedIterator for Entries<'a, K, V> {} + +/// An iterator over the keys in a `OrderedMap`. +pub struct Keys<'a, K, V> { + iter: Entries<'a, K, V>, +} + +impl<'a, K, V> Clone for Keys<'a, K, V> { + #[inline] + fn clone(&self) -> Self { + Self { + iter: self.iter.clone(), + } + } +} + +impl<'a, K, V> fmt::Debug for Keys<'a, K, V> +where + K: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list().entries(self.clone()).finish() + } +} + +impl<'a, K, V> Iterator for Keys<'a, K, V> { + type Item = &'a K; + + fn next(&mut self) -> Option<&'a K> { + self.iter.next().map(|e| e.0) + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } +} + +impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> { + fn next_back(&mut self) -> Option<&'a K> { + self.iter.next_back().map(|e| e.0) + } +} + +impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {} + +impl<'a, K, V> FusedIterator for Keys<'a, K, V> {} + +/// An iterator over the values in a `OrderedMap`. +pub struct Values<'a, K, V> { + iter: Entries<'a, K, V>, +} + +impl<'a, K, V> Clone for Values<'a, K, V> { + #[inline] + fn clone(&self) -> Self { + Self { + iter: self.iter.clone(), + } + } +} + +impl<'a, K, V> fmt::Debug for Values<'a, K, V> +where + V: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list().entries(self.clone()).finish() + } +} + +impl<'a, K, V> Iterator for Values<'a, K, V> { + type Item = &'a V; + + fn next(&mut self) -> Option<&'a V> { + self.iter.next().map(|e| e.1) + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } +} + +impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> { + fn next_back(&mut self) -> Option<&'a V> { + self.iter.next_back().map(|e| e.1) + } +} + +impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {} + +impl<'a, K, V> FusedIterator for Values<'a, K, V> {} diff --git a/vendor/phf/src/ordered_set.rs b/vendor/phf/src/ordered_set.rs new file mode 100644 index 000000000..e85d45711 --- /dev/null +++ b/vendor/phf/src/ordered_set.rs @@ -0,0 +1,170 @@ +//! An order-preserving immutable set constructed at compile time. +use crate::{ordered_map, OrderedMap, PhfHash}; +use core::fmt; +use core::iter::FusedIterator; +use core::iter::IntoIterator; +use phf_shared::PhfBorrow; + +/// An order-preserving immutable set constructed at compile time. +/// +/// Unlike a `Set`, iteration order is guaranteed to match the definition +/// order. +/// +/// ## Note +/// +/// The fields of this struct are public so that they may be initialized by the +/// `phf_ordered_set!` macro and code generation. They are subject to change at +/// any time and should never be accessed directly. +pub struct OrderedSet<T: 'static> { + #[doc(hidden)] + pub map: OrderedMap<T, ()>, +} + +impl<T> fmt::Debug for OrderedSet<T> +where + T: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_set().entries(self).finish() + } +} + +impl<T> OrderedSet<T> { + /// Returns the number of elements in the `OrderedSet`. + #[inline] + pub const fn len(&self) -> usize { + self.map.len() + } + + /// Returns true if the `OrderedSet` contains no elements. + #[inline] + pub const fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Returns a reference to the set's internal static instance of the given + /// key. + /// + /// This can be useful for interning schemes. + pub fn get_key<U: ?Sized>(&self, key: &U) -> Option<&T> + where + U: Eq + PhfHash, + T: PhfBorrow<U>, + { + self.map.get_key(key) + } + + /// Returns the index of the key within the list used to initialize + /// the ordered set. + pub fn get_index<U: ?Sized>(&self, key: &U) -> Option<usize> + where + U: Eq + PhfHash, + T: PhfBorrow<U>, + { + self.map.get_index(key) + } + + /// Returns a reference to the key at an index + /// within the list used to initialize the ordered set. See `.get_index(key)`. + pub fn index(&self, index: usize) -> Option<&T> { + self.map.index(index).map(|(k, &())| k) + } + + /// Returns true if `value` is in the `OrderedSet`. + pub fn contains<U: ?Sized>(&self, value: &U) -> bool + where + U: Eq + PhfHash, + T: PhfBorrow<U>, + { + self.map.contains_key(value) + } + + /// Returns an iterator over the values in the set. + /// + /// Values are returned in the same order in which they were defined. + pub fn iter(&self) -> Iter<'_, T> { + Iter { + iter: self.map.keys(), + } + } +} + +impl<T> OrderedSet<T> +where + T: Eq + PhfHash + PhfBorrow<T>, +{ + /// Returns true if `other` shares no elements with `self`. + #[inline] + pub fn is_disjoint(&self, other: &OrderedSet<T>) -> bool { + !self.iter().any(|value| other.contains(value)) + } + + /// Returns true if `other` contains all values in `self`. + #[inline] + pub fn is_subset(&self, other: &OrderedSet<T>) -> bool { + self.iter().all(|value| other.contains(value)) + } + + /// Returns true if `self` contains all values in `other`. + #[inline] + pub fn is_superset(&self, other: &OrderedSet<T>) -> bool { + other.is_subset(self) + } +} + +impl<'a, T> IntoIterator for &'a OrderedSet<T> { + type Item = &'a T; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } +} + +/// An iterator over the values in a `OrderedSet`. +pub struct Iter<'a, T> { + iter: ordered_map::Keys<'a, T, ()>, +} + +impl<'a, T> Clone for Iter<'a, T> { + #[inline] + fn clone(&self) -> Self { + Self { + iter: self.iter.clone(), + } + } +} + +impl<'a, T> fmt::Debug for Iter<'a, T> +where + T: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list().entries(self.clone()).finish() + } +} + +impl<'a, T> Iterator for Iter<'a, T> { + type Item = &'a T; + + #[inline] + fn next(&mut self) -> Option<&'a T> { + self.iter.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } +} + +impl<'a, T> DoubleEndedIterator for Iter<'a, T> { + #[inline] + fn next_back(&mut self) -> Option<&'a T> { + self.iter.next_back() + } +} + +impl<'a, T> ExactSizeIterator for Iter<'a, T> {} + +impl<'a, T> FusedIterator for Iter<'a, T> {} diff --git a/vendor/phf/src/set.rs b/vendor/phf/src/set.rs new file mode 100644 index 000000000..d9fdd5bb2 --- /dev/null +++ b/vendor/phf/src/set.rs @@ -0,0 +1,147 @@ +//! An immutable set constructed at compile time. +use core::fmt; +use core::iter::FusedIterator; +use core::iter::IntoIterator; + +use phf_shared::{PhfBorrow, PhfHash}; + +use crate::{map, Map}; + +/// An immutable set constructed at compile time. +/// +/// ## Note +/// +/// The fields of this struct are public so that they may be initialized by the +/// `phf_set!` macro and code generation. They are subject to change at any +/// time and should never be accessed directly. +pub struct Set<T: 'static> { + #[doc(hidden)] + pub map: Map<T, ()>, +} + +impl<T> fmt::Debug for Set<T> +where + T: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_set().entries(self).finish() + } +} + +impl<T> Set<T> { + /// Returns the number of elements in the `Set`. + #[inline] + pub const fn len(&self) -> usize { + self.map.len() + } + + /// Returns true if the `Set` contains no elements. + #[inline] + pub const fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Returns a reference to the set's internal static instance of the given + /// key. + /// + /// This can be useful for interning schemes. + pub fn get_key<U: ?Sized>(&self, key: &U) -> Option<&T> + where + U: Eq + PhfHash, + T: PhfBorrow<U>, + { + self.map.get_key(key) + } + + /// Returns true if `value` is in the `Set`. + pub fn contains<U: ?Sized>(&self, value: &U) -> bool + where + U: Eq + PhfHash, + T: PhfBorrow<U>, + { + self.map.contains_key(value) + } + + /// Returns an iterator over the values in the set. + /// + /// Values are returned in an arbitrary but fixed order. + pub fn iter(&self) -> Iter<'_, T> { + Iter { + iter: self.map.keys(), + } + } +} + +impl<T> Set<T> +where + T: Eq + PhfHash + PhfBorrow<T>, +{ + /// Returns true if `other` shares no elements with `self`. + pub fn is_disjoint(&self, other: &Set<T>) -> bool { + !self.iter().any(|value| other.contains(value)) + } + + /// Returns true if `other` contains all values in `self`. + pub fn is_subset(&self, other: &Set<T>) -> bool { + self.iter().all(|value| other.contains(value)) + } + + /// Returns true if `self` contains all values in `other`. + pub fn is_superset(&self, other: &Set<T>) -> bool { + other.is_subset(self) + } +} + +impl<'a, T> IntoIterator for &'a Set<T> { + type Item = &'a T; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } +} + +/// An iterator over the values in a `Set`. +pub struct Iter<'a, T: 'static> { + iter: map::Keys<'a, T, ()>, +} + +impl<'a, T> Clone for Iter<'a, T> { + #[inline] + fn clone(&self) -> Self { + Self { + iter: self.iter.clone(), + } + } +} + +impl<'a, T> fmt::Debug for Iter<'a, T> +where + T: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list().entries(self.clone()).finish() + } +} + +impl<'a, T> Iterator for Iter<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option<&'a T> { + self.iter.next() + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } +} + +impl<'a, T> DoubleEndedIterator for Iter<'a, T> { + fn next_back(&mut self) -> Option<&'a T> { + self.iter.next_back() + } +} + +impl<'a, T> ExactSizeIterator for Iter<'a, T> {} + +impl<'a, T> FusedIterator for Iter<'a, T> {} diff --git a/vendor/phf_codegen/.cargo-checksum.json b/vendor/phf_codegen/.cargo-checksum.json new file mode 100644 index 000000000..1f6ffe9fc --- /dev/null +++ b/vendor/phf_codegen/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"f6fd52523100ca5655e0326407e2e4b7c9df947ab55a2d1079b424ada242e9cc","src/lib.rs":"26542892e9f9aac772fe1c37b5f5d8119ec64db91bf8c4f8b018c30cdff33ee8"},"package":"4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"}
\ No newline at end of file diff --git a/vendor/phf_codegen/Cargo.toml b/vendor/phf_codegen/Cargo.toml new file mode 100644 index 000000000..c22369fb2 --- /dev/null +++ b/vendor/phf_codegen/Cargo.toml @@ -0,0 +1,25 @@ +# 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 are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "phf_codegen" +version = "0.10.0" +authors = ["Steven Fackler <sfackler@gmail.com>"] +description = "Codegen library for PHF types" +readme = "../README.md" +license = "MIT" +repository = "https://github.com/sfackler/rust-phf" +[dependencies.phf_generator] +version = "0.10.0" + +[dependencies.phf_shared] +version = "0.10.0" diff --git a/vendor/phf_codegen/src/lib.rs b/vendor/phf_codegen/src/lib.rs new file mode 100644 index 000000000..dfcf6ed0e --- /dev/null +++ b/vendor/phf_codegen/src/lib.rs @@ -0,0 +1,486 @@ +//! A set of builders to generate Rust source for PHF data structures at +//! compile time. +//! +//! The provided builders are intended to be used in a Cargo build script to +//! generate a Rust source file that will be included in a library at build +//! time. +//! +//! # Examples +//! +//! build.rs: +//! +//! ```rust,no_run +//! use std::env; +//! use std::fs::File; +//! use std::io::{BufWriter, Write}; +//! use std::path::Path; +//! +//! fn main() { +//! let path = Path::new(&env::var("OUT_DIR").unwrap()).join("codegen.rs"); +//! let mut file = BufWriter::new(File::create(&path).unwrap()); +//! +//! writeln!( +//! &mut file, +//! "static KEYWORDS: phf::Map<&'static str, Keyword> = \n{};\n", +//! phf_codegen::Map::new() +//! .entry("loop", "Keyword::Loop") +//! .entry("continue", "Keyword::Continue") +//! .entry("break", "Keyword::Break") +//! .entry("fn", "Keyword::Fn") +//! .entry("extern", "Keyword::Extern") +//! .build() +//! ).unwrap(); +//! } +//! ``` +//! +//! lib.rs: +//! +//! ```ignore +//! #[derive(Clone)] +//! enum Keyword { +//! Loop, +//! Continue, +//! Break, +//! Fn, +//! Extern, +//! } +//! +//! include!(concat!(env!("OUT_DIR"), "/codegen.rs")); +//! +//! pub fn parse_keyword(keyword: &str) -> Option<Keyword> { +//! KEYWORDS.get(keyword).cloned() +//! } +//! ``` +//! +//! ##### Byte-String Keys +//! Byte strings by default produce references to fixed-size arrays; the compiler needs a hint +//! to coerce them to slices: +//! +//! build.rs: +//! +//! ```rust,no_run +//! use std::env; +//! use std::fs::File; +//! use std::io::{BufWriter, Write}; +//! use std::path::Path; +//! +//! fn main() { +//! let path = Path::new(&env::var("OUT_DIR").unwrap()).join("codegen.rs"); +//! let mut file = BufWriter::new(File::create(&path).unwrap()); +//! +//! writeln!( +//! &mut file, +//! "static KEYWORDS: phf::Map<&'static [u8], Keyword> = \n{};\n", +//! phf_codegen::Map::<&[u8]>::new() +//! .entry(b"loop", "Keyword::Loop") +//! .entry(b"continue", "Keyword::Continue") +//! .entry(b"break", "Keyword::Break") +//! .entry(b"fn", "Keyword::Fn") +//! .entry(b"extern", "Keyword::Extern") +//! .build() +//! ).unwrap(); +//! } +//! ``` +//! +//! lib.rs: +//! +//! ```rust,ignore +//! #[derive(Clone)] +//! enum Keyword { +//! Loop, +//! Continue, +//! Break, +//! Fn, +//! Extern, +//! } +//! +//! include!(concat!(env!("OUT_DIR"), "/codegen.rs")); +//! +//! pub fn parse_keyword(keyword: &[u8]) -> Option<Keyword> { +//! KEYWORDS.get(keyword).cloned() +//! } +//! ``` +//! +//! # Note +//! +//! The compiler's stack will overflow when processing extremely long method +//! chains (500+ calls). When generating large PHF data structures, consider +//! looping over the entries or making each call a separate statement: +//! +//! ```rust +//! let entries = [("hello", "1"), ("world", "2")]; +//! +//! let mut builder = phf_codegen::Map::new(); +//! for &(key, value) in &entries { +//! builder.entry(key, value); +//! } +//! // ... +//! ``` +//! +//! ```rust +//! let mut builder = phf_codegen::Map::new(); +//! builder.entry("hello", "1"); +//! builder.entry("world", "2"); +//! // ... +//! ``` +#![doc(html_root_url = "https://docs.rs/phf_codegen/0.9")] + +use phf_shared::{FmtConst, PhfHash}; +use std::collections::HashSet; +use std::fmt; +use std::hash::Hash; + +use phf_generator::HashState; + +struct Delegate<T>(T); + +impl<T: FmtConst> fmt::Display for Delegate<T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt_const(f) + } +} + +/// A builder for the `phf::Map` type. +pub struct Map<K> { + keys: Vec<K>, + values: Vec<String>, + path: String, +} + +impl<K: Hash + PhfHash + Eq + FmtConst> Map<K> { + /// Creates a new `phf::Map` builder. + pub fn new() -> Map<K> { + // FIXME rust#27438 + // + // On Windows/MSVC there are major problems with the handling of dllimport. + // Here, because downstream build scripts only invoke generics from phf_codegen, + // the linker ends up throwing a way a bunch of static symbols we actually need. + // This works around the problem, assuming that all clients call `Map::new` by + // calling a non-generic function. + fn noop_fix_for_27438() {} + noop_fix_for_27438(); + + Map { + keys: vec![], + values: vec![], + path: String::from("::phf"), + } + } + + /// Set the path to the `phf` crate from the global namespace + pub fn phf_path(&mut self, path: &str) -> &mut Map<K> { + self.path = path.to_owned(); + self + } + + /// Adds an entry to the builder. + /// + /// `value` will be written exactly as provided in the constructed source. + pub fn entry(&mut self, key: K, value: &str) -> &mut Map<K> { + self.keys.push(key); + self.values.push(value.to_owned()); + self + } + + /// Calculate the hash parameters and return a struct implementing + /// [`Display`](::std::fmt::Display) which will print the constructed `phf::Map`. + /// + /// # Panics + /// + /// Panics if there are any duplicate keys. + pub fn build(&self) -> DisplayMap<'_, K> { + let mut set = HashSet::new(); + for key in &self.keys { + if !set.insert(key) { + panic!("duplicate key `{}`", Delegate(key)); + } + } + + let state = phf_generator::generate_hash(&self.keys); + + DisplayMap { + path: &self.path, + keys: &self.keys, + values: &self.values, + state, + } + } +} + +/// An adapter for printing a [`Map`](Map). +pub struct DisplayMap<'a, K> { + path: &'a str, + state: HashState, + keys: &'a [K], + values: &'a [String], +} + +impl<'a, K: FmtConst + 'a> fmt::Display for DisplayMap<'a, K> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // funky formatting here for nice output + write!( + f, + "{}::Map {{ + key: {:?}, + disps: &[", + self.path, self.state.key + )?; + + // write map displacements + for &(d1, d2) in &self.state.disps { + write!( + f, + " + ({}, {}),", + d1, d2 + )?; + } + + write!( + f, + " + ], + entries: &[", + )?; + + // write map entries + for &idx in &self.state.map { + write!( + f, + " + ({}, {}),", + Delegate(&self.keys[idx]), + &self.values[idx] + )?; + } + + write!( + f, + " + ], +}}" + ) + } +} + +/// A builder for the `phf::Set` type. +pub struct Set<T> { + map: Map<T>, +} + +impl<T: Hash + PhfHash + Eq + FmtConst> Set<T> { + /// Constructs a new `phf::Set` builder. + pub fn new() -> Set<T> { + Set { map: Map::new() } + } + + /// Set the path to the `phf` crate from the global namespace + pub fn phf_path(&mut self, path: &str) -> &mut Set<T> { + self.map.phf_path(path); + self + } + + /// Adds an entry to the builder. + pub fn entry(&mut self, entry: T) -> &mut Set<T> { + self.map.entry(entry, "()"); + self + } + + /// Calculate the hash parameters and return a struct implementing + /// [`Display`](::std::fmt::Display) which will print the constructed `phf::Set`. + /// + /// # Panics + /// + /// Panics if there are any duplicate keys. + pub fn build(&self) -> DisplaySet<'_, T> { + DisplaySet { + inner: self.map.build(), + } + } +} + +/// An adapter for printing a [`Set`](Set). +pub struct DisplaySet<'a, T> { + inner: DisplayMap<'a, T>, +} + +impl<'a, T: FmtConst + 'a> fmt::Display for DisplaySet<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}::Set {{ map: {} }}", self.inner.path, self.inner) + } +} + +/// A builder for the `phf::OrderedMap` type. +pub struct OrderedMap<K> { + keys: Vec<K>, + values: Vec<String>, + path: String, +} + +impl<K: Hash + PhfHash + Eq + FmtConst> OrderedMap<K> { + /// Constructs a enw `phf::OrderedMap` builder. + pub fn new() -> OrderedMap<K> { + OrderedMap { + keys: vec![], + values: vec![], + path: String::from("::phf"), + } + } + + /// Set the path to the `phf` crate from the global namespace + pub fn phf_path(&mut self, path: &str) -> &mut OrderedMap<K> { + self.path = path.to_owned(); + self + } + + /// Adds an entry to the builder. + /// + /// `value` will be written exactly as provided in the constructed source. + pub fn entry(&mut self, key: K, value: &str) -> &mut OrderedMap<K> { + self.keys.push(key); + self.values.push(value.to_owned()); + self + } + + /// Calculate the hash parameters and return a struct implementing + /// [`Display`](::std::fmt::Display) which will print the constructed + /// `phf::OrderedMap`. + /// + /// # Panics + /// + /// Panics if there are any duplicate keys. + pub fn build(&self) -> DisplayOrderedMap<'_, K> { + let mut set = HashSet::new(); + for key in &self.keys { + if !set.insert(key) { + panic!("duplicate key `{}`", Delegate(key)); + } + } + + let state = phf_generator::generate_hash(&self.keys); + + DisplayOrderedMap { + path: &self.path, + state, + keys: &self.keys, + values: &self.values, + } + } +} + +/// An adapter for printing a [`OrderedMap`](OrderedMap). +pub struct DisplayOrderedMap<'a, K> { + path: &'a str, + state: HashState, + keys: &'a [K], + values: &'a [String], +} + +impl<'a, K: FmtConst + 'a> fmt::Display for DisplayOrderedMap<'a, K> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}::OrderedMap {{ + key: {:?}, + disps: &[", + self.path, self.state.key + )?; + for &(d1, d2) in &self.state.disps { + write!( + f, + " + ({}, {}),", + d1, d2 + )?; + } + write!( + f, + " + ], + idxs: &[", + )?; + for &idx in &self.state.map { + write!( + f, + " + {},", + idx + )?; + } + write!( + f, + " + ], + entries: &[", + )?; + for (key, value) in self.keys.iter().zip(self.values.iter()) { + write!( + f, + " + ({}, {}),", + Delegate(key), + value + )?; + } + write!( + f, + " + ], +}}" + ) + } +} + +/// A builder for the `phf::OrderedSet` type. +pub struct OrderedSet<T> { + map: OrderedMap<T>, +} + +impl<T: Hash + PhfHash + Eq + FmtConst> OrderedSet<T> { + /// Constructs a new `phf::OrderedSet` builder. + pub fn new() -> OrderedSet<T> { + OrderedSet { + map: OrderedMap::new(), + } + } + + /// Set the path to the `phf` crate from the global namespace + pub fn phf_path(&mut self, path: &str) -> &mut OrderedSet<T> { + self.map.phf_path(path); + self + } + + /// Adds an entry to the builder. + pub fn entry(&mut self, entry: T) -> &mut OrderedSet<T> { + self.map.entry(entry, "()"); + self + } + + /// Calculate the hash parameters and return a struct implementing + /// [`Display`](::std::fmt::Display) which will print the constructed + /// `phf::OrderedSet`. + /// + /// # Panics + /// + /// Panics if there are any duplicate keys. + pub fn build(&self) -> DisplayOrderedSet<'_, T> { + DisplayOrderedSet { + inner: self.map.build(), + } + } +} + +/// An adapter for printing a [`OrderedSet`](OrderedSet). +pub struct DisplayOrderedSet<'a, T> { + inner: DisplayOrderedMap<'a, T>, +} + +impl<'a, T: FmtConst + 'a> fmt::Display for DisplayOrderedSet<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}::OrderedSet {{ map: {} }}", + self.inner.path, self.inner + ) + } +} diff --git a/vendor/phf_generator/.cargo-checksum.json b/vendor/phf_generator/.cargo-checksum.json new file mode 100644 index 000000000..da32ef167 --- /dev/null +++ b/vendor/phf_generator/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.lock":"78ce14c16f470a167be59026946ff3caf139ecbad133e0ff01732d5f8702e2ce","Cargo.toml":"46412745915006724fdfa342f9804013efa4b1413564fcff0dd4d795404018b2","benches/benches.rs":"5d8dc7df14d19d46554908c66832e7075a6ae5f900b491e4f246ed34762ffcc1","src/bin/gen_hash_test.rs":"6837aa742812fb5f23e014a006d54ee9ad92b42b1ee8461e848e53b29e54c24f","src/lib.rs":"18ef26903499d8520e4c22a30fec95e1275909490f3b5d09c326c1d85fa911e7"},"package":"5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"}
\ No newline at end of file diff --git a/vendor/phf_generator/Cargo.lock b/vendor/phf_generator/Cargo.lock new file mode 100644 index 000000000..1e2faa18a --- /dev/null +++ b/vendor/phf_generator/Cargo.lock @@ -0,0 +1,679 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bstr" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" + +[[package]] +name = "cast" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "bitflags", + "textwrap", + "unicode-width", +] + +[[package]] +name = "criterion" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if", + "lazy_static", +] + +[[package]] +name = "csv" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" +dependencies = [ + "bstr", + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +dependencies = [ + "memchr", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "half" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "itertools" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "js-sys" +version = "0.3.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce791b7ca6638aae45be056e068fc756d871eb3b3b10b8efa62d1c9cec616752" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" + +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "phf_generator" +version = "0.10.0" +dependencies = [ + "criterion", + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "plotters" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" + +[[package]] +name = "plotters-svg" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "proc-macro2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "semver" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" + +[[package]] +name = "serde" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" + +[[package]] +name = "serde_cbor" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "siphasher" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1" + +[[package]] +name = "syn" +version = "1.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b608ecc8f4198fe8680e2ed18eccab5f0cd4caaf3d83516fa5fb2e927fda2586" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "580aa3a91a63d23aac5b6b267e2d13cb4f363e31dce6c352fca4752ae12e479f" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171ebf0ed9e1458810dfcb31f2e766ad6b3a89dbda42d8901f2b268277e5f09c" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c2657dd393f03aa2a659c25c6ae18a13a4048cebd220e147933ea837efc589f" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e0c4a743a309662d45f4ede961d7afa4ba4131a59a639f29b0069c3798bbcc2" + +[[package]] +name = "web-sys" +version = "0.3.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c70a82d842c9979078c772d4a1344685045f1a5628f677c2b2eab4dd7d2696" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/vendor/phf_generator/Cargo.toml b/vendor/phf_generator/Cargo.toml new file mode 100644 index 000000000..53394ab30 --- /dev/null +++ b/vendor/phf_generator/Cargo.toml @@ -0,0 +1,40 @@ +# 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 are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "phf_generator" +version = "0.10.0" +authors = ["Steven Fackler <sfackler@gmail.com>"] +description = "PHF generation logic" +license = "MIT" +repository = "https://github.com/sfackler/rust-phf" + +[[bin]] +name = "gen_hash_test" +required-features = ["criterion"] + +[[bench]] +name = "benches" +harness = false +[dependencies.criterion] +version = "=0.3.4" +optional = true + +[dependencies.phf_shared] +version = "0.10.0" +default-features = false + +[dependencies.rand] +version = "0.8" +features = ["small_rng"] +[dev-dependencies.criterion] +version = "=0.3.4" diff --git a/vendor/phf_generator/benches/benches.rs b/vendor/phf_generator/benches/benches.rs new file mode 100644 index 000000000..179c8627b --- /dev/null +++ b/vendor/phf_generator/benches/benches.rs @@ -0,0 +1,58 @@ +use criterion::measurement::Measurement; +use criterion::{criterion_group, criterion_main, Bencher, BenchmarkId, Criterion}; + +use rand::distributions::Standard; +use rand::rngs::SmallRng; +use rand::{Rng, SeedableRng}; + +use phf_generator::generate_hash; + +fn gen_vec(len: usize) -> Vec<u64> { + SmallRng::seed_from_u64(0xAAAAAAAAAAAAAAAA) + .sample_iter(Standard) + .take(len) + .collect() +} + +fn bench_hash<M: Measurement>(b: &mut Bencher<M>, len: &usize) { + let vec = gen_vec(*len); + b.iter(|| generate_hash(&vec)) +} + +fn gen_hash_small(c: &mut Criterion) { + let sizes = vec![0, 1, 2, 5, 10, 25, 50, 75]; + for size in &sizes { + c.bench_with_input(BenchmarkId::new("gen_hash_small", *size), size, bench_hash); + } +} + +fn gen_hash_med(c: &mut Criterion) { + let sizes = vec![100, 250, 500, 1000, 2500, 5000, 7500]; + for size in &sizes { + c.bench_with_input(BenchmarkId::new("gen_hash_medium", *size), size, bench_hash); + } +} + +fn gen_hash_large(c: &mut Criterion) { + let sizes = vec![10_000, 25_000, 50_000, 75_000]; + for size in &sizes { + c.bench_with_input(BenchmarkId::new("gen_hash_large", *size), size, bench_hash); + } +} + +fn gen_hash_xlarge(c: &mut Criterion) { + let sizes = vec![100_000, 250_000, 500_000, 750_000, 1_000_000]; + for size in &sizes { + c.bench_with_input(BenchmarkId::new("gen_hash_xlarge", *size), size, bench_hash); + } +} + +criterion_group!( + benches, + gen_hash_small, + gen_hash_med, + gen_hash_large, + gen_hash_xlarge +); + +criterion_main!(benches); diff --git a/vendor/phf_generator/src/bin/gen_hash_test.rs b/vendor/phf_generator/src/bin/gen_hash_test.rs new file mode 100644 index 000000000..2e1fbec45 --- /dev/null +++ b/vendor/phf_generator/src/bin/gen_hash_test.rs @@ -0,0 +1,20 @@ +use criterion::*; + +use rand::distributions::Alphanumeric; +use rand::rngs::SmallRng; +use rand::{Rng, SeedableRng}; + +use phf_generator::generate_hash; + +fn gen_vec(len: usize) -> Vec<String> { + let mut rng = SmallRng::seed_from_u64(0xAAAAAAAAAAAAAAAA).sample_iter(Alphanumeric); + + (0..len) + .map(move |_| rng.by_ref().take(64).collect::<String>()) + .collect() +} + +fn main() { + let data = black_box(gen_vec(1_000_000)); + black_box(generate_hash(&data)); +} diff --git a/vendor/phf_generator/src/lib.rs b/vendor/phf_generator/src/lib.rs new file mode 100644 index 000000000..6c848ce5a --- /dev/null +++ b/vendor/phf_generator/src/lib.rs @@ -0,0 +1,105 @@ +#![doc(html_root_url = "https://docs.rs/phf_generator/0.9")] +use phf_shared::{HashKey, PhfHash}; +use rand::distributions::Standard; +use rand::rngs::SmallRng; +use rand::{Rng, SeedableRng}; + +const DEFAULT_LAMBDA: usize = 5; + +const FIXED_SEED: u64 = 1234567890; + +pub struct HashState { + pub key: HashKey, + pub disps: Vec<(u32, u32)>, + pub map: Vec<usize>, +} + +pub fn generate_hash<H: PhfHash>(entries: &[H]) -> HashState { + SmallRng::seed_from_u64(FIXED_SEED) + .sample_iter(Standard) + .find_map(|key| try_generate_hash(entries, key)) + .expect("failed to solve PHF") +} + +fn try_generate_hash<H: PhfHash>(entries: &[H], key: HashKey) -> Option<HashState> { + struct Bucket { + idx: usize, + keys: Vec<usize>, + } + + let hashes: Vec<_> = entries + .iter() + .map(|entry| phf_shared::hash(entry, &key)) + .collect(); + + let buckets_len = (hashes.len() + DEFAULT_LAMBDA - 1) / DEFAULT_LAMBDA; + let mut buckets = (0..buckets_len) + .map(|i| Bucket { + idx: i, + keys: vec![], + }) + .collect::<Vec<_>>(); + + for (i, hash) in hashes.iter().enumerate() { + buckets[(hash.g % (buckets_len as u32)) as usize] + .keys + .push(i); + } + + // Sort descending + buckets.sort_by(|a, b| a.keys.len().cmp(&b.keys.len()).reverse()); + + let table_len = hashes.len(); + let mut map = vec![None; table_len]; + let mut disps = vec![(0u32, 0u32); buckets_len]; + + // store whether an element from the bucket being placed is + // located at a certain position, to allow for efficient overlap + // checks. It works by storing the generation in each cell and + // each new placement-attempt is a new generation, so you can tell + // if this is legitimately full by checking that the generations + // are equal. (A u64 is far too large to overflow in a reasonable + // time for current hardware.) + let mut try_map = vec![0u64; table_len]; + let mut generation = 0u64; + + // the actual values corresponding to the markers above, as + // (index, key) pairs, for adding to the main map once we've + // chosen the right disps. + let mut values_to_add = vec![]; + + 'buckets: for bucket in &buckets { + for d1 in 0..(table_len as u32) { + 'disps: for d2 in 0..(table_len as u32) { + values_to_add.clear(); + generation += 1; + + for &key in &bucket.keys { + let idx = (phf_shared::displace(hashes[key].f1, hashes[key].f2, d1, d2) + % (table_len as u32)) as usize; + if map[idx].is_some() || try_map[idx] == generation { + continue 'disps; + } + try_map[idx] = generation; + values_to_add.push((idx, key)); + } + + // We've picked a good set of disps + disps[bucket.idx] = (d1, d2); + for &(idx, key) in &values_to_add { + map[idx] = Some(key); + } + continue 'buckets; + } + } + + // Unable to find displacements for a bucket + return None; + } + + Some(HashState { + key, + disps, + map: map.into_iter().map(|i| i.unwrap()).collect(), + }) +} diff --git a/vendor/phf_shared/.cargo-checksum.json b/vendor/phf_shared/.cargo-checksum.json new file mode 100644 index 000000000..07e0f39a0 --- /dev/null +++ b/vendor/phf_shared/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"dbcb7cd89d95fb146864c5d665496c1803561d5f7f1eea88c35a699f44375f29","src/lib.rs":"e8975dad7d6d3ed71a6bb3bdbe594f18297451cf25dbe69bb1aca61bed2ad5b5"},"package":"b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"}
\ No newline at end of file diff --git a/vendor/phf_shared/Cargo.toml b/vendor/phf_shared/Cargo.toml new file mode 100644 index 000000000..86ed69472 --- /dev/null +++ b/vendor/phf_shared/Cargo.toml @@ -0,0 +1,39 @@ +# 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 are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "phf_shared" +version = "0.10.0" +authors = ["Steven Fackler <sfackler@gmail.com>"] +description = "Support code shared by PHF libraries" +license = "MIT" +repository = "https://github.com/sfackler/rust-phf" + +[lib] +name = "phf_shared" +path = "src/lib.rs" +test = false +[dependencies.siphasher] +version = "0.3" + +[dependencies.uncased] +version = "0.9.6" +optional = true +default-features = false + +[dependencies.unicase] +version = "2.4.0" +optional = true + +[features] +default = ["std"] +std = [] diff --git a/vendor/phf_shared/src/lib.rs b/vendor/phf_shared/src/lib.rs new file mode 100644 index 000000000..79b119a32 --- /dev/null +++ b/vendor/phf_shared/src/lib.rs @@ -0,0 +1,421 @@ +#![doc(html_root_url = "https://docs.rs/phf_shared/0.9")] +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "std")] +extern crate std as core; + +use core::fmt; +use core::hash::{Hash, Hasher}; +use core::num::Wrapping; +use siphasher::sip128::{Hash128, Hasher128, SipHasher13}; + +#[non_exhaustive] +pub struct Hashes { + pub g: u32, + pub f1: u32, + pub f2: u32, +} + +/// A central typedef for hash keys +/// +/// Makes experimentation easier by only needing to be updated here. +pub type HashKey = u64; + +#[inline] +pub fn displace(f1: u32, f2: u32, d1: u32, d2: u32) -> u32 { + (Wrapping(d2) + Wrapping(f1) * Wrapping(d1) + Wrapping(f2)).0 +} + +/// `key` is from `phf_generator::HashState`. +#[inline] +pub fn hash<T: ?Sized + PhfHash>(x: &T, key: &HashKey) -> Hashes { + let mut hasher = SipHasher13::new_with_keys(0, *key); + x.phf_hash(&mut hasher); + + let Hash128 { + h1: lower, + h2: upper, + } = hasher.finish128(); + + Hashes { + g: (lower >> 32) as u32, + f1: lower as u32, + f2: upper as u32, + } +} + +/// Return an index into `phf_generator::HashState::map`. +/// +/// * `hash` is from `hash()` in this crate. +/// * `disps` is from `phf_generator::HashState::disps`. +/// * `len` is the length of `phf_generator::HashState::map`. +#[inline] +pub fn get_index(hashes: &Hashes, disps: &[(u32, u32)], len: usize) -> u32 { + let (d1, d2) = disps[(hashes.g % (disps.len() as u32)) as usize]; + displace(hashes.f1, hashes.f2, d1, d2) % (len as u32) +} + +/// A trait implemented by types which can be used in PHF data structures. +/// +/// This differs from the standard library's `Hash` trait in that `PhfHash`'s +/// results must be architecture independent so that hashes will be consistent +/// between the host and target when cross compiling. +pub trait PhfHash { + /// Feeds the value into the state given, updating the hasher as necessary. + fn phf_hash<H: Hasher>(&self, state: &mut H); + + /// Feeds a slice of this type into the state provided. + fn phf_hash_slice<H: Hasher>(data: &[Self], state: &mut H) + where + Self: Sized, + { + for piece in data { + piece.phf_hash(state); + } + } +} + +/// Trait for printing types with `const` constructors, used by `phf_codegen` and `phf_macros`. +pub trait FmtConst { + /// Print a `const` expression representing this value. + fn fmt_const(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result; +} + +/// Identical to `std::borrow::Borrow` except omitting blanket impls to facilitate other +/// borrowing patterns. +/// +/// The same semantic requirements apply: +/// +/// > In particular `Eq`, `Ord` and `Hash` must be equivalent for borrowed and owned values: +/// `x.borrow() == y.borrow()` should give the same result as `x == y`. +/// +/// (This crate's API only requires `Eq` and `PhfHash`, however.) +/// +/// ### Motivation +/// The conventional signature for lookup methods on collections looks something like this: +/// +/// ```rust,ignore +/// impl<K, V> Map<K, V> where K: PhfHash + Eq { +/// fn get<T: ?Sized>(&self, key: &T) -> Option<&V> where T: PhfHash + Eq, K: Borrow<T> { +/// ... +/// } +/// } +/// ``` +/// +/// This allows the key type used for lookup to be different than the key stored in the map so for +/// example you can use `&str` to look up a value in a `Map<String, _>`. However, this runs into +/// a problem in the case where `T` and `K` are both a `Foo<_>` type constructor but +/// the contained type is different (even being the same type with different lifetimes). +/// +/// The main issue for this crate's API is that, with this method signature, you cannot perform a +/// lookup on a `Map<UniCase<&'static str>, _>` with a `UniCase<&'a str>` where `'a` is not +/// `'static`; there is no impl of `Borrow` that resolves to +/// `impl Borrow<UniCase<'a>> for UniCase<&'static str>` and one cannot be added either because of +/// all the blanket impls. +/// +/// Instead, this trait is implemented conservatively, without blanket impls, so that impls like +/// this may be added. This is feasible since the set of types that implement `PhfHash` is +/// intentionally small. +/// +/// This likely won't be fixable with specialization alone but will require full support for lattice +/// impls since we technically want to add overlapping blanket impls. +pub trait PhfBorrow<B: ?Sized> { + /// Convert a reference to `self` to a reference to the borrowed type. + fn borrow(&self) -> &B; +} + +/// Create an impl of `FmtConst` delegating to `fmt::Debug` for types that can deal with it. +/// +/// Ideally with specialization this could be just one default impl and then specialized where +/// it doesn't apply. +macro_rules! delegate_debug ( + ($ty:ty) => { + impl FmtConst for $ty { + fn fmt_const(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self) + } + } + } +); + +delegate_debug!(str); +delegate_debug!(char); +delegate_debug!(u8); +delegate_debug!(i8); +delegate_debug!(u16); +delegate_debug!(i16); +delegate_debug!(u32); +delegate_debug!(i32); +delegate_debug!(u64); +delegate_debug!(i64); +delegate_debug!(u128); +delegate_debug!(i128); +delegate_debug!(bool); + +/// `impl PhfBorrow<T> for T` +macro_rules! impl_reflexive( + ($($t:ty),*) => ( + $(impl PhfBorrow<$t> for $t { + fn borrow(&self) -> &$t { + self + } + })* + ) +); + +impl_reflexive!( + str, + char, + u8, + i8, + u16, + i16, + u32, + i32, + u64, + i64, + u128, + i128, + bool, + [u8] +); + +#[cfg(feature = "std")] +impl PhfBorrow<str> for String { + fn borrow(&self) -> &str { + self + } +} + +#[cfg(feature = "std")] +impl PhfBorrow<[u8]> for Vec<u8> { + fn borrow(&self) -> &[u8] { + self + } +} + +#[cfg(feature = "std")] +delegate_debug!(String); + +#[cfg(feature = "std")] +impl PhfHash for String { + #[inline] + fn phf_hash<H: Hasher>(&self, state: &mut H) { + (**self).phf_hash(state) + } +} + +#[cfg(feature = "std")] +impl PhfHash for Vec<u8> { + #[inline] + fn phf_hash<H: Hasher>(&self, state: &mut H) { + (**self).phf_hash(state) + } +} + +impl<'a, T: 'a + PhfHash + ?Sized> PhfHash for &'a T { + fn phf_hash<H: Hasher>(&self, state: &mut H) { + (*self).phf_hash(state) + } +} + +impl<'a, T: 'a + FmtConst + ?Sized> FmtConst for &'a T { + fn fmt_const(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (*self).fmt_const(f) + } +} + +impl<'a> PhfBorrow<str> for &'a str { + fn borrow(&self) -> &str { + self + } +} + +impl<'a> PhfBorrow<[u8]> for &'a [u8] { + fn borrow(&self) -> &[u8] { + self + } +} + +impl PhfHash for str { + #[inline] + fn phf_hash<H: Hasher>(&self, state: &mut H) { + self.as_bytes().phf_hash(state) + } +} + +impl PhfHash for [u8] { + #[inline] + fn phf_hash<H: Hasher>(&self, state: &mut H) { + state.write(self); + } +} + +impl FmtConst for [u8] { + #[inline] + fn fmt_const(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // slices need a leading reference + write!(f, "&{:?}", self) + } +} + +#[cfg(feature = "unicase")] +impl<S> PhfHash for unicase::UniCase<S> +where + unicase::UniCase<S>: Hash, +{ + #[inline] + fn phf_hash<H: Hasher>(&self, state: &mut H) { + self.hash(state) + } +} + +#[cfg(feature = "unicase")] +impl<S> FmtConst for unicase::UniCase<S> +where + S: AsRef<str>, +{ + fn fmt_const(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.is_ascii() { + f.write_str("UniCase::ascii(")?; + } else { + f.write_str("UniCase::unicode(")?; + } + + self.as_ref().fmt_const(f)?; + f.write_str(")") + } +} + +#[cfg(feature = "unicase")] +impl<'b, 'a: 'b, S: ?Sized + 'a> PhfBorrow<unicase::UniCase<&'b S>> for unicase::UniCase<&'a S> { + fn borrow(&self) -> &unicase::UniCase<&'b S> { + self + } +} + +#[cfg(feature = "uncased")] +impl PhfHash for uncased::UncasedStr { + #[inline] + fn phf_hash<H: Hasher>(&self, state: &mut H) { + self.hash(state) + } +} + +#[cfg(feature = "uncased")] +impl FmtConst for uncased::UncasedStr { + fn fmt_const(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // transmute is not stable in const fns (rust-lang/rust#53605), so + // `UncasedStr::new` can't be a const fn itself, but we can inline the + // call to transmute here in the meantime. + f.write_str("unsafe { ::std::mem::transmute::<&'static str, &'static UncasedStr>(")?; + self.as_str().fmt_const(f)?; + f.write_str(") }") + } +} + +#[cfg(feature = "uncased")] +impl PhfBorrow<uncased::UncasedStr> for &uncased::UncasedStr { + fn borrow(&self) -> &uncased::UncasedStr { + self + } +} + +macro_rules! sip_impl ( + (le $t:ty) => ( + impl PhfHash for $t { + #[inline] + fn phf_hash<H: Hasher>(&self, state: &mut H) { + self.to_le().hash(state); + } + } + ); + ($t:ty) => ( + impl PhfHash for $t { + #[inline] + fn phf_hash<H: Hasher>(&self, state: &mut H) { + self.hash(state); + } + } + ) +); + +sip_impl!(u8); +sip_impl!(i8); +sip_impl!(le u16); +sip_impl!(le i16); +sip_impl!(le u32); +sip_impl!(le i32); +sip_impl!(le u64); +sip_impl!(le i64); +sip_impl!(le u128); +sip_impl!(le i128); +sip_impl!(bool); + +impl PhfHash for char { + #[inline] + fn phf_hash<H: Hasher>(&self, state: &mut H) { + (*self as u32).phf_hash(state) + } +} + +// minimize duplicated code since formatting drags in quite a bit +fn fmt_array(array: &[u8], f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", array) +} + +macro_rules! array_impl ( + ($t:ty, $n:expr) => ( + impl PhfHash for [$t; $n] { + #[inline] + fn phf_hash<H: Hasher>(&self, state: &mut H) { + state.write(self); + } + } + + impl FmtConst for [$t; $n] { + fn fmt_const(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt_array(self, f) + } + } + + impl PhfBorrow<[$t]> for [$t; $n] { + fn borrow(&self) -> &[$t] { + self + } + } + ) +); + +array_impl!(u8, 1); +array_impl!(u8, 2); +array_impl!(u8, 3); +array_impl!(u8, 4); +array_impl!(u8, 5); +array_impl!(u8, 6); +array_impl!(u8, 7); +array_impl!(u8, 8); +array_impl!(u8, 9); +array_impl!(u8, 10); +array_impl!(u8, 11); +array_impl!(u8, 12); +array_impl!(u8, 13); +array_impl!(u8, 14); +array_impl!(u8, 15); +array_impl!(u8, 16); +array_impl!(u8, 17); +array_impl!(u8, 18); +array_impl!(u8, 19); +array_impl!(u8, 20); +array_impl!(u8, 21); +array_impl!(u8, 22); +array_impl!(u8, 23); +array_impl!(u8, 24); +array_impl!(u8, 25); +array_impl!(u8, 26); +array_impl!(u8, 27); +array_impl!(u8, 28); +array_impl!(u8, 29); +array_impl!(u8, 30); +array_impl!(u8, 31); +array_impl!(u8, 32); |