Skip to content

Commit fa0f64f

Browse files
authored
fix: Optimize GetRandomChain() in DenseSet (#6033)
* fix: Update dense_set * fix: review comments * fix: review comments
1 parent 384f7ea commit fa0f64f

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

src/core/dense_set.cc

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ constexpr size_t kMinSizeShift = 2;
2727
constexpr size_t kMinSize = 1 << kMinSizeShift;
2828
constexpr bool kAllowDisplacements = true;
2929

30+
thread_local absl::InsecureBitGen tl_bit_gen;
31+
3032
#define PREFETCH_READ(x) __builtin_prefetch(x, 0, 1)
3133

3234
DenseSet::IteratorBase::IteratorBase(const DenseSet* owner, bool is_end)
@@ -673,13 +675,28 @@ void DenseSet::Delete(DensePtr* prev, DensePtr* ptr) {
673675
}
674676

675677
DenseSet::ChainVectorIterator DenseSet::GetRandomChain() {
676-
size_t offset = absl::Uniform(absl::BitGen{}, 0u, entries_.size());
677-
for (size_t i = offset; i < entries_.size() + offset; i++) {
678-
auto it = entries_.begin() + (i % entries_.size());
679-
ExpireIfNeeded(nullptr, &*it);
680-
if (!it->IsEmpty())
681-
return it;
678+
if (entries_.empty() || size_ == 0) {
679+
return entries_.end();
682680
}
681+
682+
size_t offset = absl::Uniform<size_t>(tl_bit_gen, 0u, entries_.size());
683+
684+
// Start at random position and scan linearly with wrap-around
685+
auto it = entries_.begin() + offset;
686+
for (size_t n = 0; n < entries_.size(); n++) {
687+
// Check IsEmpty first to avoid ExpireIfNeeded overhead on empty buckets
688+
if (!it->IsEmpty()) {
689+
ExpireIfNeeded(nullptr, &*it);
690+
if (!it->IsEmpty()) {
691+
return it;
692+
}
693+
}
694+
695+
if (++it == entries_.end()) {
696+
it = entries_.begin();
697+
}
698+
}
699+
683700
return entries_.end();
684701
}
685702

@@ -689,8 +706,7 @@ DenseSet::IteratorBase DenseSet::GetRandomIterator() {
689706
return IteratorBase{};
690707

691708
DensePtr* ptr = &*chain_it;
692-
absl::BitGen bg{};
693-
while (ptr->IsLink() && absl::Bernoulli(bg, 0.5)) {
709+
while (ptr->IsLink() && absl::Bernoulli(tl_bit_gen, 0.5)) {
694710
DensePtr* next = ptr->Next();
695711
if (ExpireIfNeeded(ptr, next)) // stop if we break the chain with expiration
696712
break;

0 commit comments

Comments
 (0)