aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/format/idxfile/idxfile.go
blob: b39295a9a7ff000cd93e8bd95865a5cf2028a1ba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package idxfile

import "srcd.works/go-git.v4/plumbing"

const (
	// VersionSupported is the only idx version supported.
	VersionSupported = 2
)

var (
	idxHeader = []byte{255, 't', 'O', 'c'}
)

// Idxfile is the in memory representation of an idx file.
type Idxfile struct {
	Version          uint32
	Fanout           [255]uint32
	ObjectCount      uint32
	Entries          EntryList
	PackfileChecksum [20]byte
	IdxChecksum      [20]byte
}

// Entry is the in memory representation of an object entry in the idx file.
type Entry struct {
	Hash   plumbing.Hash
	CRC32  uint32
	Offset uint64
}

// Add adds a new Entry with the given values to the Idxfile.
func (idx *Idxfile) Add(h plumbing.Hash, offset uint64, crc32 uint32) {
	idx.Entries = append(idx.Entries, Entry{
		Hash:   h,
		Offset: offset,
		CRC32:  crc32,
	})
}

func (idx *Idxfile) isValid() bool {
	fanout := idx.calculateFanout()
	for k, c := range idx.Fanout {
		if fanout[k] != c {
			return false
		}
	}

	return true
}

func (idx *Idxfile) calculateFanout() [256]uint32 {
	fanout := [256]uint32{}
	for _, e := range idx.Entries {
		fanout[e.Hash[0]]++
	}

	for i := 1; i < 256; i++ {
		fanout[i] += fanout[i-1]
	}

	return fanout
}