| 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
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
# 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
# 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
# File lib/grit/git-ruby/internal/pack.rb, line 97
97: def close
98: # shouldnt be anything open now
99: end
# 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
# 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
# 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
# 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
# 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
# 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
# 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