mirror of
https://github.com/ruby/ruby.git
synced 2026-01-27 04:24:23 +00:00
Change load factor of concur. set from 0.5 to 0.75 (#15007)
Before, the 50% load factor was not working correctly with the new capacity calculation on resize and too many resizes were seen. Before this change ------------------ Example: old_capacity = 32 old_size = 16 deleted_entries = 2 (almost all live) That means we have: expected_size = 14 We'll see that 64 > 14 * 4 We'll end up using 32 as the new capacity (same as old) even though that only leaves us two elements free before we'd have to rebuild again. Co-authored-by: John Hawthorn <john.hawthorn@shopify.com>
This commit is contained in:
parent
34b0ac68b3
commit
2afcdc6902
Notes:
git
2025-10-30 21:15:05 +00:00
Merged-By: luke-gru <luke.gru@gmail.com>
@ -118,6 +118,7 @@ concurrent_set_try_resize_without_locking(VALUE old_set_obj, VALUE *set_obj_ptr)
|
||||
// GC may also happen between now and the set being rebuilt
|
||||
int expected_size = rbimpl_atomic_load(&old_set->size, RBIMPL_ATOMIC_RELAXED) - old_set->deleted_entries;
|
||||
|
||||
// NOTE: new capacity must make sense with load factor, don't change one without checking the other.
|
||||
struct concurrent_set_entry *old_entries = old_set->entries;
|
||||
int old_capacity = old_set->capacity;
|
||||
int new_capacity = old_capacity * 2;
|
||||
@ -287,7 +288,10 @@ rb_concurrent_set_find_or_insert(VALUE *set_obj_ptr, VALUE key, void *data)
|
||||
|
||||
rb_atomic_t prev_size = rbimpl_atomic_fetch_add(&set->size, 1, RBIMPL_ATOMIC_RELAXED);
|
||||
|
||||
if (UNLIKELY(prev_size > set->capacity / 2)) {
|
||||
// Load_factor reached at 75% full. ex: prev_size: 32, capacity: 64, load_factor: 50%.
|
||||
bool load_factor_reached = (uint64_t)(prev_size * 4) >= (uint64_t)(set->capacity * 3);
|
||||
|
||||
if (UNLIKELY(load_factor_reached)) {
|
||||
concurrent_set_try_resize(set_obj, set_obj_ptr);
|
||||
|
||||
goto retry;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user