diff options
author | Marc-Andre Lafortune <github@marc-andre.ca> | 2021-03-15 22:15:03 -0400 |
---|---|---|
committer | Marc-Andre Lafortune <github@marc-andre.ca> | 2021-03-18 07:34:40 -0400 |
commit | 0ef2923c2b9afb76b3a1cebc56ebabc71c9a2ba8 (patch) | |
tree | a5572db3a246e53e1293823249e8ad4413ef061b | |
parent | d094c3ef046aba0bb99fd08bcbc72ff87216e736 (diff) |
Avoid rehashing in Hash#replace/dup/initialize_copy [Bug #16996]
-rw-r--r-- | hash.c | 2 | ||||
-rw-r--r-- | test/ruby/test_hash.rb | 10 | ||||
-rw-r--r-- | test/test_set.rb | 7 |
3 files changed, 7 insertions, 12 deletions
@@ -2958,7 +2958,7 @@ rb_hash_replace(VALUE hash, VALUE hash2) RHASH_TBL_RAW(hash)->type = RHASH_ST_TABLE(hash2)->type; } } - rb_hash_foreach(hash2, rb_hash_rehash_i, (VALUE)hash); + hash_copy(hash, hash2); rb_gc_writebarrier_remember(hash); diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb index 25dfaf4f64..3458053fea 100644 --- a/test/ruby/test_hash.rb +++ b/test/ruby/test_hash.rb @@ -113,13 +113,8 @@ class TestHash < Test::Unit::TestCase assert_equal(2, h[1]) end - def test_dup_will_rehash - set1 = @cls[] - set2 = @cls[set1 => true] - - set1[set1] = true - - assert_equal set2, set2.dup + def test_dup_will_not_rehash + assert_hash_does_not_rehash(&:dup) end def assert_hash_does_not_rehash @@ -480,6 +475,7 @@ class TestHash < Test::Unit::TestCase h1 = @cls[h => 1] assert_equal(h1, h1.dup) h[1] = 2 + h1.rehash assert_equal(h1, h1.dup) end diff --git a/test/test_set.rb b/test/test_set.rb index e62f30d852..af9806ed51 100644 --- a/test/test_set.rb +++ b/test/test_set.rb @@ -637,11 +637,10 @@ class TC_Set < Test::Unit::TestCase assert_not_equal(Set[1], [1]) set1 = Class.new(Set)["a", "b"] - set2 = Set["a", "b", set1] - set1 = set1.add(set1.clone) + set1.add(set1).reset # Make recursive + set2 = Set["a", "b", Set["a", "b", set1]] - assert_equal(set2, set2.clone) - assert_equal(set1.clone, set1) + assert_equal(set1, set2) assert_not_equal(Set[Exception.new,nil], Set[Exception.new,Exception.new], "[ruby-dev:26127]") end |