ref: 1fa0d2bcfa7aebdcec8644f53acc58465c109b72
dir: /commitgraph_read_access.go/
package furgit
import (
"encoding/binary"
"codeberg.org/lindenii/furgit/internal/bloom"
)
const (
commitGraphParentNone = 0x70000000
commitGraphParentExtraMask = 0x80000000
commitGraphParentLastMask = 0x7fffffff
correctedGenerationOverflow = 0x80000000
)
type commitGraphCommit struct {
Position uint32
Tree Hash
Parents []uint32
CommitTime uint64
Generation uint64
Graph *commitGraph
graphLexPos uint32
}
func commitGraphAppendParent(parents []uint32, g *commitGraph, edge uint32) ([]uint32, error) {
if edge == commitGraphParentNone {
return parents, nil
}
if (edge & commitGraphParentExtraMask) == 0 {
return append(parents, edge), nil
}
if g.chunkExtraEdges == nil {
return nil, ErrInvalidObject
}
idx := edge & commitGraphParentLastMask
for {
off := int(idx) * 4
if off+4 > len(g.chunkExtraEdges) {
return nil, ErrInvalidObject
}
val := binary.BigEndian.Uint32(g.chunkExtraEdges[off : off+4])
parents = append(parents, val&commitGraphParentLastMask)
idx++
if (val & commitGraphParentExtraMask) != 0 {
break
}
}
return parents, nil
}
func (cg *commitGraph) CommitPosition(id Hash) (uint32, bool) {
return cg.lookupOID(id)
}
func (cg *commitGraph) CommitAt(pos uint32) (*commitGraphCommit, error) {
return cg.commitDataAt(pos)
}
func (cg *commitGraph) OIDAt(pos uint32) (Hash, error) {
return cg.loadOID(pos)
}
func (c *commitGraphCommit) HasBloom() bool {
return c != nil && c.Graph != nil && c.Graph.chunkBloomIndex != nil && c.Graph.chunkBloomData != nil
}
func (cg *commitGraph) BloomSettings() *bloom.Settings {
if cg == nil {
return nil
}
return cg.bloomSettings
}
func (cg *commitGraph) BloomFilter(pos uint32) (*bloom.Filter, bool) {
g := cg
for g != nil && pos < g.numCommitsInBase {
g = g.base
}
if g == nil || g.chunkBloomIndex == nil || g.chunkBloomData == nil || g.bloomSettings == nil {
return nil, false
}
if pos >= g.numCommits+g.numCommitsInBase {
return nil, false
}
lex := pos - g.numCommitsInBase
if int(lex)*4+4 > len(g.chunkBloomIndex) {
return nil, false
}
end := binary.BigEndian.Uint32(g.chunkBloomIndex[int(lex)*4:])
var start uint32
if lex > 0 {
start = binary.BigEndian.Uint32(g.chunkBloomIndex[int(lex-1)*4:])
}
if end < start {
return nil, false
}
if int(end) > len(g.chunkBloomData)-bloom.DataHeaderSize ||
int(start) > len(g.chunkBloomData)-bloom.DataHeaderSize {
return nil, false
}
data := g.chunkBloomData[bloom.DataHeaderSize+start : bloom.DataHeaderSize+end]
return &bloom.Filter{Data: data, Version: g.bloomSettings.HashVersion}, true
}
func (c *commitGraphCommit) BloomFilter() (*bloom.Filter, *bloom.Settings, bool) {
if c == nil || c.Graph == nil {
return nil, nil, false
}
filter, ok := c.Graph.BloomFilter(c.Position)
if !ok {
return nil, nil, false
}
return filter, c.Graph.bloomSettings, true
}
func (c *commitGraphCommit) ChangedPathMightContain(path []byte) bool {
filter, settings, ok := c.BloomFilter()
if !ok {
return false
}
return filter.MightContain(path, settings)
}