Commit 5204fe2f authored by Joe Loser's avatar Joe Loser Committed by Facebook Github Bot

Contains with precomputed hash for F14Map and F14Set (#1063)

Summary:
- Implement `contains(F14HashToken const& token, key_type const& key)` similar
  to the C++20 `contains(key_type const& key, size_t hash)` interface. Parameter order follows existing F14 interface, even though it differs from the C++20 interface.
- Implement heterogeneous lookup overloads of `contains` of the above.
Pull Request resolved: https://github.com/facebook/folly/pull/1063

Reviewed By: nbronson

Differential Revision: D14500835

Pulled By: yfeldblum

fbshipit-source-id: 85b0fbb66c2db948958e67105cf8ef98851ee0a6
parent 8a00bcc5
......@@ -833,6 +833,19 @@ class F14BasicMap {
return !table_.find(key).atEnd();
}
FOLLY_ALWAYS_INLINE bool contains(
F14HashToken const& token,
key_type const& key) const {
return !table_.find(token, key).atEnd();
}
template <typename K>
FOLLY_ALWAYS_INLINE EnableHeterogeneousFind<K, bool> contains(
F14HashToken const& token,
K const& key) const {
return !table_.find(token, key).atEnd();
}
std::pair<iterator, iterator> equal_range(key_type const& key) {
return equal_range(*this, key);
}
......
......@@ -615,6 +615,19 @@ class F14BasicSet {
return !table_.find(key).atEnd();
}
FOLLY_ALWAYS_INLINE bool contains(
F14HashToken const& token,
key_type const& key) const {
return !table_.find(token, key).atEnd();
}
template <typename K>
FOLLY_ALWAYS_INLINE EnableHeterogeneousFind<K, bool> contains(
F14HashToken const& token,
K const& key) const {
return !table_.find(token, key).atEnd();
}
std::pair<iterator, iterator> equal_range(key_type const& key) {
return equal_range(*this, key);
}
......
......@@ -1317,14 +1317,21 @@ TEST(F14ValueMap, heterogeneousLookup) {
EXPECT_TRUE(ref.end() == ref.find(buddy));
EXPECT_EQ(hello, ref.find(hello)->first);
const auto buddyHashToken = ref.prehash(buddy);
const auto helloHashToken = ref.prehash(hello);
// prehash + find
EXPECT_TRUE(ref.end() == ref.find(ref.prehash(buddy), buddy));
EXPECT_EQ(hello, ref.find(ref.prehash(hello), hello)->first);
EXPECT_TRUE(ref.end() == ref.find(buddyHashToken, buddy));
EXPECT_EQ(hello, ref.find(helloHashToken, hello)->first);
// contains
EXPECT_FALSE(ref.contains(buddy));
EXPECT_TRUE(ref.contains(hello));
// contains with prehash
EXPECT_FALSE(ref.contains(buddyHashToken, buddy));
EXPECT_TRUE(ref.contains(helloHashToken, hello));
// equal_range
EXPECT_TRUE(std::make_pair(ref.end(), ref.end()) == ref.equal_range(buddy));
EXPECT_TRUE(
......@@ -1751,6 +1758,25 @@ TEST(F14Map, continuousCapacityF12) {
0xfff0, 0xfffe);
}
template <template <class...> class TMap>
void testContainsWithPrecomputedHash() {
TMap<int, int> m{};
const auto key{1};
m.insert({key, 1});
const auto hashToken = m.prehash(key);
EXPECT_TRUE(m.contains(hashToken, key));
const auto otherKey{2};
const auto hashTokenNotFound = m.prehash(otherKey);
EXPECT_FALSE(m.contains(hashTokenNotFound, otherKey));
}
TEST(F14Map, containsWithPrecomputedHash) {
testContainsWithPrecomputedHash<F14ValueMap>();
testContainsWithPrecomputedHash<F14VectorMap>();
testContainsWithPrecomputedHash<F14NodeMap>();
testContainsWithPrecomputedHash<F14FastMap>();
}
///////////////////////////////////
#endif // FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE
///////////////////////////////////
......@@ -991,14 +991,21 @@ TEST(F14ValueSet, heterogeneous) {
EXPECT_TRUE(ref.end() == ref.find(buddy));
EXPECT_EQ(hello, *ref.find(hello));
const auto buddyHashToken = ref.prehash(buddy);
const auto helloHashToken = ref.prehash(hello);
// prehash + find
EXPECT_TRUE(ref.end() == ref.find(ref.prehash(buddy), buddy));
EXPECT_EQ(hello, *ref.find(ref.prehash(hello), hello));
EXPECT_TRUE(ref.end() == ref.find(buddyHashToken, buddy));
EXPECT_EQ(hello, *ref.find(helloHashToken, hello));
// contains
EXPECT_FALSE(ref.contains(buddy));
EXPECT_TRUE(ref.contains(hello));
// contains with prehash
EXPECT_FALSE(ref.contains(buddyHashToken, buddy));
EXPECT_TRUE(ref.contains(helloHashToken, hello));
// equal_range
EXPECT_TRUE(std::make_pair(ref.end(), ref.end()) == ref.equal_range(buddy));
EXPECT_TRUE(
......@@ -1344,6 +1351,25 @@ TEST(F14Set, randomInsertOrder) {
});
}
template <template <class...> class TSet>
void testContainsWithPrecomputedHash() {
TSet<int> m{};
const auto key{1};
m.insert(key);
const auto hashToken = m.prehash(key);
EXPECT_TRUE(m.contains(hashToken, key));
const auto otherKey{2};
const auto hashTokenNotFound = m.prehash(otherKey);
EXPECT_FALSE(m.contains(hashTokenNotFound, otherKey));
}
TEST(F14Set, containsWithPrecomputedHash) {
testContainsWithPrecomputedHash<F14ValueSet>();
testContainsWithPrecomputedHash<F14NodeSet>();
testContainsWithPrecomputedHash<F14VectorSet>();
testContainsWithPrecomputedHash<F14FastSet>();
}
///////////////////////////////////
#endif // FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE
///////////////////////////////////
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment