@@ -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,6 +178,12 @@ 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
+ if ! idx .offsetHashIsFull && idx .offsetHash != nil {
182
+ if hash , ok := idx .offsetHash [o ]; ok {
183
+ return hash , nil
184
+ }
185
+ }
186
+
170
187
// Lazily generate the reverse offset/hash map if required.
171
188
if idx .offsetHash == nil {
172
189
if err := idx .genOffsetHash (); err != nil {
@@ -190,6 +207,7 @@ func (idx *MemoryIndex) genOffsetHash() error {
190
207
}
191
208
192
209
idx .offsetHash = make (map [int64 ]plumbing.Hash , count )
210
+ idx .offsetHashIsFull = true
193
211
194
212
iter , err := idx .Entries ()
195
213
if err != nil {
0 commit comments