Fix sampling for the insert into a non-SOO table with capacity==1.

RecordInsertMiss is where we increment size for hashtablez.
This call was missing, so size was off by one.
We can even end up with negative size if a later erase takes place on the same table.

PiperOrigin-RevId: 882493632
Change-Id: Ifbb58fb2eaa0225d310c919bd0162dc2e0185d58
This commit is contained in:
Vitaly Goldshteyn
2026-03-12 03:38:48 -07:00
committed by Copybara-Service
parent 896d915069
commit ec35402ac9
2 changed files with 34 additions and 3 deletions

View File

@@ -1528,6 +1528,10 @@ std::pair<ctrl_t*, void*> PrepareInsertSmallNonSoo(
if (common.capacity() == 1) {
if (common.empty()) {
IncrementSmallSizeNonSoo(common, policy);
if (common.has_infoz()) {
common.infoz().RecordInsertMiss(get_hash(common.seed().seed()),
/*distance_from_desired=*/0);
}
return {SooControl(), common.slot_array()};
} else {
return Grow1To3AndPrepareInsert(common, policy, get_hash);

View File

@@ -2878,8 +2878,9 @@ TYPED_TEST(RawHashSamplerTest, Sample) {
}
}
std::vector<const HashtablezInfo*> SampleSooMutation(
absl::FunctionRef<void(SooInt32Table&)> mutate_table) {
template <typename IntTableType>
std::vector<const HashtablezInfo*> SampleTableMutation(
absl::FunctionRef<void(IntTableType&)> mutate_table) {
// Enable the feature even if the prod default is off.
SetSamplingRateTo1Percent();
@@ -2892,7 +2893,7 @@ std::vector<const HashtablezInfo*> SampleSooMutation(
++start_size;
});
std::vector<SooInt32Table> tables;
std::vector<IntTableType> tables;
for (int i = 0; i < 1000000; ++i) {
tables.emplace_back();
mutate_table(tables.back());
@@ -2911,6 +2912,16 @@ std::vector<const HashtablezInfo*> SampleSooMutation(
return infos;
}
std::vector<const HashtablezInfo*> SampleSooMutation(
absl::FunctionRef<void(SooInt32Table&)> mutate_table) {
return SampleTableMutation<SooInt32Table>(mutate_table);
}
std::vector<const HashtablezInfo*> SampleNonSooMutation(
absl::FunctionRef<void(NonSooIntTable&)> mutate_table) {
return SampleTableMutation<NonSooIntTable>(mutate_table);
}
TEST(RawHashSamplerTest, SooTableInsertToEmpty) {
if (SooInt32Table().capacity() != SooCapacity()) {
CHECK_LT(sizeof(void*), 8) << "missing SOO coverage";
@@ -2956,6 +2967,22 @@ TEST(RawHashSamplerTest, SooTableRepeatedInsertEraseDoesNotOversample) {
// instance.
}
TEST(RawHashSamplerTest, NonSooTableRepeatedInsertEraseCountSizeRight) {
ASSERT_EQ(NonSooIntTable().capacity(), 0);
std::vector<const HashtablezInfo*> infos =
SampleNonSooMutation([](NonSooIntTable& t) {
for (int i = 0; i < 10; ++i) {
t.insert(1);
t.erase(1);
}
});
for (const HashtablezInfo* info : infos) {
EXPECT_EQ(info->soo_capacity, 0);
ASSERT_EQ(info->capacity, 1);
ASSERT_EQ(info->size, 0);
}
}
// Verifies that copy-constructing or copy-assigning an SOO table does not
// incorrectly trigger new sampling evaluations.
TEST(RawHashSamplerTest, SooTableCopyDoesNotOversample) {