<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/test/ruby/test_hash.rb, branch v3_2_11</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>Replace tombstone when converting AR to ST hash</title>
<updated>2025-03-06T02:05:43+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2025-03-05T22:21:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=bb6b3c98dc06b92c48928d8c7f942b3dfd990089'/>
<id>bb6b3c98dc06b92c48928d8c7f942b3dfd990089</id>
<content type='text'>
[Bug #21170]

st_table reserves -1 as a special hash value to indicate that an entry
has been deleted. So that that's a valid value to be returned from the
hash function, do_hash replaces -1 with 0 so that it is not mistaken for
the sentinel.

Previously, when upgrading an AR table to an ST table,
rb_st_add_direct_with_hash was used which did not perform the same
conversion, this could lead to a hash in a broken state where one if its
entries which was supposed to exist being marked as a tombstone.

The hash could then become further corrupted when the ST table required
resizing as the falsely tombstoned entry would be skipped but it would
be counted in num entries, leading to an uninitialized entry at index
15.

In most cases this will be really rare, unless using a very poorly
implemented custom hash function.

This also adds two debug assertions, one that st_add_direct_with_hash
does not receive the reserved hash value, and a second in
rebuild_table_with, which ensures that after we rebuild/compact a table
it contains the expected number of elements.

Co-authored-by: Alan Wu &lt;alanwu@ruby-lang.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Bug #21170]

st_table reserves -1 as a special hash value to indicate that an entry
has been deleted. So that that's a valid value to be returned from the
hash function, do_hash replaces -1 with 0 so that it is not mistaken for
the sentinel.

Previously, when upgrading an AR table to an ST table,
rb_st_add_direct_with_hash was used which did not perform the same
conversion, this could lead to a hash in a broken state where one if its
entries which was supposed to exist being marked as a tombstone.

The hash could then become further corrupted when the ST table required
resizing as the falsely tombstoned entry would be skipped but it would
be counted in num entries, leading to an uninitialized entry at index
15.

In most cases this will be really rare, unless using a very poorly
implemented custom hash function.

This also adds two debug assertions, one that st_add_direct_with_hash
does not receive the reserved hash value, and a second in
rebuild_table_with, which ensures that after we rebuild/compact a table
it contains the expected number of elements.

Co-authored-by: Alan Wu &lt;alanwu@ruby-lang.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>merge revision(s) f36a71e26995b69ff72bc132bbcf40ad89571414: [Backport #20307]</title>
<updated>2024-07-13T06:43:23+00:00</updated>
<author>
<name>nagachika</name>
<email>nagachika@ruby-lang.org</email>
</author>
<published>2024-07-13T06:43:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=90a44bcd39c569d851f73d167955c83f3ff2384f'/>
<id>90a44bcd39c569d851f73d167955c83f3ff2384f</id>
<content type='text'>
	[Bug #20307] Fix `Hash#update` to make frozen copy of string keys
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	[Bug #20307] Fix `Hash#update` to make frozen copy of string keys
</pre>
</div>
</content>
</entry>
<entry>
<title>Backport https://github.com/ruby/ruby/pull/9240 to Ruby 3.2</title>
<updated>2024-04-08T09:40:47+00:00</updated>
<author>
<name>KJ Tsanaktsidis</name>
<email>ktsanaktsidis@zendesk.com</email>
</author>
<published>2024-03-28T04:57:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=06049fe98ef6eced6ccf6028621f3e10edeedccb'/>
<id>06049fe98ef6eced6ccf6028621f3e10edeedccb</id>
<content type='text'>
Merged into master in 7ba2506232d3fa6c4e82e3708c0ff746a1a8de5c

[Bug #20050]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Merged into master in 7ba2506232d3fa6c4e82e3708c0ff746a1a8de5c

[Bug #20050]
</pre>
</div>
</content>
</entry>
<entry>
<title>merge revision(s) 9eac9d71786a8dbec520d0541a91149f01adf8ea: [Backport #19969]</title>
<updated>2023-11-19T13:00:38+00:00</updated>
<author>
<name>nagachika</name>
<email>nagachika@ruby-lang.org</email>
</author>
<published>2023-11-19T13:00:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=1cc38d5a2f84733e1c2e42548639e2891fe61e69'/>
<id>1cc38d5a2f84733e1c2e42548639e2891fe61e69</id>
<content type='text'>
	[Bug #19969] Compact st_table after deleted if possible

	---
	 hash.c                 | 19 +++++++++++++++++++
	 st.c                   | 40 +++++++++++++++++++++++++++++-----------
	 test/ruby/test_hash.rb |  9 +++++++++
	 3 files changed, 57 insertions(+), 11 deletions(-)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	[Bug #19969] Compact st_table after deleted if possible

	---
	 hash.c                 | 19 +++++++++++++++++++
	 st.c                   | 40 +++++++++++++++++++++++++++++-----------
	 test/ruby/test_hash.rb |  9 +++++++++
	 3 files changed, 57 insertions(+), 11 deletions(-)
</pre>
</div>
</content>
</entry>
<entry>
<title>merge revision(s) 8c360ce713f57d4177de833297364f6f6d950420: [Backport #19589]</title>
<updated>2023-07-17T05:21:39+00:00</updated>
<author>
<name>nagachika</name>
<email>nagachika@ruby-lang.org</email>
</author>
<published>2023-07-17T05:21:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=8165db0f4666f90fe0df5cdd466f73c6de1f6cea'/>
<id>8165db0f4666f90fe0df5cdd466f73c6de1f6cea</id>
<content type='text'>
	hash.c: Fix hash_iter_lev_dec corrupting shape

	[Bug #19589]

	When decrementing `iter_lev` from `65` to `64` the flags would be
	corrupted, causing the shape_id to be invalid.
	---
	 hash.c                 | 12 +++++++++---
	 test/ruby/test_hash.rb | 11 +++++++++++
	 2 files changed, 20 insertions(+), 3 deletions(-)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	hash.c: Fix hash_iter_lev_dec corrupting shape

	[Bug #19589]

	When decrementing `iter_lev` from `65` to `64` the flags would be
	corrupted, causing the shape_id to be invalid.
	---
	 hash.c                 | 12 +++++++++---
	 test/ruby/test_hash.rb | 11 +++++++++++
	 2 files changed, 20 insertions(+), 3 deletions(-)
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix inconsistency with opt_aref_with</title>
<updated>2022-08-04T21:48:47+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2022-07-28T23:41:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=70b60d24b9c3859a859853ddb2e17c603bd3485b'/>
<id>70b60d24b9c3859a859853ddb2e17c603bd3485b</id>
<content type='text'>
opt_aref_with is an optimized instruction for accessing a Hash using a
non-frozen string key (ie. from a file without frozen_string_literal).
It attempts to avoid allocating the string, and instead silently using a
frozen string (hash string keys are always fstrings).

Because this is just an optimization, it should be invisible to the
user. However, previously this optimization was could be seen via hashes
with default procs.

For example, previously:

    h = Hash.new { |h, k| k.frozen? }
    str = "foo"
    h[str]   # false
    h["foo"] # true when optimizations enabled

This commit checks that the Hash doesn't have a default proc when using
opt_aref_with.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
opt_aref_with is an optimized instruction for accessing a Hash using a
non-frozen string key (ie. from a file without frozen_string_literal).
It attempts to avoid allocating the string, and instead silently using a
frozen string (hash string keys are always fstrings).

Because this is just an optimization, it should be invisible to the
user. However, previously this optimization was could be seen via hashes
with default procs.

For example, previously:

    h = Hash.new { |h, k| k.frozen? }
    str = "foo"
    h[str]   # false
    h["foo"] # true when optimizations enabled

This commit checks that the Hash doesn't have a default proc when using
opt_aref_with.
</pre>
</div>
</content>
</entry>
<entry>
<title>Make method id explicit in rb_exec_recursive_outer</title>
<updated>2022-06-10T21:48:21+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2022-06-10T16:43:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=52da90aceefd9f8de06666796f6a2d484ca18036'/>
<id>52da90aceefd9f8de06666796f6a2d484ca18036</id>
<content type='text'>
Previously, because opt_aref and opt_aset don't push a frame, when they
would call rb_hash to determine the hash value of the key, the initial
level of recursion would incorrectly use the method id at the top of the
stack instead of "hash".

This commit replaces rb_exec_recursive_outer with
rb_exec_recursive_outer_mid, which takes an explicit method id, so that
we can make the hash calculation behave consistently.

rb_exec_recursive_outer was documented as being internal, so I believe
this should be okay to change.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously, because opt_aref and opt_aset don't push a frame, when they
would call rb_hash to determine the hash value of the key, the initial
level of recursion would incorrectly use the method id at the top of the
stack instead of "hash".

This commit replaces rb_exec_recursive_outer with
rb_exec_recursive_outer_mid, which takes an explicit method id, so that
we can make the hash calculation behave consistently.

rb_exec_recursive_outer was documented as being internal, so I believe
this should be okay to change.
</pre>
</div>
</content>
</entry>
<entry>
<title>st.c: Do not clear entries_bound when calling Hash#shift for empty hash</title>
<updated>2022-02-09T15:14:27+00:00</updated>
<author>
<name>Yusuke Endoh</name>
<email>mame@ruby-lang.org</email>
</author>
<published>2022-02-09T09:24:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=496591de96b261b8789332c7f8b2bfbd17658955'/>
<id>496591de96b261b8789332c7f8b2bfbd17658955</id>
<content type='text'>
tab-&gt;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-&gt;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-&gt;entries_bound in Hash#shift.
[Bug #18578]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
tab-&gt;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-&gt;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-&gt;entries_bound in Hash#shift.
[Bug #18578]
</pre>
</div>
</content>
</entry>
<entry>
<title>Make Hash#shift return nil for empty hash</title>
<updated>2022-01-14T20:17:57+00:00</updated>
<author>
<name>Jeremy Evans</name>
<email>code@jeremyevans.net</email>
</author>
<published>2021-12-27T22:41:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=a93cc3e23b4044762e80820fc7a45606587e11db'/>
<id>a93cc3e23b4044762e80820fc7a45606587e11db</id>
<content type='text'>
Fixes [Bug #16908]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fixes [Bug #16908]
</pre>
</div>
</content>
</entry>
<entry>
<title>Add documentation and tests for keyword argument value omission</title>
<updated>2021-09-11T11:23:36+00:00</updated>
<author>
<name>Shugo Maeda</name>
<email>shugo@ruby-lang.org</email>
</author>
<published>2021-09-11T11:23:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=297f9b8d4c4502aa2ba0eccf93dfce215a7b6dfe'/>
<id>297f9b8d4c4502aa2ba0eccf93dfce215a7b6dfe</id>
<content type='text'>
[Feature #14579]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Feature #14579]
</pre>
</div>
</content>
</entry>
</feed>
