Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a constant empty tar header to avoid extra allocations #7484

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 20 additions & 4 deletions lib/rubygems/package/tar_header.rb
Expand Up @@ -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

Expand All @@ -123,7 +123,7 @@ def self.from(stream)
devminor: strict_oct(fields.shift),
prefix: fields.shift,

empty: empty
empty: false
end

def self.strict_oct(str)
Expand Down Expand Up @@ -172,6 +172,22 @@ def initialize(vals)
@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?

Expand Down Expand Up @@ -241,7 +257,7 @@ def header(checksum = @checksum)

header = header.pack PACK_FORMAT

header << ("\0" * ((512 - header.size) % 512))
header.ljust 512, "\0"
deivid-rodriguez marked this conversation as resolved.
Show resolved Hide resolved
end

def oct(num, len)
Expand Down
25 changes: 25 additions & 0 deletions test/rubygems/test_gem_package_tar_header.rb
Expand Up @@ -99,6 +99,31 @@ def test_empty_eh
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
Expand Down