Skip to content

Commit

Permalink
overload F14Table::prehash to take hashes
Browse files Browse the repository at this point in the history
Summary: The current interface is `F14HashToken F14Table::prehash(K const&) const`. This is helpful for users to pipeline an overall lookup operation into separate `prehash` and then lookup-with-hash-token steps. But there is a further refinement: allow the user to split up prehashing into computing the hash value of the key from the hasher in one step and then postprocessing that hash value into a hash-token in a second step.

Reviewed By: bmaurer

Differential Revision: D60047675

fbshipit-source-id: 6620e7993d6b97f73b7629ad288e1831bc83650d
  • Loading branch information
yfeldblum authored and facebook-github-bot committed Jul 23, 2024
1 parent dc5586d commit 09c7323
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 0 deletions.
10 changes: 10 additions & 0 deletions folly/container/F14Map.h
Original file line number Diff line number Diff line change
Expand Up @@ -807,12 +807,22 @@ class F14BasicMap {
F14HashToken prehash(key_type const& key) const {
return table_.prehash(key);
}
/// @copydoc prehash
F14HashToken prehash(key_type const& key, std::size_t hash) const {
return table_.prehash(key, hash);
}

/// @copydoc prehash
template <typename K>
EnableHeterogeneousFind<K, F14HashToken> prehash(K const& key) const {
return table_.prehash(key);
}
/// @copydoc prehash
template <typename K>
EnableHeterogeneousFind<K, F14HashToken> prehash(
K const& key, std::size_t hash) const {
return table_.prehash(key, hash);
}

/**
* @overloadbrief Prefetch cachelines associated with a key.
Expand Down
11 changes: 11 additions & 0 deletions folly/container/F14Set.h
Original file line number Diff line number Diff line change
Expand Up @@ -505,11 +505,22 @@ class F14BasicSet {
F14HashToken prehash(key_type const& key) const {
return table_.prehash(key);
}
/// @copydoc prehash
F14HashToken prehash(key_type const& key, std::size_t hash) const {
return table_.prehash(key, hash);
}

/// @copydoc prehash
template <typename K>
EnableHeterogeneousFind<K, F14HashToken> prehash(K const& key) const {
return table_.prehash(key);
}
/// @copydoc prehash
template <typename K>
EnableHeterogeneousFind<K, F14HashToken> prehash(
K const& key, std::size_t hash) const {
return table_.prehash(key, hash);
}

/**
* @overloadbrief Prefetch cachelines associated with a key.
Expand Down
8 changes: 8 additions & 0 deletions folly/container/detail/F14MapFallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -571,11 +571,19 @@ class F14BasicMap : public std::unordered_map<K, M, H, E, A> {
F14HashToken prehash(key_type const&) const {
return {}; // Ignored.
}
F14HashToken prehash(key_type const&, std::size_t) const {
return {}; // Ignored.
}

template <typename K2>
EnableHeterogeneousFind<K2, F14HashToken> prehash(K2 const&) const {
return {}; // Ignored.
}
template <typename K2>
EnableHeterogeneousFind<K2, F14HashToken> prehash(
K2 const&, std::size_t) const {
return {}; // Ignored.
}

void prefetch(F14HashToken const&) const {}

Expand Down
8 changes: 8 additions & 0 deletions folly/container/detail/F14SetFallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,11 +405,19 @@ class F14BasicSet
F14HashToken prehash(key_type const& /*key*/) const {
return {}; // Ignored.
}
F14HashToken prehash(key_type const& /*key*/, std::size_t /*hash*/) const {
return {}; // Ignored.
}

template <typename K>
EnableHeterogeneousFind<K, F14HashToken> prehash(K const& /*key*/) const {
return {};
}
template <typename K>
EnableHeterogeneousFind<K, F14HashToken> prehash(
K const& /*key*/, std::size_t /*hash*/) const {
return {};
}

void prefetch(F14HashToken const& /*token*/) const {}

Expand Down
6 changes: 6 additions & 0 deletions folly/container/detail/F14Table.h
Original file line number Diff line number Diff line change
Expand Up @@ -1600,6 +1600,12 @@ class F14Table : public Policy {
return F14HashToken{splitHash(this->computeKeyHash(key))};
}

template <typename K>
F14HashToken prehash(K const& key, std::size_t hash) const {
FOLLY_SAFE_DCHECK(hash == this->computeKeyHash(key));
return F14HashToken{splitHash(hash)};
}

void prefetch(F14HashToken const& token) const {
FOLLY_SAFE_DCHECK(chunks_ != nullptr, "");
ChunkPtr firstChunk = chunks_ + moduloByChunkCount(token.hp_.first);
Expand Down
24 changes: 24 additions & 0 deletions folly/container/test/F14MapTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,21 @@ void runPrehash() {
EXPECT_TRUE(h.find(t1, s("def")) == h.end());
EXPECT_FALSE(h.find(t2, s("abc")) == h.end());
h.prefetch(t1);

{
auto const key3 = s("def");
auto hv3 = h.hash_function()(key3);
auto t3 = h.prehash(key3, hv3);
EXPECT_EQ(t3, h.prehash(key3));
EXPECT_TRUE(h.find(t3, key3) == h.end());
}
{
auto const key3 = s("abc");
auto hv3 = h.hash_function()(key3);
auto t3 = h.prehash(key3, hv3);
EXPECT_EQ(t3, h.prehash(key3));
EXPECT_FALSE(h.find(t3, key3) == h.end());
}
}
TEST(F14ValueMap, prehash) {
runPrehash<F14ValueMap<std::string, std::string>>();
Expand Down Expand Up @@ -1667,6 +1682,15 @@ TEST(F14ValueMap, heterogeneousLookup) {
const auto buddyHashToken = ref.prehash(buddy);
const auto helloHashToken = ref.prehash(hello);

EXPECT_TRUE(
buddyHashToken == ref.prehash(buddy, ref.hash_function()(buddy)));
EXPECT_TRUE(
helloHashToken == ref.prehash(hello, ref.hash_function()(hello)));
#if FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE
EXPECT_FALSE(
buddyHashToken == ref.prehash(hello, ref.hash_function()(hello)));
#endif

// prehash + find
EXPECT_TRUE(ref.end() == ref.find(buddyHashToken, buddy));
EXPECT_EQ(hello, ref.find(helloHashToken, hello)->first);
Expand Down
9 changes: 9 additions & 0 deletions folly/container/test/F14SetTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,15 @@ TEST(F14ValueSet, heterogeneous) {
const auto buddyHashToken = ref.prehash(buddy);
const auto helloHashToken = ref.prehash(hello);

EXPECT_TRUE(
buddyHashToken == ref.prehash(buddy, ref.hash_function()(buddy)));
EXPECT_TRUE(
helloHashToken == ref.prehash(hello, ref.hash_function()(hello)));
#if FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE
EXPECT_FALSE(
buddyHashToken == ref.prehash(hello, ref.hash_function()(hello)));
#endif

// prehash + find
EXPECT_TRUE(ref.end() == ref.find(buddyHashToken, buddy));
EXPECT_EQ(hello, *ref.find(helloHashToken, hello));
Expand Down

0 comments on commit 09c7323

Please sign in to comment.