Skip to content

Commit a7c3961

Browse files
committed
Pass through u128 hashes to the hashmap
Since u128 is already a good hash, use one part of it (lower u64 word) as the hash for the hashmap.
1 parent 967dc01 commit a7c3961

File tree

5 files changed

+47
-8
lines changed

5 files changed

+47
-8
lines changed

src/accelerate.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use std::sync::atomic::{AtomicUsize, Ordering};
22

3-
use rustc_hash::FxHashMap;
43
use parking_lot::{MappedRwLockReadGuard, Mutex, RwLock, RwLockReadGuard};
54

5+
use crate::passthroughhasher::PassthroughHashMap;
6+
67
/// The global list of currently alive accelerators.
78
static ACCELERATORS: RwLock<(usize, Vec<Accelerator>)> = RwLock::new((0, Vec::new()));
89

@@ -12,7 +13,7 @@ static ID: AtomicUsize = AtomicUsize::new(0);
1213
/// The type of each individual accelerator.
1314
///
1415
/// Maps from call hashes to return hashes.
15-
type Accelerator = Mutex<FxHashMap<u128, u128>>;
16+
type Accelerator = Mutex<PassthroughHashMap<u128, u128>>;
1617

1718
/// Generate a new accelerator.
1819
pub fn id() -> usize {
@@ -58,6 +59,6 @@ pub fn get(id: usize) -> Option<MappedRwLockReadGuard<'static, Accelerator>> {
5859
fn resize(len: usize) {
5960
let mut pair = ACCELERATORS.write();
6061
if len > pair.1.len() {
61-
pair.1.resize_with(len, || Mutex::new(FxHashMap::default()));
62+
pair.1.resize_with(len, || Mutex::new(PassthroughHashMap::default()));
6263
}
6364
}

src/constraint.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ use std::collections::hash_map::Entry;
22
use std::hash::Hash;
33

44
use parking_lot::Mutex;
5-
use rustc_hash::FxHashMap;
65

76
use crate::Track;
7+
use crate::passthroughhasher::PassthroughHashMap;
88
use crate::track::{Call, Sink};
99

1010
/// Records calls performed on a trackable type.
@@ -82,7 +82,7 @@ pub struct CallSequence<C> {
8282
/// The raw calls. In order, but deduplicated via the `map`.
8383
vec: Vec<Option<(C, u128)>>,
8484
/// A map from hashes of calls to the indices in the vector.
85-
map: FxHashMap<u128, usize>,
85+
map: PassthroughHashMap<u128, usize>,
8686
/// A cursor for iteration in `Self::next`.
8787
cursor: usize,
8888
}
@@ -92,7 +92,7 @@ impl<C> CallSequence<C> {
9292
pub fn new() -> Self {
9393
Self {
9494
vec: Vec::new(),
95-
map: FxHashMap::default(),
95+
map: PassthroughHashMap::default(),
9696
cursor: 0,
9797
}
9898
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ mod constraint;
9393
mod hash;
9494
mod input;
9595
mod memoize;
96+
mod passthroughhasher;
9697
mod track;
9798
mod tree;
9899

src/passthroughhasher.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use std::collections::HashMap;
2+
use std::hash::{BuildHasher, Hasher};
3+
4+
/// Hash Map that re-uses the u128 as the hash value
5+
pub(crate) type PassthroughHashMap<Key, Value> =
6+
HashMap<Key, Value, BuildPassthroughHasher>;
7+
8+
#[derive(Copy, Clone, Default)]
9+
pub(crate) struct BuildPassthroughHasher;
10+
11+
#[derive(Default)]
12+
pub(crate) struct PassthroughHasher {
13+
value: u64,
14+
}
15+
16+
impl Hasher for PassthroughHasher {
17+
fn finish(&self) -> u64 {
18+
self.value
19+
}
20+
21+
fn write(&mut self, _bytes: &[u8]) {
22+
unimplemented!("Unsupported operation")
23+
}
24+
25+
fn write_u128(&mut self, i: u128) {
26+
// truncating conversion
27+
self.value = i as u64;
28+
}
29+
}
30+
31+
impl BuildHasher for BuildPassthroughHasher {
32+
type Hasher = PassthroughHasher;
33+
fn build_hasher(&self) -> PassthroughHasher {
34+
PassthroughHasher::default()
35+
}
36+
}

src/tree.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_hash::FxHashMap;
55
use slab::Slab;
66

77
use crate::constraint::CallSequence;
8+
use crate::passthroughhasher::PassthroughHashMap;
89

910
/// A tree data structure that associates a value with a key hash and a sequence
1011
/// of (call, return hash) pairs.
@@ -18,7 +19,7 @@ pub struct CallTree<C, T> {
1819
/// Leaf nodes, directly storing outputs.
1920
leaves: Slab<LeafNode<T>>,
2021
/// The initial node for the given key hash.
21-
start: FxHashMap<u128, NodeId>,
22+
start: PassthroughHashMap<u128, NodeId>,
2223
/// Maps from parent nodes to child nodes. The key is a pair of an inner
2324
/// node ID and a return hash for that call. The value is the node to
2425
/// transition to.
@@ -50,8 +51,8 @@ impl<C, T> CallTree<C, T> {
5051
Self {
5152
inner: Slab::new(),
5253
leaves: Slab::new(),
54+
start: PassthroughHashMap::default(),
5355
edges: FxHashMap::default(),
54-
start: FxHashMap::default(),
5556
}
5657
}
5758
}

0 commit comments

Comments
 (0)