Skip to content

Commit 047b22c

Browse files
authored
Merge branch 'master' into specialize_randomstate
2 parents 7dc83fc + 7778357 commit 047b22c

8 files changed

+54
-19
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ rand = "0.8.5"
100100
pcg-mwc = "0.2.1"
101101
serde_json = "1.0.59"
102102
hashbrown = "0.14.3"
103+
smallvec = "1.13.1"
103104

104105
[package.metadata.docs.rs]
105106
rustc-args = ["-C", "target-feature=+aes"]

compare/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ codegen-units = 1
2929

3030
[dependencies]
3131
ahash = { path = "../", default-features = false }
32+
pcg-mwc = "0.2.1"
33+
rand = "0.8.5"
34+
rand_core = "0.6.4"
3235

3336
[dev-dependencies]
3437
criterion = "0.3.3"

compare/src/main.rs

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use std::io::Error;
2+
use std::fs::File;
3+
use std::io::Write;
4+
use pcg_mwc::Mwc256XXA64;
5+
use ahash::RandomState;
6+
use std::io::BufWriter;
7+
use std::path::Path;
8+
use rand_core::SeedableRng;
9+
use rand::Rng;
10+
use std::time::Instant;
11+
12+
13+
fn main() -> Result<(), Error> {
14+
let mut r = Mwc256XXA64::seed_from_u64(0xe786_c22b_119c_1479);
15+
16+
let path = Path::new("hash_output");
17+
18+
let mut file = BufWriter::new(File::create(path)?);
19+
let hasher = RandomState::with_seeds(r.gen(), r.gen(), r.gen(), r.gen());
20+
let start = Instant::now();
21+
let mut sum: u64 = 0;
22+
for i in 0..i32::MAX {
23+
let value = hasher.hash_one(i as u64);
24+
sum = sum.wrapping_add(value);
25+
let value: [u8; 8] = value.to_ne_bytes();
26+
file.write_all(&value)?;
27+
}
28+
let elapsed = start.elapsed();
29+
println!("Sum {} Elapsed time: {}", sum, elapsed.as_millis());
30+
file.flush()?;
31+
Ok(())
32+
}

src/aes_hash.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,7 @@ pub(crate) struct AHasherU64 {
226226
impl Hasher for AHasherU64 {
227227
#[inline]
228228
fn finish(&self) -> u64 {
229-
let rot = (self.pad & 63) as u32;
230-
self.buffer.rotate_left(rot)
229+
folded_multiply(self.buffer, self.pad)
231230
}
232231

233232
#[inline]
@@ -253,7 +252,6 @@ impl Hasher for AHasherU64 {
253252
#[inline]
254253
fn write_u64(&mut self, i: u64) {
255254
self.buffer = folded_multiply(i ^ self.buffer, MULTIPLE);
256-
self.pad = self.pad.wrapping_add(i);
257255
}
258256

259257
#[inline]

src/fallback_hash.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ impl AHasher {
5656
#[allow(dead_code)] // Is not called if non-fallback hash is used.
5757
pub(crate) fn from_random_state<T>(rand_state: &RandomState<T>) -> AHasher {
5858
AHasher {
59-
buffer: rand_state.k0,
60-
pad: rand_state.k1,
59+
buffer: rand_state.k1,
60+
pad: rand_state.k0,
6161
extra_keys: [rand_state.k2, rand_state.k3],
6262
}
6363
}
@@ -117,7 +117,7 @@ impl AHasher {
117117
#[inline]
118118
#[cfg(feature = "specialize")]
119119
fn short_finish(&self) -> u64 {
120-
self.buffer.wrapping_add(self.pad)
120+
folded_multiply(self.buffer, self.pad)
121121
}
122122
}
123123

@@ -210,8 +210,8 @@ pub(crate) struct AHasherU64 {
210210
impl Hasher for AHasherU64 {
211211
#[inline]
212212
fn finish(&self) -> u64 {
213-
let rot = (self.pad & 63) as u32;
214-
self.buffer.rotate_left(rot)
213+
folded_multiply(self.buffer, self.pad)
214+
//self.buffer
215215
}
216216

217217
#[inline]
@@ -237,7 +237,6 @@ impl Hasher for AHasherU64 {
237237
#[inline]
238238
fn write_u64(&mut self, i: u64) {
239239
self.buffer = folded_multiply(i ^ self.buffer, MULTIPLE);
240-
self.pad = self.pad.wrapping_add(i);
241240
}
242241

243242
#[inline]

src/hash_quality_test.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -338,22 +338,24 @@ fn test_length_extension<T: Hasher>(hasher: impl Fn(u128, u128) -> T) {
338338
}
339339

340340
fn test_sparse<T: Hasher>(hasher: impl Fn() -> T) {
341+
use smallvec::SmallVec;
342+
341343
let mut buf = [0u8; 256];
342344
let mut hashes = HashMap::new();
343-
for idx_1 in 0..256 {
344-
for idx_2 in idx_1 + 1..256 {
345+
for idx_1 in 0..255_u8 {
346+
for idx_2 in idx_1 + 1..=255_u8 {
345347
for value_1 in [1, 2, 4, 8, 16, 32, 64, 128] {
346348
for value_2 in [
347349
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 16, 17, 18, 20, 24, 31, 32, 33, 48, 64, 96, 127, 128, 129,
348350
192, 254, 255,
349351
] {
350-
buf[idx_1] = value_1;
351-
buf[idx_2] = value_2;
352+
buf[idx_1 as usize] = value_1;
353+
buf[idx_2 as usize] = value_2;
352354
let hash_value = hash_with(&buf, &mut hasher());
353-
let keys = hashes.entry(hash_value).or_insert(Vec::new());
354-
keys.push((idx_1, value_1, idx_2, value_2));
355-
buf[idx_1] = 0;
356-
buf[idx_2] = 0;
355+
let keys = hashes.entry(hash_value).or_insert(SmallVec::<[[u8; 4]; 1]>::new());
356+
keys.push([idx_1, value_1, idx_2, value_2]);
357+
buf[idx_1 as usize] = 0;
358+
buf[idx_2 as usize] = 0;
357359
}
358360
}
359361
}

tests/bench.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ fn gen_strings() -> Vec<String> {
7373
macro_rules! bench_inputs {
7474
($group:ident, $hash:ident) => {
7575
// Number of iterations per batch should be high enough to hide timing overhead.
76-
let size = BatchSize::NumIterations(2_000);
76+
let size = BatchSize::NumIterations(50_000);
7777

7878
let mut rng = rand::thread_rng();
7979
$group.bench_function("u8", |b| b.iter_batched(|| rng.gen::<u8>(), |v| $hash(&v), size));

tests/map_tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ fn test_byte_dist() {
238238
let mut table: [bool; 256 * 8] = [false; 256 * 8];
239239
let hasher = RandomState::<u64>::with_seeds(r.gen(), r.gen(), r.gen(), r.gen());
240240
for i in 0..128 {
241-
let mut keys: [u8; 8] = hasher.hash_one(i as u64).to_ne_bytes();
241+
let mut keys: [u8; 8] = hasher.hash_one((i as u64) << 30).to_ne_bytes();
242242
//let mut keys = r.next_u64().to_ne_bytes(); //This is a control to test assert sensitivity.
243243
for idx in 0..8 {
244244
while table[idx * 256 + keys[idx] as usize] {

0 commit comments

Comments
 (0)