Class: Amp::Core::Repositories::Git::PackFileIndex

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

Overview

PackFile

Git uses it’s “gc” command to pack loose objects into PackFiles. This is one file, preferably with an index (though not requiring one), which stores a number of objects in a very simple raw form.

This class handles the index file, which is used for fast lookups of entries in packfiles. They use fanouts to make searching very simple.

The fanout values are interesting - they are the number of entries with a first sha1 byte less than or equal to the byte provided. So if the only sha1s you can find in a given packfile are 00112233.… and 020304.… then the first few fanouts are: fanout = 1 fanout = 1 fanout = 2 .… fanout = 2

Direct Known Subclasses

PackFileIndexV1, PackFileIndexV2

Constant Summary collapse

FANOUT_TABLE_SIZE =
4 * 256

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fp) ⇒ PackFileIndex

Common initialization code

Parameters:

  • fp (IO, #read)

    input stream to read the file from



76
77
78
79
80
# File 'lib/amp-git/repo_format/packfile_index.rb', line 76

def initialize(fp)
  @fp = fp
  @fanout = @fp.read(FANOUT_TABLE_SIZE).unpack("N256")
  @size = @fanout[255]
end

Instance Attribute Details

#fanoutObject (readonly)

Returns the value of attribute fanout.



72
73
74
# File 'lib/amp-git/repo_format/packfile_index.rb', line 72

def fanout
  @fanout
end

#sizeObject (readonly)

Common PackFileIndex methods



71
72
73
# File 'lib/amp-git/repo_format/packfile_index.rb', line 71

def size
  @size
end

Class Method Details

.parse(fp) ⇒ Object

Initializes the index file by reading from an input source. Does not automatically read in any actual data, but instead finds the necessary values to make searching by SHA1 quick.

Parameters:

  • fp (IO, #read)

    an input stream at the beginning of the index



56
57
58
59
60
61
62
63
64
65
# File 'lib/amp-git/repo_format/packfile_index.rb', line 56

def parse(fp)
  fourcc = fp.read(4)
  if fourcc == "\xfftOc"
    version = fp.read(4).unpack("N").first
    PackFileIndexV2.new(fp) if version == 2
  else
    fp.seek(-4, IO::SEEK_CUR)
    PackFileIndexV1.new(fp)
  end
end

Instance Method Details

#search_range_for_hash(hash) ⇒ Object

uses fanout logic to determine the indices in which the desired hash might be found. This range can be searched to find the hash.



85
86
87
88
89
90
# File 'lib/amp-git/repo_format/packfile_index.rb', line 85

def search_range_for_hash(hash)
  byte = Support::HexString.from_bin(hash).ord
  min = byte > 0 ? (fanout[byte - 1]) : 0
  max = fanout[byte]
  min...max
end