@@ -677,30 +677,27 @@ DenseSet::ChainVectorIterator DenseSet::GetRandomChain() {
677677 return entries_.end ();
678678 }
679679
680- // Use thread-local generator to avoid repeated construction overhead
681- thread_local absl::BitGen gen;
682-
683- // Try up to 32 random probes before falling back to linear scan
684- // Expected probes needed = 1 / utilization
685- // For 10% util, expected = 10 probes, so 32 gives good probability
686- constexpr int kMaxProbes = 32 ;
687- for (int probe = 0 ; probe < kMaxProbes ; probe++) {
688- size_t idx = absl::Uniform<size_t >(gen, 0u , entries_.size ());
689- auto it = entries_.begin () + idx;
690- ExpireIfNeeded (nullptr , &*it);
680+ // Use thread-local generator to avoid construction overhead
681+ thread_local absl::InsecureBitGen gen;
682+
683+ size_t offset = absl::Uniform<size_t >(gen, 0u , entries_.size ());
684+
685+ // Start at random position and scan linearly with wrap-around
686+ auto it = entries_.begin () + offset;
687+ for (size_t n = 0 ; n < entries_.size (); n++) {
688+ // Check IsEmpty first to avoid ExpireIfNeeded overhead on empty buckets
691689 if (!it->IsEmpty ()) {
692- return it;
690+ ExpireIfNeeded (nullptr , &*it);
691+ if (!it->IsEmpty ()) {
692+ return it;
693+ }
693694 }
694- }
695695
696- // Fallback or normal path: linear scan from random offset
697- size_t offset = absl::Uniform<size_t >(gen, 0u , entries_.size ());
698- for (size_t i = offset; i < entries_.size () + offset; i++) {
699- auto it = entries_.begin () + (i % entries_.size ());
700- ExpireIfNeeded (nullptr , &*it);
701- if (!it->IsEmpty ())
702- return it;
696+ if (++it == entries_.end ()) {
697+ it = entries_.begin ();
698+ }
703699 }
700+
704701 return entries_.end ();
705702}
706703
@@ -710,7 +707,7 @@ DenseSet::IteratorBase DenseSet::GetRandomIterator() {
710707 return IteratorBase{};
711708
712709 DensePtr* ptr = &*chain_it;
713- absl::BitGen bg{};
710+ thread_local absl::InsecureBitGen bg{};
714711 while (ptr->IsLink () && absl::Bernoulli (bg, 0.5 )) {
715712 DensePtr* next = ptr->Next ();
716713 if (ExpireIfNeeded (ptr, next)) // stop if we break the chain with expiration
0 commit comments