Class Grit::GitRuby::Internal::PackStorage
In: lib/grit/git-ruby/internal/pack.rb
Parent: Object

Methods

Constants

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

Public Class methods

[Source]

# 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

Public Instance methods

[Source]

# 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

[Source]

# 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

[Source]

# File lib/grit/git-ruby/internal/pack.rb, line 97
        def close
          # shouldnt be anything open now
        end

[Source]

# 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

[Source]

# 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

[Source]

# 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

[Source]

# File lib/grit/git-ruby/internal/pack.rb, line 102
        def get_shas
          shas = []
          each_sha1 { |sha| shas << sha.unpack("H*")[0] }
          shas
        end

[Source]

# 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

[Source]

# File lib/grit/git-ruby/internal/pack.rb, line 93
        def name
          @name
        end

[Source]

# 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

[Source]

# File lib/grit/git-ruby/internal/pack.rb, line 75
        def with_packfile
          packfile = File.open(@name, 'rb')
          yield packfile
          packfile.close
        end

Protected Instance methods

[Source]

# File lib/grit/git-ruby/internal/pack.rb, line 237
        def parse_object(offset)
          obj = nil
          with_packfile do |packfile|
            data, type = unpack_object(packfile, offset)
            obj = RawObject.new(OBJ_TYPES[type], data)
          end
          obj
        end

[Validate]