Skip to content
This repository has been archived by the owner on Sep 11, 2020. It is now read-only.

Commit

Permalink
Merge pull request #1119 from filipnavara/idxfile-reverse-index
Browse files Browse the repository at this point in the history
plumbing: idxfile, avoid unnecessary building of reverse offset/hash map
  • Loading branch information
mcuadros authored Apr 22, 2019
2 parents e5268e9 + 74ae8aa commit 78092a2
Showing 1 changed file with 26 additions and 4 deletions.
30 changes: 26 additions & 4 deletions plumbing/format/idxfile/idxfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand All @@ -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 {
Expand Down

0 comments on commit 78092a2

Please sign in to comment.