Commit 5ae23ed1 by Evan Brown Committed by Copybara-Service

Make PolicyTraits::transfer_uses_memcpy() true for node_hash_* tables.

This should enable binary size savings for now and more efficiency improvements with small buffer optimization.

PiperOrigin-RevId: 564741270
Change-Id: Icf204d88256243eb60464439a52dd589d7a559cb
parent f01b1b56
...@@ -499,6 +499,7 @@ cc_test( ...@@ -499,6 +499,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS, linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [ deps = [
":common_policy_traits", ":common_policy_traits",
"//absl/base:config",
"@com_google_googletest//:gtest_main", "@com_google_googletest//:gtest_main",
], ],
) )
...@@ -582,6 +583,7 @@ cc_test( ...@@ -582,6 +583,7 @@ cc_test(
deps = [ deps = [
":hash_policy_traits", ":hash_policy_traits",
":node_slot_policy", ":node_slot_policy",
"//absl/base:config",
"@com_google_googletest//:gtest_main", "@com_google_googletest//:gtest_main",
], ],
) )
......
...@@ -577,6 +577,7 @@ absl_cc_test( ...@@ -577,6 +577,7 @@ absl_cc_test(
${ABSL_TEST_COPTS} ${ABSL_TEST_COPTS}
DEPS DEPS
absl::common_policy_traits absl::common_policy_traits
absl::config
GTest::gmock_main GTest::gmock_main
) )
...@@ -660,6 +661,7 @@ absl_cc_test( ...@@ -660,6 +661,7 @@ absl_cc_test(
COPTS COPTS
${ABSL_TEST_COPTS} ${ABSL_TEST_COPTS}
DEPS DEPS
absl::config
absl::hash_policy_traits absl::hash_policy_traits
absl::node_slot_policy absl::node_slot_policy
GTest::gmock_main GTest::gmock_main
......
...@@ -93,11 +93,13 @@ struct common_policy_traits { ...@@ -93,11 +93,13 @@ struct common_policy_traits {
struct Rank0 : Rank1 {}; struct Rank0 : Rank1 {};
// Use auto -> decltype as an enabler. // Use auto -> decltype as an enabler.
// P::transfer returns std::true_type if transfer uses memcpy (e.g. in
// node_slot_policy).
template <class Alloc, class P = Policy> template <class Alloc, class P = Policy>
static auto transfer_impl(Alloc* alloc, slot_type* new_slot, static auto transfer_impl(Alloc* alloc, slot_type* new_slot,
slot_type* old_slot, Rank0) slot_type* old_slot, Rank0)
-> decltype((void)P::transfer(alloc, new_slot, old_slot)) { -> decltype(P::transfer(alloc, new_slot, old_slot)) {
P::transfer(alloc, new_slot, old_slot); return P::transfer(alloc, new_slot, old_slot);
} }
#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 #if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
// This overload returns true_type for the trait below. // This overload returns true_type for the trait below.
......
...@@ -16,10 +16,12 @@ ...@@ -16,10 +16,12 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <new> #include <type_traits>
#include <utility>
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "absl/base/config.h"
namespace absl { namespace absl {
ABSL_NAMESPACE_BEGIN ABSL_NAMESPACE_BEGIN
...@@ -51,9 +53,14 @@ std::function<Slot&(Slot*)> PolicyWithoutOptionalOps::element; ...@@ -51,9 +53,14 @@ std::function<Slot&(Slot*)> PolicyWithoutOptionalOps::element;
struct PolicyWithOptionalOps : PolicyWithoutOptionalOps { struct PolicyWithOptionalOps : PolicyWithoutOptionalOps {
static std::function<void(void*, Slot*, Slot*)> transfer; static std::function<void(void*, Slot*, Slot*)> transfer;
}; };
std::function<void(void*, Slot*, Slot*)> PolicyWithOptionalOps::transfer; std::function<void(void*, Slot*, Slot*)> PolicyWithOptionalOps::transfer;
struct PolicyWithMemcpyTransfer : PolicyWithoutOptionalOps {
static std::function<std::true_type(void*, Slot*, Slot*)> transfer;
};
std::function<std::true_type(void*, Slot*, Slot*)>
PolicyWithMemcpyTransfer::transfer;
struct Test : ::testing::Test { struct Test : ::testing::Test {
Test() { Test() {
PolicyWithoutOptionalOps::construct = [&](void* a1, Slot* a2, Slot a3) { PolicyWithoutOptionalOps::construct = [&](void* a1, Slot* a2, Slot a3) {
...@@ -114,6 +121,13 @@ TEST_F(Test, with_transfer) { ...@@ -114,6 +121,13 @@ TEST_F(Test, with_transfer) {
common_policy_traits<PolicyWithOptionalOps>::transfer(&alloc, &a, &b); common_policy_traits<PolicyWithOptionalOps>::transfer(&alloc, &a, &b);
} }
TEST(TransferUsesMemcpy, Basic) {
EXPECT_FALSE(
common_policy_traits<PolicyWithOptionalOps>::transfer_uses_memcpy());
EXPECT_TRUE(
common_policy_traits<PolicyWithMemcpyTransfer>::transfer_uses_memcpy());
}
} // namespace } // namespace
} // namespace container_internal } // namespace container_internal
ABSL_NAMESPACE_END ABSL_NAMESPACE_END
......
...@@ -62,9 +62,12 @@ struct node_slot_policy { ...@@ -62,9 +62,12 @@ struct node_slot_policy {
Policy::delete_element(alloc, *slot); Policy::delete_element(alloc, *slot);
} }
// Returns true_type to indicate that transfer can use memcpy.
template <class Alloc> template <class Alloc>
static void transfer(Alloc*, slot_type* new_slot, slot_type* old_slot) { static std::true_type transfer(Alloc*, slot_type* new_slot,
slot_type* old_slot) {
*new_slot = *old_slot; *new_slot = *old_slot;
return {};
} }
static size_t space_used(const slot_type* slot) { static size_t space_used(const slot_type* slot) {
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "absl/base/config.h"
#include "absl/container/internal/hash_policy_traits.h" #include "absl/container/internal/hash_policy_traits.h"
namespace absl { namespace absl {
...@@ -61,6 +62,7 @@ TEST_F(NodeTest, transfer) { ...@@ -61,6 +62,7 @@ TEST_F(NodeTest, transfer) {
int* b = &s; int* b = &s;
NodePolicy::transfer(&alloc, &a, &b); NodePolicy::transfer(&alloc, &a, &b);
EXPECT_EQ(&s, a); EXPECT_EQ(&s, a);
EXPECT_TRUE(NodePolicy::transfer_uses_memcpy());
} }
} // namespace } // namespace
......
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