Skip to content

Commit

Permalink
allow hasher module use in no_std
Browse files Browse the repository at this point in the history
  • Loading branch information
notsatvrn committed Dec 31, 2023
1 parent cabf31a commit 7afadf7
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 10 deletions.
12 changes: 10 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,23 @@ exclude = ["article/*"]

[features]
default = ["std"]
std = []
std = ["rand_core/std"]
# Only relevant for throughput benchmarks
bench-csv = []
bench-md = []
bench-plot = []

[dependencies]
rand = "0.8"
rand_chacha = { version = "0.3", default_features = false }
rand_core = "0.6"

# (no_std) RDRAND is still preferable to constant seed
[target.'cfg(target_feature = "rdrand")'.dependencies]
getrandom = { version = "0.2", features = ["rdrand"] }
rand_core = { version = "0.6", features = ["getrandom"] }

[dev-dependencies]
rand = "0.8"
lazy_static = { version = "1.4" }
itertools = "0.12.0"
# Benchmarks
Expand All @@ -38,6 +45,7 @@ metrohash = "1.0.6"
fnv = "1.0.3"

[build-dependencies]
rand = "0.8"
rustc_version = "0.4.0"

[dev-dependencies.plotters]
Expand Down
19 changes: 19 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@ extern crate rustc_version;
use rustc_version::{version_meta, Channel};

fn main() {
// generate seed for GxBuildHasher RNG if entropy isn't available
let entropy = cfg!(target_feature = "rdrand") || cfg!(feature = "std");
if entropy {
println!("cargo:rustc-cfg=entropy")
} else {
let out_dir = std::env::var_os("OUT_DIR").unwrap();
let seed_path = std::path::Path::new(&out_dir).join("seed.rs");

use rand::RngCore;
let mut seed = [0u8; 32];
let mut rng = rand::thread_rng();
rng.fill_bytes(&mut seed);

let mut string = "const SEED: [u8; 32] = [".to_owned();
string.push_str(&seed.into_iter().map(|i| i.to_string()).collect::<Vec<String>>().join(","));
string.push_str("];");
std::fs::write(seed_path, &string).unwrap();
}

if version_meta().unwrap().channel == Channel::Nightly
&& cfg!(target_arch = "x86_64")
&& cfg!(target_feature = "avx2")
Expand Down
21 changes: 15 additions & 6 deletions src/hasher.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#[cfg(feature = "std")]
use std::collections::{HashMap, HashSet};
use std::hash::{BuildHasher, Hasher};
use std::mem::MaybeUninit;
use core::hash::{BuildHasher, Hasher};
use core::mem::MaybeUninit;

use rand::RngCore;
use rand_core::{RngCore, SeedableRng};

use crate::gxhash::platform::*;
use crate::gxhash::*;
Expand Down Expand Up @@ -84,7 +85,7 @@ impl GxHasher {
/// unsigned integer.
#[inline]
pub fn finish_u128(&self) -> u128 {
debug_assert!(std::mem::size_of::<State>() >= std::mem::size_of::<u128>());
debug_assert!(core::mem::size_of::<State>() >= core::mem::size_of::<u128>());

unsafe {
let p = &finalize(self.state) as *const State as *const u128;
Expand Down Expand Up @@ -135,14 +136,20 @@ impl Hasher for GxHasher {
#[derive(Clone, Debug)]
pub struct GxBuildHasher(State);

#[cfg(not(entropy))]
include!(concat!(env!("OUT_DIR"), "/seed.rs"));

impl Default for GxBuildHasher {
#[inline]
fn default() -> GxBuildHasher {
let mut uninit: MaybeUninit<State> = MaybeUninit::uninit();
let mut rng = rand::thread_rng();
#[cfg(entopy)]

This comment has been minimized.

Copy link
@ogxd

ogxd Jan 1, 2024

entropy

let mut rng = rand_chacha::ChaCha12Rng::from_entropy();
#[cfg(not(entropy))]
let mut rng = rand_chacha::ChaCha12Rng::from_seed(SEED);
unsafe {
let ptr = uninit.as_mut_ptr() as *mut u8;
let slice = std::slice::from_raw_parts_mut(ptr, VECTOR_SIZE);
let slice = core::slice::from_raw_parts_mut(ptr, VECTOR_SIZE);
rng.fill_bytes(slice);
GxBuildHasher(uninit.assume_init())
}
Expand All @@ -158,9 +165,11 @@ impl BuildHasher for GxBuildHasher {
}

/// A `HashMap` using a (DOS-resistant) [`GxBuildHasher`].
#[cfg(feature = "std")]
pub type GxHashMap<K, V> = HashMap<K, V, GxBuildHasher>;

/// A `HashSet` using a (DOS-resistant) [`GxBuildHasher`].
#[cfg(feature = "std")]
pub type GxHashSet<T> = HashSet<T, GxBuildHasher>;

#[cfg(test)]
Expand Down
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,5 @@
mod gxhash;
pub use crate::gxhash::*;

#[cfg(feature = "std")]
mod hasher;
#[cfg(feature = "std")]
pub use crate::hasher::*;

0 comments on commit 7afadf7

Please sign in to comment.