Make `OptimalMemcpySizeForSooSlotTransfer` ready to work with MaxSooSlotSize upto `3*sizeof(size_t)`.
It would simplifying experimentation with larger SOO space. We may either put `seed` or `GrowthInfo` into the table to increase SOO space.
PiperOrigin-RevId: 729312729
Change-Id: I2b741298ed54db3eee02751aedbbdd6ad82a7171
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 82d83ac..b62599a 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -1388,9 +1388,6 @@
const void* soo_data() const { return heap_or_soo_.get_soo_data(); }
void* soo_data() { return heap_or_soo_.get_soo_data(); }
- HeapOrSoo heap_or_soo() const { return heap_or_soo_; }
- const HeapOrSoo& heap_or_soo_ref() const { return heap_or_soo_; }
-
ctrl_t* control() const { return heap_or_soo_.control(); }
void set_control(ctrl_t* c) { heap_or_soo_.control() = c; }
void* backing_array_start() const {
@@ -2142,7 +2139,9 @@
// The result must not exceed MaxSooSlotSize().
// Some of the cases are merged to minimize the number of function
// instantiations.
-constexpr size_t OptimalMemcpySizeForSooSlotTransfer(size_t slot_size) {
+constexpr size_t OptimalMemcpySizeForSooSlotTransfer(
+ size_t slot_size, size_t max_soo_slot_size = MaxSooSlotSize()) {
+ static_assert(MaxSooSlotSize() >= 8, "unexpectedly small SOO slot size");
if (slot_size == 1) {
return 1;
}
@@ -2154,8 +2153,17 @@
if (slot_size <= 8) {
return 8;
}
- static_assert(MaxSooSlotSize() <= 16, "unexpectedly large SOO slot size");
- return 16;
+ if (max_soo_slot_size <= 16) {
+ return max_soo_slot_size;
+ }
+ if (slot_size <= 16) {
+ return 16;
+ }
+ if (max_soo_slot_size <= 24) {
+ return max_soo_slot_size;
+ }
+ static_assert(MaxSooSlotSize() <= 24, "unexpectedly large SOO slot size");
+ return 24;
}
// Resizes a full SOO table to the NextCapacity(SooCapacity()).
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index 2617719..4e48f48 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -224,6 +224,40 @@
EXPECT_TRUE(gi.HasNoGrowthLeftAssumingMayHaveDeleted());
}
+TEST(Util, OptimalMemcpySizeForSooSlotTransfer) {
+ EXPECT_EQ(1, OptimalMemcpySizeForSooSlotTransfer(1));
+ ASSERT_EQ(4, OptimalMemcpySizeForSooSlotTransfer(2));
+ ASSERT_EQ(4, OptimalMemcpySizeForSooSlotTransfer(3));
+ for (size_t slot_size = 4; slot_size <= 8; ++slot_size) {
+ ASSERT_EQ(8, OptimalMemcpySizeForSooSlotTransfer(slot_size));
+ }
+ // If maximum amount of memory is 16, then we can copy up to 16 bytes.
+ for (size_t slot_size = 9; slot_size <= 16; ++slot_size) {
+ ASSERT_EQ(16,
+ OptimalMemcpySizeForSooSlotTransfer(slot_size,
+ /*max_soo_slot_size=*/16));
+ ASSERT_EQ(16,
+ OptimalMemcpySizeForSooSlotTransfer(slot_size,
+ /*max_soo_slot_size=*/24));
+ }
+ // But we shouldn't try to copy more than maximum amount of memory.
+ for (size_t slot_size = 9; slot_size <= 12; ++slot_size) {
+ ASSERT_EQ(12, OptimalMemcpySizeForSooSlotTransfer(
+ slot_size, /*max_soo_slot_size=*/12));
+ }
+ for (size_t slot_size = 17; slot_size <= 24; ++slot_size) {
+ ASSERT_EQ(24,
+ OptimalMemcpySizeForSooSlotTransfer(slot_size,
+ /*max_soo_slot_size=*/24));
+ }
+ // We shouldn't copy more than maximum.
+ for (size_t slot_size = 17; slot_size <= 20; ++slot_size) {
+ ASSERT_EQ(20,
+ OptimalMemcpySizeForSooSlotTransfer(slot_size,
+ /*max_soo_slot_size=*/20));
+ }
+}
+
TEST(Util, NormalizeCapacity) {
EXPECT_EQ(1, NormalizeCapacity(0));
EXPECT_EQ(1, NormalizeCapacity(1));