[前][次][番号順一覧][スレッド一覧]

ruby-changes:71133

From: Yusuke <ko1@a...>
Date: Thu, 10 Feb 2022 00:14:53 +0900 (JST)
Subject: [ruby-changes:71133] 496591de96 (master): st.c: Do not clear entries_bound when calling Hash#shift for empty hash

https://git.ruby-lang.org/ruby.git/commit/?id=496591de96

From 496591de96b261b8789332c7f8b2bfbd17658955 Mon Sep 17 00:00:00 2001
From: Yusuke Endoh <mame@r...>
Date: Wed, 9 Feb 2022 18:24:17 +0900
Subject: st.c: Do not clear entries_bound when calling Hash#shift for empty
 hash

tab->entries_bound is used to check if the bins are full in
rebuild_table_if_necessary.

Hash#shift against an empty hash assigned 0 to tab->entries_bound, but
didn't clear the bins. Thus, the table is not rebuilt even when the bins
are full. Attempting to add a new element into full-bin hash gets stuck.

This change stops clearing tab->entries_bound in Hash#shift.
[Bug #18578]
---
 st.c                   |  1 -
 test/ruby/test_hash.rb | 13 +++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/st.c b/st.c
index 53e9dc8320..07a083abb0 100644
--- a/st.c
+++ b/st.c
@@ -1363,7 +1363,6 @@ st_shift(st_table *tab, st_data_t *key, st_data_t *value) https://github.com/ruby/ruby/blob/trunk/st.c#L1363
 	    return 1;
 	}
     }
-    tab->entries_start = tab->entries_bound = 0;
     if (value != 0) *value = 0;
     return 0;
 }
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb
index 39376524fa..073a0dabe8 100644
--- a/test/ruby/test_hash.rb
+++ b/test/ruby/test_hash.rb
@@ -1069,6 +1069,19 @@ class TestHash < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_hash.rb#L1069
     assert_nil(h.shift)
   end
 
+  def test_shift_for_empty_hash
+    # [ruby-dev:51159]
+    h = @cls[]
+    100.times{|n|
+      while h.size < n
+        k = Random.rand 0..1<<30
+        h[k] = 1
+      end
+      0 while h.shift
+      assert_equal({}, h)
+    }
+  end
+
   def test_reject_bang2
     assert_equal({1=>2}, @cls[1=>2,3=>4].reject! {|k, v| k + v == 7 })
     assert_nil(@cls[1=>2,3=>4].reject! {|k, v| k == 5 })
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]