diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2019-04-22 13:35:45 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-22 13:35:45 +0200 |
commit | 78092a2843dc534d6f5ee2048f608d84c407bf46 (patch) | |
tree | 71fa29bba0c05b9757a92643b75cd3fb035413fb /plumbing | |
parent | e5268e9c3c94f60e3c2008dc2ab4762c75352bfc (diff) | |
parent | 74ae8aab9157e2a661efb3c9beafac626f73672b (diff) | |
download | go-git-78092a2843dc534d6f5ee2048f608d84c407bf46.tar.gz |
Merge pull request #1119 from filipnavara/idxfile-reverse-index
plumbing: idxfile, avoid unnecessary building of reverse offset/hash map
Diffstat (limited to 'plumbing')
-rw-r--r-- | plumbing/format/idxfile/idxfile.go | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/plumbing/format/idxfile/idxfile.go b/plumbing/format/idxfile/idxfile.go index 5fed278..26cca59 100644 --- a/plumbing/format/idxfile/idxfile.go +++ b/plumbing/format/idxfile/idxfile.go @@ -55,7 +55,8 @@ type MemoryIndex struct { PackfileChecksum [20]byte IdxChecksum [20]byte - offsetHash map[int64]plumbing.Hash + offsetHash map[int64]plumbing.Hash + offsetHashIsFull bool } var _ Index = (*MemoryIndex)(nil) @@ -121,7 +122,17 @@ func (idx *MemoryIndex) FindOffset(h plumbing.Hash) (int64, error) { return 0, plumbing.ErrObjectNotFound } - return idx.getOffset(k, i) + offset, err := idx.getOffset(k, i) + + if !idx.offsetHashIsFull { + // Save the offset for reverse lookup + if idx.offsetHash == nil { + idx.offsetHash = make(map[int64]plumbing.Hash) + } + idx.offsetHash[offset] = h + } + + return offset, err } const isO64Mask = uint64(1) << 31 @@ -167,14 +178,24 @@ func (idx *MemoryIndex) getCRC32(firstLevel, secondLevel int) (uint32, error) { // FindHash implements the Index interface. func (idx *MemoryIndex) FindHash(o int64) (plumbing.Hash, error) { + var hash plumbing.Hash + var ok bool + + if idx.offsetHash != nil { + if hash, ok = idx.offsetHash[o]; ok { + return hash, nil + } + } + // Lazily generate the reverse offset/hash map if required. - if idx.offsetHash == nil { + if !idx.offsetHashIsFull || idx.offsetHash == nil { if err := idx.genOffsetHash(); err != nil { return plumbing.ZeroHash, err } + + hash, ok = idx.offsetHash[o] } - hash, ok := idx.offsetHash[o] if !ok { return plumbing.ZeroHash, plumbing.ErrObjectNotFound } @@ -190,6 +211,7 @@ func (idx *MemoryIndex) genOffsetHash() error { } idx.offsetHash = make(map[int64]plumbing.Hash, count) + idx.offsetHashIsFull = true iter, err := idx.Entries() if err != nil { |