@@ -55,7 +55,8 @@ type MemoryIndex struct {
55
55
PackfileChecksum [20 ]byte
56
56
IdxChecksum [20 ]byte
57
57
58
- offsetHash map [int64 ]plumbing.Hash
58
+ offsetHash map [int64 ]plumbing.Hash
59
+ offsetHashIsFull bool
59
60
}
60
61
61
62
var _ Index = (* MemoryIndex )(nil )
@@ -121,7 +122,17 @@ func (idx *MemoryIndex) FindOffset(h plumbing.Hash) (int64, error) {
121
122
return 0 , plumbing .ErrObjectNotFound
122
123
}
123
124
124
- return idx .getOffset (k , i )
125
+ offset , err := idx .getOffset (k , i )
126
+
127
+ if ! idx .offsetHashIsFull {
128
+ // Save the offset for reverse lookup
129
+ if idx .offsetHash == nil {
130
+ idx .offsetHash = make (map [int64 ]plumbing.Hash )
131
+ }
132
+ idx .offsetHash [offset ] = h
133
+ }
134
+
135
+ return offset , err
125
136
}
126
137
127
138
const isO64Mask = uint64 (1 ) << 31
@@ -167,14 +178,24 @@ func (idx *MemoryIndex) getCRC32(firstLevel, secondLevel int) (uint32, error) {
167
178
168
179
// FindHash implements the Index interface.
169
180
func (idx * MemoryIndex ) FindHash (o int64 ) (plumbing.Hash , error ) {
181
+ var hash plumbing.Hash
182
+ var ok bool
183
+
184
+ if idx .offsetHash != nil {
185
+ if hash , ok = idx .offsetHash [o ]; ok {
186
+ return hash , nil
187
+ }
188
+ }
189
+
170
190
// Lazily generate the reverse offset/hash map if required.
171
- if idx .offsetHash == nil {
191
+ if ! idx . offsetHashIsFull || idx .offsetHash == nil {
172
192
if err := idx .genOffsetHash (); err != nil {
173
193
return plumbing .ZeroHash , err
174
194
}
195
+
196
+ hash , ok = idx .offsetHash [o ]
175
197
}
176
198
177
- hash , ok := idx .offsetHash [o ]
178
199
if ! ok {
179
200
return plumbing .ZeroHash , plumbing .ErrObjectNotFound
180
201
}
@@ -190,6 +211,7 @@ func (idx *MemoryIndex) genOffsetHash() error {
190
211
}
191
212
192
213
idx .offsetHash = make (map [int64 ]plumbing.Hash , count )
214
+ idx .offsetHashIsFull = true
193
215
194
216
iter , err := idx .Entries ()
195
217
if err != nil {
0 commit comments