package packfile import ( "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/format/idxfile" ) // Index is an in-memory representation of a packfile index. // This uses idxfile.Idxfile under the hood to obtain indexes from .idx files // or to store them. type Index struct { byHash map[plumbing.Hash]*idxfile.Entry byOffset map[uint64]*idxfile.Entry } // NewIndex creates a new empty index with the given size. Size is a hint and // can be 0. It is recommended to set it to the number of objects to be indexed // if it is known beforehand (e.g. reading from a packfile). func NewIndex(size int) *Index { return &Index{ byHash: make(map[plumbing.Hash]*idxfile.Entry, size), byOffset: make(map[uint64]*idxfile.Entry, size), } } // NewIndexFromIdxFile creates a new Index from an idxfile.IdxFile. func NewIndexFromIdxFile(idxf *idxfile.Idxfile) *Index { idx := &Index{ byHash: make(map[plumbing.Hash]*idxfile.Entry, idxf.ObjectCount), byOffset: make(map[uint64]*idxfile.Entry, idxf.ObjectCount), } for _, e := range idxf.Entries { idx.add(e) } return idx } // Add adds a new Entry with the given values to the index. func (idx *Index) Add(h plumbing.Hash, offset uint64, crc32 uint32) { e := idxfile.Entry{ Hash: h, Offset: offset, CRC32: crc32, } idx.add(&e) } func (idx *Index) add(e *idxfile.Entry) { idx.byHash[e.Hash] = e idx.byOffset[e.Offset] = e } // LookupHash looks an entry up by its hash. An idxfile.Entry is returned and // a bool, which is true if it was found or false if it wasn't. func (idx *Index) LookupHash(h plumbing.Hash) (*idxfile.Entry, bool) { e, ok := idx.byHash[h] return e, ok } // LookupHash looks an entry up by its offset in the packfile. An idxfile.Entry // is returned and a bool, which is true if it was found or false if it wasn't. func (idx *Index) LookupOffset(offset uint64) (*idxfile.Entry, bool) { e, ok := idx.byOffset[offset] return e, ok } // Size returns the number of entries in the index. func (idx *Index) Size() int { return len(idx.byHash) } // ToIdxFile converts the index to an idxfile.Idxfile, which can then be used // to serialize. func (idx *Index) ToIdxFile() *idxfile.Idxfile { idxf := idxfile.NewIdxfile() for _, e := range idx.byHash { idxf.Entries = append(idxf.Entries, e) } return idxf }