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
39:         def initialize(file)
40:           if file =~ /\.idx$/
41:             file = file[0...-3] + 'pack'
42:           end
43:           @name = file
44:           @cache = {}
45:           init_pack
46:         end

Public Instance methods

[Source]

     # File lib/grit/git-ruby/internal/pack.rb, line 108
108:         def [](sha1)
109:           if obj = @cache[sha1]
110:             return obj 
111:           end
112:           
113:           offset = find_object(sha1)
114:           return nil if !offset
115:           @cache[sha1] = obj = parse_object(offset)
116:           return obj
117:         end

[Source]

    # File lib/grit/git-ruby/internal/pack.rb, line 81
81:         def cache_objects
82:           @cache = {}
83:           with_packfile do |packfile|          
84:             each_entry do |sha, offset|
85:               data, type = unpack_object(packfile, offset, {:caching => true})
86:               if data
87:                 @cache[sha] = RawObject.new(OBJ_TYPES[type], data)
88:               end
89:             end
90:           end
91:         end

[Source]

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

[Source]

     # File lib/grit/git-ruby/internal/pack.rb, line 133
133:         def each_entry
134:           with_idx do |idx|
135:             if @version == 2
136:               data = read_data_v2(idx)
137:               data.each do |sha1, crc, offset|
138:                 yield sha1, offset
139:               end
140:             else
141:               pos = OffsetStart
142:               @size.times do
143:                 offset = idx[pos,OffsetSize].unpack('N')[0]
144:                 sha1 = idx[pos+OffsetSize,SHA1Size]
145:                 pos += EntrySize
146:                 yield sha1, offset
147:               end
148:             end
149:           end
150:         end

[Source]

     # File lib/grit/git-ruby/internal/pack.rb, line 173
173:         def each_sha1
174:           with_idx do |idx|
175:             if @version == 2
176:               data = read_data_v2(idx)
177:               data.each do |sha1, crc, offset|
178:                 yield sha1
179:               end
180:             else
181:               pos = SHA1Start
182:               @size.times do
183:                 sha1 = idx[pos,SHA1Size]
184:                 pos += EntrySize
185:                 yield sha1
186:               end
187:             end
188:           end
189:         end

[Source]

     # File lib/grit/git-ruby/internal/pack.rb, line 191
191:         def find_object_in_index(idx, sha1)
192:           slot = sha1.getord(0)
193:           return nil if !slot
194:           first, last = @offsets[slot,2] 
195:           while first < last
196:             mid = (first + last) / 2
197:             if @version == 2
198:               midsha1 = idx[OffsetStart + (mid * SHA1Size), SHA1Size]
199:               cmp = midsha1 <=> sha1
200: 
201:               if cmp < 0
202:                 first = mid + 1
203:               elsif cmp > 0
204:                 last = mid
205:               else
206:                 pos = OffsetStart + (@size * (SHA1Size + CrcSize)) + (mid * OffsetSize)
207:                 offset = idx[pos, OffsetSize].unpack('N')[0]
208:                 return offset
209:               end
210:             else
211:               midsha1 = idx[SHA1Start + mid * EntrySize,SHA1Size]
212:               cmp = midsha1 <=> sha1
213: 
214:               if cmp < 0
215:                 first = mid + 1
216:               elsif cmp > 0
217:                 last = mid
218:               else
219:                 pos = OffsetStart + mid * EntrySize
220:                 offset = idx[pos,OffsetSize].unpack('N')[0]
221:                 return offset
222:               end
223:             end
224:           end
225:           nil
226:         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
102:         def get_shas
103:           shas = []
104:           each_sha1 { |sha| shas << sha.unpack("H*")[0] }
105:           shas
106:         end

[Source]

     # File lib/grit/git-ruby/internal/pack.rb, line 119
119:         def init_pack
120:           with_idx do |idx|
121:             @offsets = [0]
122:             FanOutCount.times do |i|
123:               pos = idx[i * IdxOffsetSize,IdxOffsetSize].unpack('N')[0]
124:               if pos < @offsets[i]
125:                 raise PackFormatError, "pack #@name has discontinuous index #{i}"
126:               end
127:               @offsets << pos
128:             end
129:             @size = @offsets[-1]
130:           end
131:         end

[Source]

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

[Source]

    # File lib/grit/git-ruby/internal/pack.rb, line 48
48:         def with_idx(index_file = nil)
49:           if !index_file
50:             index_file = @name
51:             idxfile = File.open(@name[0...-4]+'idx', 'rb')
52:           else
53:             idxfile = File.open(index_file, 'rb')
54:           end
55:           
56:           # read header
57:           sig = idxfile.read(4)
58:           ver = idxfile.read(4).unpack("N")[0]
59:           
60:           if sig == PACK_IDX_SIGNATURE
61:             if(ver != 2)
62:               raise PackFormatError, "pack #@name has unknown pack file version #{ver}"
63:             end            
64:             @version = 2
65:           else
66:             @version = 1
67:           end
68:                     
69:           idx = FileWindow.new(idxfile, @version)
70:           yield idx
71:           idx.unmap
72:           idxfile.close
73:         end

[Source]

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

Protected Instance methods

[Source]

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

[Validate]