Skip to content

Commit

Permalink
Merge pull request #7484 from rubygems/segiddins/use-a-constant-empty…
Browse files Browse the repository at this point in the history
…-tar-header-to-avoid-extra-allocations

Use a constant empty tar header to avoid extra allocations

(cherry picked from commit 90d0ceb)
  • Loading branch information
deivid-rodriguez committed May 16, 2024
1 parent fc348a8 commit 1b9905c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
24 changes: 20 additions & 4 deletions lib/rubygems/package/tar_header.rb
Original file line number Diff line number Diff line change
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"
end

def oct(num, len)
Expand Down
25 changes: 25 additions & 0 deletions test/rubygems/test_gem_package_tar_header.rb
Original file line number Diff line number Diff line change
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

0 comments on commit 1b9905c

Please sign in to comment.