Skip to content

Commit

Permalink
Do not pre-freeze string keys if Ruby will dedup them
Browse files Browse the repository at this point in the history
  • Loading branch information
byroot committed Sep 7, 2020
1 parent b90ab6f commit e8dedef
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 0 deletions.
12 changes: 12 additions & 0 deletions ext/msgpack/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@
$CFLAGS << %[ -DDISABLE_RMEM]
end

# checking if Hash#[]= (rb_hash_aset) dedupes string keys
h = {}
x = {}
r = rand.to_s
h[%W(#{r}).join('')] = :foo
x[%W(#{r}).join('')] = :foo
if x.keys[0].equal?(h.keys[0])
$CFLAGS << ' -DHASH_ASET_DEDUPE=1 '
else
$CFLAGS << ' -DHASH_ASET_DEDUPE=0 '
end

if warnflags = CONFIG['warnflags']
warnflags.slice!(/ -Wdeclaration-after-statement/)
end
Expand Down
3 changes: 3 additions & 0 deletions ext/msgpack/unpacker.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,12 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
} else {
ret = object_complete_ext(uk, raw_type, string);
}

# if !HASH_ASET_DEDUPE
if(will_freeze) {
rb_obj_freeze(string);
}
# endif
uk->reading_raw_remaining = 0;
return ret;
}
Expand Down
11 changes: 11 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ def java?
/java/ =~ RUBY_PLATFORM
end

# checking if Hash#[]= (rb_hash_aset) dedupes string keys
def automatic_string_keys_deduplication?
h = {}
x = {}
r = rand.to_s
h[%W(#{r}).join('')] = :foo
x[%W(#{r}).join('')] = :foo

x.keys[0].equal?(h.keys[0])
end

if java?
RSpec.configure do |c|
c.treat_symbols_as_metadata_keys_with_true_values = true
Expand Down
11 changes: 11 additions & 0 deletions spec/unpacker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@
u2.allow_unknown_ext?.should == true
end

if automatic_string_keys_deduplication?
it 'ensure string hash keys are deduplicated' do
sample_data = [{"foo" => 1}, {"foo" => 2}]
sample_packed = MessagePack.pack(sample_data).force_encoding('ASCII-8BIT')
unpacker.feed(sample_packed)
hashes = nil
unpacker.each { |obj| hashes = obj }
expect(hashes[0].keys.first).to equal(hashes[1].keys.first)
end
end

it 'gets IO or object which has #read to read data from it' do
sample_data = {"message" => "morning!", "num" => 1}
sample_packed = MessagePack.pack(sample_data).force_encoding('ASCII-8BIT')
Expand Down

0 comments on commit e8dedef

Please sign in to comment.