summaryrefslogtreecommitdiff
path: root/absl/container
diff options
context:
space:
mode:
authorGravatar Evan Brown <ezb@google.com>2023-09-12 09:14:32 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2023-09-12 09:15:26 -0700
commit5ae23ed130027e2376e0868ec4bb4fa358b7e238 (patch)
tree0e7cf0c8c3444ef0a620627a3eb9f528f202c586 /absl/container
parentf01b1b56de359de540c97a7898ff3011c47e2c26 (diff)
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
Diffstat (limited to 'absl/container')
-rw-r--r--absl/container/BUILD.bazel2
-rw-r--r--absl/container/CMakeLists.txt2
-rw-r--r--absl/container/internal/common_policy_traits.h6
-rw-r--r--absl/container/internal/common_policy_traits_test.cc18
-rw-r--r--absl/container/internal/node_slot_policy.h5
-rw-r--r--absl/container/internal/node_slot_policy_test.cc2
6 files changed, 30 insertions, 5 deletions
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel
index 208e78e8..51318379 100644
--- a/absl/container/BUILD.bazel
+++ b/absl/container/BUILD.bazel
@@ -499,6 +499,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":common_policy_traits",
+ "//absl/base:config",
"@com_google_googletest//:gtest_main",
],
)
@@ -582,6 +583,7 @@ cc_test(
deps = [
":hash_policy_traits",
":node_slot_policy",
+ "//absl/base:config",
"@com_google_googletest//:gtest_main",
],
)
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt
index 64f6965a..f5ef0ddb 100644
--- a/absl/container/CMakeLists.txt
+++ b/absl/container/CMakeLists.txt
@@ -577,6 +577,7 @@ absl_cc_test(
${ABSL_TEST_COPTS}
DEPS
absl::common_policy_traits
+ absl::config
GTest::gmock_main
)
@@ -660,6 +661,7 @@ absl_cc_test(
COPTS
${ABSL_TEST_COPTS}
DEPS
+ absl::config
absl::hash_policy_traits
absl::node_slot_policy
GTest::gmock_main
diff --git a/absl/container/internal/common_policy_traits.h b/absl/container/internal/common_policy_traits.h
index 3558a543..57eac678 100644
--- a/absl/container/internal/common_policy_traits.h
+++ b/absl/container/internal/common_policy_traits.h
@@ -93,11 +93,13 @@ struct common_policy_traits {
struct Rank0 : Rank1 {};
// 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>
static auto transfer_impl(Alloc* alloc, slot_type* new_slot,
slot_type* old_slot, Rank0)
- -> decltype((void)P::transfer(alloc, new_slot, old_slot)) {
- P::transfer(alloc, new_slot, old_slot);
+ -> decltype(P::transfer(alloc, new_slot, old_slot)) {
+ return P::transfer(alloc, new_slot, old_slot);
}
#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
// This overload returns true_type for the trait below.
diff --git a/absl/container/internal/common_policy_traits_test.cc b/absl/container/internal/common_policy_traits_test.cc
index 5eaa4aae..faee3e7a 100644
--- a/absl/container/internal/common_policy_traits_test.cc
+++ b/absl/container/internal/common_policy_traits_test.cc
@@ -16,10 +16,12 @@
#include <functional>
#include <memory>
-#include <new>
+#include <type_traits>
+#include <utility>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -51,9 +53,14 @@ std::function<Slot&(Slot*)> PolicyWithoutOptionalOps::element;
struct PolicyWithOptionalOps : PolicyWithoutOptionalOps {
static std::function<void(void*, Slot*, Slot*)> 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 {
Test() {
PolicyWithoutOptionalOps::construct = [&](void* a1, Slot* a2, Slot a3) {
@@ -114,6 +121,13 @@ TEST_F(Test, with_transfer) {
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 container_internal
ABSL_NAMESPACE_END
diff --git a/absl/container/internal/node_slot_policy.h b/absl/container/internal/node_slot_policy.h
index baba5743..3f1874d4 100644
--- a/absl/container/internal/node_slot_policy.h
+++ b/absl/container/internal/node_slot_policy.h
@@ -62,9 +62,12 @@ struct node_slot_policy {
Policy::delete_element(alloc, *slot);
}
+ // Returns true_type to indicate that transfer can use memcpy.
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;
+ return {};
}
static size_t space_used(const slot_type* slot) {
diff --git a/absl/container/internal/node_slot_policy_test.cc b/absl/container/internal/node_slot_policy_test.cc
index 51b7467b..d4ea919d 100644
--- a/absl/container/internal/node_slot_policy_test.cc
+++ b/absl/container/internal/node_slot_policy_test.cc
@@ -18,6 +18,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/container/internal/hash_policy_traits.h"
namespace absl {
@@ -61,6 +62,7 @@ TEST_F(NodeTest, transfer) {
int* b = &s;
NodePolicy::transfer(&alloc, &a, &b);
EXPECT_EQ(&s, a);
+ EXPECT_TRUE(NodePolicy::transfer_uses_memcpy());
}
} // namespace