Skip to content

Commit

Permalink
Migrate off of RawTable APIs
Browse files Browse the repository at this point in the history
Summary:
The `RawTable` APIs are removed in latest `hashbrown` upgrade (coming in D68793000). rust-lang/hashbrown#546

The PR notes that users should migrate to the `HashTable` APIs instead.

- `HashTable`: https://docs.rs/hashbrown/latest/hashbrown/struct.HashTable.html
- `RawTable`: https://docs.rs/hashbrown/0.14.5/hashbrown/raw/struct.RawTable.html

Reviewed By: dtolnay

Differential Revision: D69195912

fbshipit-source-id: b5c4d0cc33a977d9ceb247ffedcf49d7be0b01ec
  • Loading branch information
capickett authored and facebook-github-bot committed Feb 6, 2025
1 parent 8b542d7 commit c964fbc
Showing 1 changed file with 13 additions and 14 deletions.
27 changes: 13 additions & 14 deletions hphp/hack/src/utils/intern/src/sharded_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ use std::collections::hash_map::RandomState;
use std::fmt;
use std::hash::BuildHasher;
use std::hash::Hash;
use std::hash::Hasher;

use hashbrown::raw::RawTable;
use hashbrown::HashTable;
use parking_lot::RwLock;
use parking_lot::RwLockWriteGuard;

Expand All @@ -21,7 +20,7 @@ const SHARDS: usize = 1 << SHARD_SHIFT;

pub struct ShardedSet<T, S = RandomState> {
build_hasher: S,
shards: [RwLock<RawTable<T>>; SHARDS],
shards: [RwLock<HashTable<T>>; SHARDS],
}

impl<T, S> fmt::Debug for ShardedSet<T, S> {
Expand Down Expand Up @@ -111,15 +110,13 @@ impl<T, S: BuildHasher> ShardedSet<T, S> {
}

fn hash_one<B: BuildHasher, T: Hash>(build_hasher: &B, x: T) -> u64 {
let mut hasher = build_hasher.build_hasher();
x.hash(&mut hasher);
hasher.finish()
build_hasher.hash_one(&x)
}

pub struct InsertLock<'a, T, S = RandomState> {
build_hasher: &'a S,
hash: u64,
shard: RwLockWriteGuard<'a, RawTable<T>>,
shard: RwLockWriteGuard<'a, HashTable<T>>,
}

impl<'a, T, S> fmt::Debug for InsertLock<'a, T, S> {
Expand All @@ -133,7 +130,7 @@ impl<T: Eq + Hash, S: BuildHasher> ShardedSet<T, S> {
/// hashbrown uses the upper 7 bits for disambiguation and the lower bits
/// for bucket indexing, we take the bits just above the top 7.
#[inline(always)]
fn hash_and_shard<Q>(&self, q: &Q) -> (u64, &RwLock<RawTable<T>>)
fn hash_and_shard<Q>(&self, q: &Q) -> (u64, &RwLock<HashTable<T>>)
where
T: Borrow<Q>,
Q: ?Sized + Hash,
Expand All @@ -159,7 +156,7 @@ impl<T: Eq + Hash, S: BuildHasher> ShardedSet<T, S> {
write_lock
} else {
// Write contention. Try reading first to see if the entry already exists.
if let Some(t) = shard.read().get(hash, |other| q == other.borrow()) {
if let Some(t) = shard.read().find(hash, |other| q == other.borrow()) {
// Already exists.
return Ok(t.clone());
}
Expand All @@ -170,7 +167,7 @@ impl<T: Eq + Hash, S: BuildHasher> ShardedSet<T, S> {
// checked in the write contention case above. We don't use an
// upgradable read lock because those are exclusive from one another
// just like write locks.
if let Some(t) = shard.get(hash, |other| q == other.borrow()) {
if let Some(t) = shard.find(hash, |other| q == other.borrow()) {
return Ok(t.clone());
}
Err(InsertLock {
Expand All @@ -189,15 +186,17 @@ impl<T: Eq + Hash, S: BuildHasher> ShardedSet<T, S> {
let (hash, shard) = self.hash_and_shard(q);
shard
.read()
.get(hash, |other| q == other.borrow())
.map(Clone::clone)
.find(hash, |other| q == other.borrow())
.cloned()
}

/// Unconditionally insert `t` without checking if it's in the set.
pub fn unchecked_insert(&self, t: T) {
let build_hasher = &self.build_hasher;
let (hash, shard) = self.hash_and_shard(&t);
shard.write().insert(hash, t, |v| hash_one(build_hasher, v));
shard
.write()
.insert_unique(hash, t, |v| hash_one(build_hasher, v));
}
}

Expand All @@ -207,6 +206,6 @@ impl<T: Sized + Hash, S: BuildHasher> InsertLock<'_, T, S> {
pub fn insert<Q: Into<T>>(&mut self, q: Q) {
let build_hasher = self.build_hasher;
self.shard
.insert(self.hash, q.into(), |v| hash_one(build_hasher, v));
.insert_unique(self.hash, q.into(), |v| hash_one(build_hasher, v));
}
}

0 comments on commit c964fbc

Please sign in to comment.