Commit ce0007aa authored by Nathan Bronson's avatar Nathan Bronson Committed by Facebook GitHub Bot

heterogeneous lookup for F14 map fallback

Summary:
This diff implements efficient heterogeneous lookup, insert,
and erase for the fallback (non-SIMD) mode of F14.  It relies on internal
implementation details of the underlying std::unordered_map implementation
that happen to be true for libstdc++, libc++, and MSVC.

Extending this technique to F14 sets would be straightforward, but has
not been done here.

(Note: this ignores all push blocking failures!)

Differential Revision: D21408628

fbshipit-source-id: 72e9ddd82a50c02ec762d4b64dc3303848bd0218
parent 5d517eb7
...@@ -44,6 +44,14 @@ ...@@ -44,6 +44,14 @@
#define FOLLY_F14_CRC_INTRINSIC_AVAILABLE 0 #define FOLLY_F14_CRC_INTRINSIC_AVAILABLE 0
#endif #endif
// The F14 extension eraseInto is only available in fallback mode for
// c++17 or later, because it relies on unordered_map::extract.
#if FOLLY_F14_VECTOR_INTRINSICS_AVAILABLE || __cplusplus >= 201703L
#define FOLLY_F14_ERASE_INTO_AVAILABLE 1
#else
#define FOLLY_F14_ERASE_INTO_AVAILABLE 0
#endif
namespace folly { namespace folly {
namespace f14 { namespace f14 {
namespace detail { namespace detail {
......
This diff is collapsed.
...@@ -43,6 +43,10 @@ class F14BasicSet : public std::unordered_set<K, H, E, A> { ...@@ -43,6 +43,10 @@ class F14BasicSet : public std::unordered_set<K, H, E, A> {
//// PUBLIC - F14 Extensions //// PUBLIC - F14 Extensions
bool containsEqualValue(value_type const& value) const { bool containsEqualValue(value_type const& value) const {
// bucket is only valid if bucket_count is non-zero
if (this->empty()) {
return false;
}
auto slot = this->bucket(value); auto slot = this->bucket(value);
auto e = this->end(slot); auto e = this->end(slot);
for (auto b = this->begin(slot); b != e; ++b) { for (auto b = this->begin(slot); b != e; ++b) {
......
...@@ -198,6 +198,27 @@ void erase_if_impl(Container& c, Predicate& predicate) { ...@@ -198,6 +198,27 @@ void erase_if_impl(Container& c, Predicate& predicate) {
} }
} }
template <
typename TableKey,
typename Hasher,
typename KeyEqual,
typename ArgKey>
struct EligibleForHeterogeneousFind
: Conjunction<
is_transparent<Hasher>,
is_transparent<KeyEqual>,
is_invocable<Hasher, ArgKey const&>,
is_invocable<KeyEqual, ArgKey const&, TableKey const&>> {};
template <
typename TableKey,
typename Hasher,
typename KeyEqual,
typename ArgKey>
using EligibleForHeterogeneousInsert = Conjunction<
EligibleForHeterogeneousFind<TableKey, Hasher, KeyEqual, ArgKey>,
std::is_constructible<TableKey, ArgKey>>;
} // namespace detail } // namespace detail
} // namespace f14 } // namespace f14
...@@ -239,27 +260,6 @@ template <typename Arg, typename Default> ...@@ -239,27 +260,6 @@ template <typename Arg, typename Default>
using Defaulted = using Defaulted =
std::conditional_t<std::is_same<Arg, void>::value, Default, Arg>; std::conditional_t<std::is_same<Arg, void>::value, Default, Arg>;
template <
typename TableKey,
typename Hasher,
typename KeyEqual,
typename ArgKey>
struct EligibleForHeterogeneousFind
: Conjunction<
is_transparent<Hasher>,
is_transparent<KeyEqual>,
is_invocable<Hasher, ArgKey const&>,
is_invocable<KeyEqual, ArgKey const&, TableKey const&>> {};
template <
typename TableKey,
typename Hasher,
typename KeyEqual,
typename ArgKey>
using EligibleForHeterogeneousInsert = Conjunction<
EligibleForHeterogeneousFind<TableKey, Hasher, KeyEqual, ArgKey>,
std::is_constructible<TableKey, ArgKey>>;
//////////////// ////////////////
template <typename T> template <typename T>
......
This diff is collapsed.
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