Class | Grit::GitRuby::Internal::PackStorage |
In: |
lib/grit/git-ruby/internal/pack.rb
|
Parent: | Object |
OBJ_OFS_DELTA | = | 6 |
OBJ_REF_DELTA | = | 7 |
FanOutCount | = | 256 |
SHA1Size | = | 20 |
IdxOffsetSize | = | 4 |
OffsetSize | = | 4 |
CrcSize | = | 4 |
OffsetStart | = | FanOutCount * IdxOffsetSize |
SHA1Start | = | OffsetStart + OffsetSize |
EntrySize | = | OffsetSize + SHA1Size |
EntrySizeV2 | = | SHA1Size + CrcSize + OffsetSize |
# File lib/grit/git-ruby/internal/pack.rb, line 39 def initialize(file) if file =~ /\.idx$/ file = file[0...-3] + 'pack' end @name = file @cache = {} init_pack end
# File lib/grit/git-ruby/internal/pack.rb, line 108 def [](sha1) if obj = @cache[sha1] return obj end offset = find_object(sha1) return nil if !offset @cache[sha1] = obj = parse_object(offset) return obj end
# File lib/grit/git-ruby/internal/pack.rb, line 81 def cache_objects @cache = {} with_packfile do |packfile| each_entry do |sha, offset| data, type = unpack_object(packfile, offset, {:caching => true}) if data @cache[sha] = RawObject.new(OBJ_TYPES[type], data) end end end end
# File lib/grit/git-ruby/internal/pack.rb, line 133 def each_entry with_idx do |idx| if @version == 2 data = read_data_v2(idx) data.each do |sha1, crc, offset| yield sha1, offset end else pos = OffsetStart @size.times do offset = idx[pos,OffsetSize].unpack('N')[0] sha1 = idx[pos+OffsetSize,SHA1Size] pos += EntrySize yield sha1, offset end end end end
# File lib/grit/git-ruby/internal/pack.rb, line 173 def each_sha1 with_idx do |idx| if @version == 2 data = read_data_v2(idx) data.each do |sha1, crc, offset| yield sha1 end else pos = SHA1Start @size.times do sha1 = idx[pos,SHA1Size] pos += EntrySize yield sha1 end end end end
# File lib/grit/git-ruby/internal/pack.rb, line 191 def find_object_in_index(idx, sha1) slot = sha1.getord(0) return nil if !slot first, last = @offsets[slot,2] while first < last mid = (first + last) / 2 if @version == 2 midsha1 = idx[OffsetStart + (mid * SHA1Size), SHA1Size] cmp = midsha1 <=> sha1 if cmp < 0 first = mid + 1 elsif cmp > 0 last = mid else pos = OffsetStart + (@size * (SHA1Size + CrcSize)) + (mid * OffsetSize) offset = idx[pos, OffsetSize].unpack('N')[0] return offset end else midsha1 = idx[SHA1Start + mid * EntrySize,SHA1Size] cmp = midsha1 <=> sha1 if cmp < 0 first = mid + 1 elsif cmp > 0 last = mid else pos = OffsetStart + mid * EntrySize offset = idx[pos,OffsetSize].unpack('N')[0] return offset end end end nil end
given an index file, list out the shas that it‘s packfile contains
# File lib/grit/git-ruby/internal/pack.rb, line 102 def get_shas shas = [] each_sha1 { |sha| shas << sha.unpack("H*")[0] } shas end
# File lib/grit/git-ruby/internal/pack.rb, line 119 def init_pack with_idx do |idx| @offsets = [0] FanOutCount.times do |i| pos = idx[i * IdxOffsetSize,IdxOffsetSize].unpack('N')[0] if pos < @offsets[i] raise PackFormatError, "pack #@name has discontinuous index #{i}" end @offsets << pos end @size = @offsets[-1] end end
# File lib/grit/git-ruby/internal/pack.rb, line 48 def with_idx(index_file = nil) if !index_file index_file = @name idxfile = File.open(@name[0...-4]+'idx', 'rb') else idxfile = File.open(index_file, 'rb') end # read header sig = idxfile.read(4) ver = idxfile.read(4).unpack("N")[0] if sig == PACK_IDX_SIGNATURE if(ver != 2) raise PackFormatError, "pack #@name has unknown pack file version #{ver}" end @version = 2 else @version = 1 end idx = FileWindow.new(idxfile, @version) yield idx idx.unmap idxfile.close end
# File lib/grit/git-ruby/internal/pack.rb, line 75 def with_packfile packfile = File.open(@name, 'rb') yield packfile packfile.close end