aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/format/packfile/index.go
diff options
context:
space:
mode:
Diffstat (limited to 'plumbing/format/packfile/index.go')
-rw-r--r--plumbing/format/packfile/index.go82
1 files changed, 82 insertions, 0 deletions
diff --git a/plumbing/format/packfile/index.go b/plumbing/format/packfile/index.go
new file mode 100644
index 0000000..2c5f98f
--- /dev/null
+++ b/plumbing/format/packfile/index.go
@@ -0,0 +1,82 @@
+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
+}