Skip to content

Commit 74d4ed7

Browse files
ko1claude
andcommitted
Fix flaky TestHash#test_rehash by modelling the AR substitution hint
test_rehash mutates a key until its own `hash_hint` (the low byte of `Array#hash`) changes, then asserts the stale key no longer hits. Since 127e903 "hash.c: add a substition hint", `ar_do_hash_hint()` maps RHASH_AR_CLEARED_HINT (0x00) to RHASH_AR_SUBSTITUTION_HINT (0x01), so hash values ending in 0x00 and 0x01 share a hint. When the mutation loop happened to exit on such a pair, the test believed the hint had changed while the AR table's hint had not: `ar_find_entry_hint()` still matched and `ar_equal()` compared the key against itself, so the lookup returned 100 instead of nil. That commit adjusted the affected specs but not test/ruby/test_hash.rb. Mirror the substitution in `hash_hint` so the loop keeps going until the hint really changes. The hash seed is per process, so this depended on the run; measured over 2,000,000 independent starting hashes the old loop failed 63 times (1/31746), matching the predicted (2/256) * (1/255). Both TestHash and TestHash::TestSubHash fail together because they share a process and build the same strings. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 81ab701 commit 74d4ed7

1 file changed

Lines changed: 4 additions & 1 deletion

File tree

test/ruby/test_hash.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,10 @@ def test_member?
617617
end
618618

619619
def hash_hint hv
620-
hv & 0xff
620+
hint = hv & 0xff
621+
# hash.c's ar_do_hash_hint() substitutes RHASH_AR_CLEARED_HINT (0x00)
622+
# with RHASH_AR_SUBSTITUTION_HINT (0x01), so those two alias.
623+
hint == 0 ? 1 : hint
621624
end
622625

623626
def test_rehash

0 commit comments

Comments
 (0)