[rubygems/rubygems] Use a constant empty tar header to avoid extra allocations

https://github.com/rubygems/rubygems/commit/716666f65f
This commit is contained in:
Samuel Giddins 2024-02-20 11:05:30 -08:00 committed by git
parent 5880103450
commit 02c8e6583b
2 changed files with 45 additions and 4 deletions

View File

@ -95,14 +95,14 @@ class Gem::Package::TarHeader
attr_reader(*FIELDS)
EMPTY_HEADER = ("\0" * 512).freeze # :nodoc:
EMPTY_HEADER = ("\0" * 512).b.freeze # :nodoc:
##
# Creates a tar header from IO +stream+
def self.from(stream)
header = stream.read 512
empty = (header == EMPTY_HEADER)
return EMPTY if header == EMPTY_HEADER
fields = header.unpack UNPACK_FORMAT
@ -123,7 +123,7 @@ class Gem::Package::TarHeader
devminor: strict_oct(fields.shift),
prefix: fields.shift,
empty: empty
empty: false
end
def self.strict_oct(str)
@ -172,6 +172,22 @@ class Gem::Package::TarHeader
@empty = vals[:empty]
end
EMPTY = new({ # :nodoc:
checksum: 0,
gname: "",
linkname: "",
magic: "",
mode: 0,
name: "",
prefix: "",
size: 0,
uname: "",
version: 0,
empty: true,
}).freeze
private_constant :EMPTY
##
# Is the tar entry empty?
@ -241,7 +257,7 @@ class Gem::Package::TarHeader
header = header.pack PACK_FORMAT
header << ("\0" * ((512 - header.size) % 512))
header.ljust 512, "\0"
end
def oct(num, len)

View File

@ -99,6 +99,31 @@ class TestGemPackageTarHeader < Gem::Package::TarTestCase
assert_empty @tar_header
end
def test_empty
@tar_header = Gem::Package::TarHeader.from(StringIO.new(Gem::Package::TarHeader::EMPTY_HEADER))
assert_empty @tar_header
assert_equal Gem::Package::TarHeader.new(
checksum: 0,
devmajor: 0,
devminor: 0,
empty: true,
gid: 0,
gname: "",
linkname: "",
magic: "",
mode: 0,
mtime: 0,
name: "",
prefix: "",
size: 0,
typeflag: "0",
uid: 0,
uname: "",
version: 0,
), @tar_header
end
def test_equals2
assert_equal @tar_header, @tar_header
assert_equal @tar_header, @tar_header.dup