Skip to content

Commit

Permalink
Prepare hashbrown for inclusion in the standard library
Browse files Browse the repository at this point in the history
  • Loading branch information
Amanieu committed Feb 21, 2019
1 parent 15ed229 commit 4f1cfb0
Show file tree
Hide file tree
Showing 8 changed files with 1,019 additions and 391 deletions.
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ keywords = ["hash", "no_std", "hashmap", "swisstable"]
categories = ["data-structures", "no-std"]

[dependencies]
byteorder = { version = "1.0", default-features = false }
scopeguard = { version = "0.3", default-features = false }

# For external trait impls
rayon = { version = "1.0", optional = true }
serde = { version = "1.0", default-features = false, optional = true }

# When built as part of libstd
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
compiler_builtins = { version = "0.1.2", optional = true }
alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }

[dev-dependencies]
lazy_static = "~1.2"
rand = "0.5.1"
Expand All @@ -26,3 +28,4 @@ serde_test = "1.0"

[features]
nightly = []
rustc-dep-of-std = ["nightly", "core", "compiler_builtins", "alloc"]
22 changes: 13 additions & 9 deletions src/fx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ use core::hash::{BuildHasherDefault, Hasher};
use core::mem::size_of;
use core::ops::BitXor;

use byteorder::{ByteOrder, NativeEndian};

/// Type alias for a `HashBuilder` using the `fx` hash algorithm.
pub type FxHashBuilder = BuildHasherDefault<FxHasher>;

Expand Down Expand Up @@ -47,23 +45,29 @@ impl FxHasher {
impl Hasher for FxHasher {
#[inline]
fn write(&mut self, mut bytes: &[u8]) {
#[cfg(target_pointer_width = "32")]
let read_usize = |bytes| NativeEndian::read_u32(bytes);
#[cfg(target_pointer_width = "64")]
let read_usize = |bytes| NativeEndian::read_u64(bytes);
macro_rules! read_bytes {
($ty:ty, $src:expr) => {{
assert!(size_of::<$ty>() <= $src.len());
let mut data: $ty = 0;
unsafe {
$src.as_ptr().copy_to_nonoverlapping(&mut data as *mut $ty as *mut u8, size_of::<$ty>());
}
data
}};
}

let mut hash = FxHasher { hash: self.hash };
assert!(size_of::<usize>() <= 8);
while bytes.len() >= size_of::<usize>() {
hash.add_to_hash(read_usize(bytes) as usize);
hash.add_to_hash(read_bytes!(usize, bytes) as usize);
bytes = &bytes[size_of::<usize>()..];
}
if (size_of::<usize>() > 4) && (bytes.len() >= 4) {
hash.add_to_hash(NativeEndian::read_u32(bytes) as usize);
hash.add_to_hash(read_bytes!(u32, bytes) as usize);
bytes = &bytes[4..];
}
if (size_of::<usize>() > 2) && bytes.len() >= 2 {
hash.add_to_hash(NativeEndian::read_u16(bytes) as usize);
hash.add_to_hash(read_bytes!(u16, bytes) as usize);
bytes = &bytes[2..];
}
if (size_of::<usize>() > 1) && bytes.len() >= 1 {
Expand Down
9 changes: 6 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,16 @@
#![warn(missing_docs)]

#[cfg(test)]
#[macro_use]
#[cfg_attr(feature = "rayon", macro_use)]
extern crate std;
#[cfg(test)]
extern crate rand;

#[cfg(feature = "nightly")]
#[cfg_attr(test, macro_use)]
extern crate alloc;
extern crate byteorder;
#[cfg(feature = "rayon")]
extern crate rayon;
extern crate scopeguard;
#[cfg(feature = "serde")]
extern crate serde;
#[cfg(not(feature = "nightly"))]
Expand All @@ -48,11 +46,16 @@ mod fx;
mod map;
mod raw;
mod set;
#[cfg(feature = "rustc-dep-of-std")]
mod rustc_entry;

pub mod hash_map {
//! A hash map implemented with quadratic probing and SIMD lookup.
pub use map::*;

#[cfg(feature = "rustc-dep-of-std")]
pub use rustc_entry::*;

#[cfg(feature = "rayon")]
/// [rayon]-based parallel iterator types for hash maps.
/// You will rarely need to interact with it directly unless you have need
Expand Down
Loading

0 comments on commit 4f1cfb0

Please sign in to comment.