Class: Amp::Core::Repositories::Git::PackFileIndexV2

Inherits:
PackFileIndex
  • Object
show all
Defined in:
lib/amp-git/repo_format/packfile_index.rb

Overview

This class is for the older version of index files. They are structured as simply a fanout table and a list of [offset] entries. There’s a checksum at the bottom for verification.

Initialization only reads in the fanout table, and the file is left open.

Constant Summary collapse

ENTRY_TABLE_START =
256 * 4 + 8
SHA1_FORMAT =
"a20"
SHA1_SIZE =
20

Constants inherited from PackFileIndex

Amp::Core::Repositories::Git::PackFileIndex::FANOUT_TABLE_SIZE

Instance Attribute Summary

Attributes inherited from PackFileIndex

#fanout, #size

Instance Method Summary collapse

Methods inherited from PackFileIndex

#initialize, parse, #search_range_for_hash

Constructor Details

This class inherits a constructor from Amp::Core::Repositories::Git::PackFileIndex

Instance Method Details

#big_offset_table_offsetObject



147
148
149
# File 'lib/amp-git/repo_format/packfile_index.rb', line 147

def big_offset_table_offset
  offset_table_offset + size * 4
end

#crc_table_offsetObject



139
140
141
# File 'lib/amp-git/repo_format/packfile_index.rb', line 139

def crc_table_offset
  ENTRY_TABLE_START + size * SHA1_SIZE
end

#offset_for_hash(hsh) ⇒ Fixnum?

Looks up the offset in a packfile of a given hash. nil is returned if the sha1 isn’t found.

Parameters:

  • hsh (String)

    a binary, sha-1 hash of the desired object

Returns:

  • (Fixnum, nil)

    the offset into the corresponding packfile at which you can find the object

Raises:



158
159
160
161
162
163
164
165
166
167
168
# File 'lib/amp-git/repo_format/packfile_index.rb', line 158

def offset_for_hash(hsh)
  range = search_range_for_hash hsh
  @fp.seek(sha1_table_offset + range.begin * SHA1_SIZE, IO::SEEK_SET)
  # linear search for now.
  # TODO: binary search!
  range.each do |idx|
    sha1 = @fp.read(SHA1_SIZE).unpack(SHA1_FORMAT).first # sha1s are 20 bytes
    return offset_for_index(idx) if sha1 == hsh.to_bin
  end
  raise PackFileIndexLookupError.new("Couldn't find the hash #{hsh.inspect} in the packfile index.")
end

#offset_for_index(idx) ⇒ Integer

Looks up the offset of an object given its index in the file. This index is assumed to have been determined by matching the sha1 of the object to a sha1 in the SHA1 table of the index.

This requires a little more advanced logic because there is an offset table, and a 64-bit offset table. The normal offset table only supports 31-bit offsets, if the high bit is set, then the 31-bit value is actually an index into the big offset table.

Parameters:

  • idx (Integer)

    the index into the offset table

Returns:

  • (Integer)

    the offset in the packfile where you can find the object with the given index into the index



183
184
185
186
187
188
189
190
191
# File 'lib/amp-git/repo_format/packfile_index.rb', line 183

def offset_for_index(idx)
  @fp.seek(offset_table_offset + 4 * idx, IO::SEEK_SET)
  offset = @fp.read(4).unpack("N").first
  if offset & 0x80000000 != 0
    @fp.seek(big_offset_table_offset + 8 * (offset & 0x7fffffff))
    offset = Support::EncodingUtils.network_to_host_64(@fp.read(8).unpack("Q").first)
  end
  offset
end

#offset_table_offsetObject



143
144
145
# File 'lib/amp-git/repo_format/packfile_index.rb', line 143

def offset_table_offset
  crc_table_offset + size * 4
end

#sha1_table_offsetObject



135
136
137
# File 'lib/amp-git/repo_format/packfile_index.rb', line 135

def sha1_table_offset
  ENTRY_TABLE_START
end