class GitObjectBrowser::Models::PackIndex
v2
signature 4bytes version 4bytes fanout 4bytes * 256 sha1 20bytes * fanout[255] crc32 4bytes * fanout[255] offset 4bytes * fanout[255] pack sha1 20bytes index sha1 20bytes
Constants
- PER_PAGE
Attributes
entries[R]
Public Class Methods
new(input)
click to toggle source
Calls superclass method
GitObjectBrowser::Models::Bindata::new
# File lib/git-object-browser/models/pack_index.rb, line 19 def initialize(input) super(input) end
path?(relpath)
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 222 def self.path?(relpath) return relpath =~ %r{\Aobjects/pack/pack-[0-9a-f]{40}\.idx\z} end
Public Instance Methods
empty?()
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 51 def empty? @entries.empty? end
find(sha1_hex)
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 160 def find(sha1_hex) parse_fanout sha1 = [sha1_hex].pack("H*") fanout_idx = sha1.unpack("C").first lo = fanout_idx == 0 ? 0 : @fanout[fanout_idx - 1] hi = @fanout[fanout_idx] while lo < hi mid = (lo + hi) / 2 mid_sha1 = get_sha1_raw(mid) if mid_sha1 == sha1 return { :sha1 => sha1_hex, :crc32 => get_crc32_hex(mid), :offset => get_offset(mid) } elsif sha1 < mid_sha1 hi = mid else lo = mid + 1 end end nil end
get_crc32_hex(pos)
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 204 def get_crc32_hex(pos) if @version == 2 seek(4 + 4 + 4 * 256 + 20 * @fanout[255] + 4 * pos) else raise "FIXME version 1" end hex(4) end
get_offset(pos)
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 213 def get_offset(pos) if @version == 2 seek(4 + 4 + 4 * 256 + 20 * @fanout[255] + 4 * @fanout[255] + 4 * pos) else raise "FIXME version 1" end int end
get_sha1_hex(pos)
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 195 def get_sha1_hex(pos) if @version == 2 seek(4 + 4 + 4 * 256 + 20 * pos) else raise "FIXME version 1" end hex(20) end
get_sha1_raw(pos)
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 186 def get_sha1_raw(pos) if @version == 2 seek(4 + 4 + 4 * 256 + 20 * pos) else raise "FIXME version 1" end raw(20) end
load_object_types(input)
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 244 def load_object_types(input) obj = PackedObject.new(self, input) @entries.each do |entry| header = obj.parse_header(entry[:offset]) if header[:type] == 'ofs_delta' obj.parse_ofs_delta_header(entry[:offset], header) elsif header[:type] == 'ref_delta' obj.parse_ref_delta_header(header) end entry.merge!(header) end end
page_data()
click to toggle source
Extended pagenation data for Git Object Browser.
# File lib/git-object-browser/models/pack_index.rb, line 235 def page_data return { :per_page => PER_PAGE, :entry_count => @fanout[255], :page => @page, :order => @order } end
parse(order, page)
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 23 def parse(order, page) parse_fanout @page = page @order = order if order == 'digest' parse_digest elsif order == 'sha1' parse_sha1_page set_fanouts else @order = 'offset' parse_offset_page set_fanouts end # XXX Doesn't support packfile >= 2 GiB # x.times do |i| # puts "offset[#{ i }] = #{ hex(8) }" # end seek(4 + 4 + 4 * 256 + (20 + 4 + 4) * @fanout[255]) @packfile_sha1 = hex(20) @index_sha1 = hex(20) self end
parse_fanout()
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 143 def parse_fanout return if @fanout seek(0) signature = raw(4) signature_v2 = [255, 'tOc'].pack('Ca*') raise "FIXME" if signature != signature_v2 @version = int raise "FIXME" if @version != 2 @fanout = [] 256.times do |i| @fanout << int end end
to_hash()
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 226 def to_hash return { :entries => @entries, :packfile_sha1 => @packfile_sha1, :index_sha1 => @index_sha1, } end
Private Instance Methods
parse_digest()
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 73 def parse_digest index = 0 @entries = [] while index <= @fanout[255] - 1 @entries << hex(20) index += PER_PAGE skip(20 * (PER_PAGE - 1)) if index <= @fanout[255] - 1 end end
parse_offset_page()
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 114 def parse_offset_page @entries = [] index_start = PER_PAGE * (@page - 1) index_end = PER_PAGE * @page - 1 index_last = @fanout[255] - 1 return if index_last < index_start index_end = index_last if index_last <= index_end entry_count = index_end - index_start + 1 # load all offsets skip((20 + 4) * @fanout[255]) offsets = [] @fanout[255].times do |i| offsets << [i, int] end offsets = offsets.sort { |a,b| a[1] <=> b[1] }[index_start, entry_count] offsets.each do |offset| @entries << { :index => offset[0], :offset => offset[1] } end @entries.each do |entry| entry[:sha1] = get_sha1_hex(entry[:index]) entry[:crc32] = get_crc32_hex(entry[:index]) end end
parse_sha1_page()
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 84 def parse_sha1_page @entries = [] index_start = PER_PAGE * (@page - 1) index_end = PER_PAGE * @page - 1 index_last = @fanout[255] - 1 return if index_last < index_start index_end = index_last if index_last <= index_end entry_count = index_end - index_start + 1 skip(20 * index_start) entry_count.times do |i| entry = { :index => index_start + i, :sha1 => hex(20) } @entries << entry end skip(20 * (index_last - index_end)) skip(4 * index_start) entry_count.times do |i| @entries[i][:crc32] = hex(4) end skip(4 * (index_last - index_end)) skip(4 * index_start) entry_count.times do |i| @entries[i][:offset] = int end end
set_fanouts()
click to toggle source
# File lib/git-object-browser/models/pack_index.rb, line 55 def set_fanouts @fanout.each_with_index do |fo, i| entry = @entries.select { |entry| entry[:index] == fo } next if entry.empty? entry = entry.first entry[:fanout_min] = entry[:fanout_min] ? [entry[:fanout_min], i].min : i entry[:fanout_max] = entry[:fanout_max] ? [entry[:fanout_max], i].max : i end @entries.each do |entry| next unless entry[:fanout_min] entry[:fanout_min] = '%02x' % entry[:fanout_min] entry[:fanout_max] = '%02x' % entry[:fanout_max] entry.delete(:fanout_max) if entry[:fanout_min] == entry[:fanout_max] end end