Skip to content

Commit 7f281c1

Browse files
ezbrcopybara-github
authored andcommitted
Add PolicyFunctions::soo_capacity() so that the compiler knows that soo_capacity() is always 0 or 1.
Also, add AssertSoo()/AssertFullSoo() functions. PiperOrigin-RevId: 755092153 Change-Id: I2eb3cfabaa34ae436af47e06b88531b2ed144e3a
1 parent 4eb1e49 commit 7f281c1

File tree

2 files changed

+49
-41
lines changed

2 files changed

+49
-41
lines changed

absl/container/internal/raw_hash_set.cc

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ template <ResizeNonSooMode kMode>
617617
void ResizeNonSooImpl(CommonFields& common, const PolicyFunctions& policy,
618618
size_t new_capacity, HashtablezInfoHandle infoz) {
619619
ABSL_SWISSTABLE_ASSERT(IsValidCapacity(new_capacity));
620-
ABSL_SWISSTABLE_ASSERT(new_capacity > policy.soo_capacity);
620+
ABSL_SWISSTABLE_ASSERT(new_capacity > policy.soo_capacity());
621621

622622
const size_t old_capacity = common.capacity();
623623
[[maybe_unused]] ctrl_t* old_ctrl = common.control();
@@ -643,7 +643,7 @@ void ResizeNonSooImpl(CommonFields& common, const PolicyFunctions& policy,
643643
size_t total_probe_length = 0;
644644
ResetCtrl(common, slot_size);
645645
ABSL_SWISSTABLE_ASSERT(kMode != ResizeNonSooMode::kGuaranteedEmpty ||
646-
old_capacity == policy.soo_capacity);
646+
old_capacity == policy.soo_capacity());
647647
ABSL_SWISSTABLE_ASSERT(kMode != ResizeNonSooMode::kGuaranteedAllocated ||
648648
old_capacity > 0);
649649
if constexpr (kMode == ResizeNonSooMode::kGuaranteedAllocated) {
@@ -670,17 +670,17 @@ void ResizeEmptyNonAllocatedTableImpl(CommonFields& common,
670670
const PolicyFunctions& policy,
671671
size_t new_capacity, bool force_infoz) {
672672
ABSL_SWISSTABLE_ASSERT(IsValidCapacity(new_capacity));
673-
ABSL_SWISSTABLE_ASSERT(new_capacity > policy.soo_capacity);
674-
ABSL_SWISSTABLE_ASSERT(!force_infoz || policy.soo_capacity > 0);
675-
ABSL_SWISSTABLE_ASSERT(common.capacity() <= policy.soo_capacity);
673+
ABSL_SWISSTABLE_ASSERT(new_capacity > policy.soo_capacity());
674+
ABSL_SWISSTABLE_ASSERT(!force_infoz || policy.soo_enabled);
675+
ABSL_SWISSTABLE_ASSERT(common.capacity() <= policy.soo_capacity());
676676
ABSL_SWISSTABLE_ASSERT(common.empty());
677677
const size_t slot_size = policy.slot_size;
678678
HashtablezInfoHandle infoz;
679679
const bool should_sample =
680680
policy.is_hashtablez_eligible && (force_infoz || ShouldSampleNextTable());
681681
if (ABSL_PREDICT_FALSE(should_sample)) {
682682
infoz = ForcedTrySample(slot_size, policy.key_size, policy.value_size,
683-
policy.soo_capacity);
683+
policy.soo_capacity());
684684
}
685685
ResizeNonSooImpl<ResizeNonSooMode::kGuaranteedEmpty>(common, policy,
686686
new_capacity, infoz);
@@ -694,8 +694,8 @@ void InsertOldSooSlotAndInitializeControlBytes(CommonFields& c,
694694
const PolicyFunctions& policy,
695695
size_t hash, ctrl_t* new_ctrl,
696696
void* new_slots) {
697-
ABSL_SWISSTABLE_ASSERT(c.size() == policy.soo_capacity);
698-
ABSL_SWISSTABLE_ASSERT(policy.soo_capacity == SooCapacity());
697+
ABSL_SWISSTABLE_ASSERT(c.size() == policy.soo_capacity());
698+
ABSL_SWISSTABLE_ASSERT(policy.soo_enabled);
699699
size_t new_capacity = c.capacity();
700700

701701
c.generate_new_seed();
@@ -717,12 +717,21 @@ enum class ResizeFullSooTableSamplingMode {
717717
kForceSampleNoResizeIfUnsampled,
718718
};
719719

720+
void AssertSoo([[maybe_unused]] CommonFields& common,
721+
[[maybe_unused]] const PolicyFunctions& policy) {
722+
ABSL_SWISSTABLE_ASSERT(policy.soo_enabled);
723+
ABSL_SWISSTABLE_ASSERT(common.capacity() == policy.soo_capacity());
724+
}
725+
void AssertFullSoo([[maybe_unused]] CommonFields& common,
726+
[[maybe_unused]] const PolicyFunctions& policy) {
727+
AssertSoo(common, policy);
728+
ABSL_SWISSTABLE_ASSERT(common.size() == policy.soo_capacity());
729+
}
730+
720731
void ResizeFullSooTable(CommonFields& common, const PolicyFunctions& policy,
721732
size_t new_capacity,
722733
ResizeFullSooTableSamplingMode sampling_mode) {
723-
ABSL_SWISSTABLE_ASSERT(common.capacity() == policy.soo_capacity);
724-
ABSL_SWISSTABLE_ASSERT(common.size() == policy.soo_capacity);
725-
ABSL_SWISSTABLE_ASSERT(policy.soo_capacity == SooCapacity());
734+
AssertFullSoo(common, policy);
726735
const size_t slot_size = policy.slot_size;
727736
const size_t slot_align = policy.slot_align;
728737

@@ -731,7 +740,7 @@ void ResizeFullSooTable(CommonFields& common, const PolicyFunctions& policy,
731740
ResizeFullSooTableSamplingMode::kForceSampleNoResizeIfUnsampled) {
732741
if (ABSL_PREDICT_FALSE(policy.is_hashtablez_eligible)) {
733742
infoz = ForcedTrySample(slot_size, policy.key_size, policy.value_size,
734-
policy.soo_capacity);
743+
policy.soo_capacity());
735744
}
736745

737746
if (!infoz.IsSampled()) {
@@ -1218,11 +1227,11 @@ size_t GrowToNextCapacityAndPrepareInsert(CommonFields& common,
12181227
ABSL_SWISSTABLE_ASSERT(common.growth_left() == 0);
12191228
const size_t old_capacity = common.capacity();
12201229
ABSL_SWISSTABLE_ASSERT(old_capacity == 0 ||
1221-
old_capacity > policy.soo_capacity);
1230+
old_capacity > policy.soo_capacity());
12221231

12231232
const size_t new_capacity = NextCapacity(old_capacity);
12241233
ABSL_SWISSTABLE_ASSERT(IsValidCapacity(new_capacity));
1225-
ABSL_SWISSTABLE_ASSERT(new_capacity > policy.soo_capacity);
1234+
ABSL_SWISSTABLE_ASSERT(new_capacity > policy.soo_capacity());
12261235

12271236
ctrl_t* old_ctrl = common.control();
12281237
void* old_slots = common.slot_array();
@@ -1238,7 +1247,7 @@ size_t GrowToNextCapacityAndPrepareInsert(CommonFields& common,
12381247
policy.is_hashtablez_eligible && ShouldSampleNextTable();
12391248
if (ABSL_PREDICT_FALSE(should_sample)) {
12401249
infoz = ForcedTrySample(slot_size, policy.key_size, policy.value_size,
1241-
policy.soo_capacity);
1250+
policy.soo_capacity());
12421251
}
12431252
}
12441253
const bool has_infoz = infoz.IsSampled();
@@ -1291,7 +1300,7 @@ size_t GrowToNextCapacityAndPrepareInsert(CommonFields& common,
12911300
find_info = find_first_non_full(common, new_hash);
12921301
SetCtrlInLargeTable(common, find_info.offset, new_h2, policy.slot_size);
12931302
}
1294-
ABSL_SWISSTABLE_ASSERT(old_capacity > policy.soo_capacity);
1303+
ABSL_SWISSTABLE_ASSERT(old_capacity > policy.soo_capacity());
12951304
(*policy.dealloc)(alloc, old_capacity, old_ctrl, slot_size, slot_align,
12961305
has_infoz);
12971306
}
@@ -1415,9 +1424,9 @@ GrowEmptySooTableToNextCapacityForceSamplingAndPrepareInsert(
14151424

14161425
// Resizes empty non-allocated table to the capacity to fit new_size elements.
14171426
// Requires:
1418-
// 1. `c.capacity() == policy.soo_capacity`.
1427+
// 1. `c.capacity() == policy.soo_capacity()`.
14191428
// 2. `c.empty()`.
1420-
// 3. `new_size > policy.soo_capacity`.
1429+
// 3. `new_size > policy.soo_capacity()`.
14211430
// The table will be attempted to be sampled.
14221431
void ReserveEmptyNonAllocatedTableToFitNewSize(CommonFields& common,
14231432
const PolicyFunctions& policy,
@@ -1435,20 +1444,20 @@ void ReserveEmptyNonAllocatedTableToFitNewSize(CommonFields& common,
14351444
// allocated backing array.
14361445
//
14371446
// Requires:
1438-
// 1. `c.capacity() > policy.soo_capacity` OR `!c.empty()`.
1447+
// 1. `c.capacity() > policy.soo_capacity()` OR `!c.empty()`.
14391448
// Reserving already allocated tables is considered to be a rare case.
14401449
ABSL_ATTRIBUTE_NOINLINE void ReserveAllocatedTable(
14411450
CommonFields& common, const PolicyFunctions& policy, size_t new_size) {
14421451
const size_t cap = common.capacity();
14431452
ValidateMaxSize(new_size, policy.slot_size);
14441453
ABSL_ASSUME(new_size > 0);
14451454
const size_t new_capacity = SizeToCapacity(new_size);
1446-
if (cap == policy.soo_capacity) {
1455+
if (cap == policy.soo_capacity()) {
14471456
ABSL_SWISSTABLE_ASSERT(!common.empty());
14481457
ResizeFullSooTable(common, policy, new_capacity,
14491458
ResizeFullSooTableSamplingMode::kNoSampling);
14501459
} else {
1451-
ABSL_SWISSTABLE_ASSERT(cap > policy.soo_capacity);
1460+
ABSL_SWISSTABLE_ASSERT(cap > policy.soo_capacity());
14521461
// TODO(b/382423690): consider using GrowToNextCapacity, when applicable.
14531462
ResizeAllocatedTableWithSeedChange(common, policy, new_capacity);
14541463
}
@@ -1486,16 +1495,14 @@ size_t GrowSooTableToNextCapacityAndPrepareInsert(CommonFields& common,
14861495
const PolicyFunctions& policy,
14871496
size_t new_hash,
14881497
ctrl_t soo_slot_ctrl) {
1489-
ABSL_SWISSTABLE_ASSERT(common.capacity() == policy.soo_capacity);
1490-
ABSL_SWISSTABLE_ASSERT(policy.soo_capacity == SooCapacity());
1498+
AssertSoo(common, policy);
14911499
if (ABSL_PREDICT_FALSE(soo_slot_ctrl == ctrl_t::kEmpty)) {
14921500
// The table is empty, it is only used for forced sampling of SOO tables.
14931501
return GrowEmptySooTableToNextCapacityForceSamplingAndPrepareInsert(
14941502
common, policy, new_hash);
14951503
}
1496-
ABSL_SWISSTABLE_ASSERT(common.size() == policy.soo_capacity);
1504+
ABSL_SWISSTABLE_ASSERT(common.size() == policy.soo_capacity());
14971505
static constexpr size_t kNewCapacity = NextCapacity(SooCapacity());
1498-
ABSL_SWISSTABLE_ASSERT(kNewCapacity > policy.soo_capacity);
14991506
const size_t slot_size = policy.slot_size;
15001507
const size_t slot_align = policy.slot_align;
15011508
common.set_capacity(kNewCapacity);
@@ -1560,9 +1567,7 @@ size_t GrowSooTableToNextCapacityAndPrepareInsert(CommonFields& common,
15601567

15611568
void GrowFullSooTableToNextCapacityForceSampling(
15621569
CommonFields& common, const PolicyFunctions& policy) {
1563-
ABSL_SWISSTABLE_ASSERT(common.capacity() == policy.soo_capacity);
1564-
ABSL_SWISSTABLE_ASSERT(common.size() == policy.soo_capacity);
1565-
ABSL_SWISSTABLE_ASSERT(policy.soo_capacity == SooCapacity());
1570+
AssertFullSoo(common, policy);
15661571
ResizeFullSooTable(
15671572
common, policy, NextCapacity(SooCapacity()),
15681573
ResizeFullSooTableSamplingMode::kForceSampleNoResizeIfUnsampled);
@@ -1573,18 +1578,18 @@ void Rehash(CommonFields& common, const PolicyFunctions& policy, size_t n) {
15731578

15741579
auto clear_backing_array = [&]() {
15751580
ClearBackingArray(common, policy, policy.get_char_alloc(common),
1576-
/*reuse=*/false, policy.soo_capacity > 0);
1581+
/*reuse=*/false, policy.soo_enabled);
15771582
};
15781583

15791584
const size_t slot_size = policy.slot_size;
15801585

15811586
if (n == 0) {
1582-
if (cap <= policy.soo_capacity) return;
1587+
if (cap <= policy.soo_capacity()) return;
15831588
if (common.empty()) {
15841589
clear_backing_array();
15851590
return;
15861591
}
1587-
if (common.size() <= policy.soo_capacity) {
1592+
if (common.size() <= policy.soo_capacity()) {
15881593
// When the table is already sampled, we keep it sampled.
15891594
if (common.infoz().IsSampled()) {
15901595
static constexpr size_t kInitialSampledCapacity =
@@ -1618,7 +1623,7 @@ void Rehash(CommonFields& common, const PolicyFunctions& policy, size_t n) {
16181623
NormalizeCapacity(n | SizeToCapacity(common.size()));
16191624
// n == 0 unconditionally rehashes as per the standard.
16201625
if (n == 0 || new_capacity > cap) {
1621-
if (cap == policy.soo_capacity) {
1626+
if (cap == policy.soo_capacity()) {
16221627
if (common.empty()) {
16231628
ResizeEmptyNonAllocatedTableImpl(common, policy, new_capacity,
16241629
/*force_infoz=*/false);
@@ -1640,7 +1645,7 @@ void Copy(CommonFields& common, const PolicyFunctions& policy,
16401645
absl::FunctionRef<void(void*, const void*)> copy_fn) {
16411646
const size_t size = other.size();
16421647
ABSL_SWISSTABLE_ASSERT(size > 0);
1643-
const size_t soo_capacity = policy.soo_capacity;
1648+
const size_t soo_capacity = policy.soo_capacity();
16441649
const size_t slot_size = policy.slot_size;
16451650
if (size <= soo_capacity) {
16461651
ABSL_SWISSTABLE_ASSERT(size == 1);
@@ -1714,17 +1719,17 @@ void ReserveTableToFitNewSize(CommonFields& common,
17141719
const PolicyFunctions& policy, size_t new_size) {
17151720
common.reset_reserved_growth(new_size);
17161721
common.set_reservation_size(new_size);
1717-
ABSL_SWISSTABLE_ASSERT(new_size > policy.soo_capacity);
1722+
ABSL_SWISSTABLE_ASSERT(new_size > policy.soo_capacity());
17181723
const size_t cap = common.capacity();
1719-
if (ABSL_PREDICT_TRUE(common.empty() && cap <= policy.soo_capacity)) {
1724+
if (ABSL_PREDICT_TRUE(common.empty() && cap <= policy.soo_capacity())) {
17201725
return ReserveEmptyNonAllocatedTableToFitNewSize(common, policy, new_size);
17211726
}
17221727

1723-
ABSL_SWISSTABLE_ASSERT(!common.empty() || cap > policy.soo_capacity);
1728+
ABSL_SWISSTABLE_ASSERT(!common.empty() || cap > policy.soo_capacity());
17241729
ABSL_SWISSTABLE_ASSERT(cap > 0);
17251730
const size_t max_size_before_growth =
1726-
cap <= policy.soo_capacity ? policy.soo_capacity
1727-
: common.size() + common.growth_left();
1731+
cap <= policy.soo_capacity() ? policy.soo_capacity()
1732+
: common.size() + common.growth_left();
17281733
if (new_size <= max_size_before_growth) {
17291734
return;
17301735
}

absl/container/internal/raw_hash_set.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,7 +1640,7 @@ struct PolicyFunctions {
16401640
uint32_t value_size;
16411641
uint32_t slot_size;
16421642
uint16_t slot_align;
1643-
uint8_t soo_capacity;
1643+
bool soo_enabled;
16441644
bool is_hashtablez_eligible;
16451645

16461646
// Returns the pointer to the hash function stored in the set.
@@ -1678,6 +1678,10 @@ struct PolicyFunctions {
16781678
void* probed_storage,
16791679
void (*encode_probed_element)(void* probed_storage, h2_t h2,
16801680
size_t source_offset, size_t h1));
1681+
1682+
uint8_t soo_capacity() const {
1683+
return static_cast<uint8_t>(soo_enabled ? SooCapacity() : 0);
1684+
}
16811685
};
16821686

16831687
// Returns the maximum valid size for a table with 1-byte slots.
@@ -3609,8 +3613,7 @@ class raw_hash_set {
36093613
static_cast<uint32_t>(sizeof(key_type)),
36103614
static_cast<uint32_t>(sizeof(value_type)),
36113615
static_cast<uint16_t>(sizeof(slot_type)),
3612-
static_cast<uint16_t>(alignof(slot_type)),
3613-
static_cast<uint8_t>(SooEnabled() ? SooCapacity() : 0),
3616+
static_cast<uint16_t>(alignof(slot_type)), SooEnabled(),
36143617
ShouldSampleHashtablezInfoForAlloc<CharAlloc>(),
36153618
// TODO(b/328722020): try to type erase
36163619
// for standard layout and alignof(Hash) <= alignof(CommonFields).

0 commit comments

Comments
 (0)