Merge pull request #1985 from dolthub/aaron/optimize-commitwalk

go/libraries/doltcore/env/actions/commitwalk: Optimize commitwalk a bit.
This commit is contained in:
AndyA
2021-08-06 16:45:50 -07:00
committed by GitHub
2 changed files with 50 additions and 23 deletions

View File

@@ -151,11 +151,27 @@ func (c *Commit) NumParents() (int, error) {
}
func (c *Commit) Height() (uint64, error) {
ref, err := types.NewRef(c.commitSt, c.vrw.Format())
maxHeight, err := maxChunkHeight(c.commitSt, c.vrw.Format())
if err != nil {
return 0, err
}
return ref.Height(), nil
return maxHeight + 1, nil
}
func maxChunkHeight(v types.Value, nbf *types.NomsBinFormat) (max uint64, err error) {
err = v.WalkRefs(nbf, func(r types.Ref) error {
if height := r.Height(); height > max {
max = height
}
return nil
})
if err != nil {
return 0, err
}
return max, nil
}
func (c *Commit) getParent(ctx context.Context, idx int) (*types.Struct, error) {

View File

@@ -15,6 +15,7 @@
package commitwalk
import (
"container/heap"
"context"
"io"
@@ -42,9 +43,37 @@ func (q *q) NumVisiblePending() int {
return q.numVisiblePending
}
func (q *q) Push(x interface{}) {
q.pending = append(q.pending, x.(*c))
}
func (q *q) Pop() interface{} {
old := q.pending
ret := old[len(old)-1]
q.pending = old[:len(old)-1]
return ret
}
func (q *q) Len() int {
return len(q.pending)
}
func (q *q) Swap(i, j int) {
q.pending[i], q.pending[j] = q.pending[j], q.pending[i]
}
func (q *q) Less(i, j int) bool {
if q.pending[i].height > q.pending[j].height {
return true
}
if q.pending[i].height == q.pending[j].height {
return q.pending[i].meta.UserTimestamp > q.pending[j].meta.UserTimestamp
}
return false
}
func (q *q) PopPending() *c {
c := q.pending[len(q.pending)-1]
q.pending = q.pending[:len(q.pending)-1]
c := heap.Pop(q).(*c)
if !c.invisible {
q.numVisiblePending--
}
@@ -58,25 +87,7 @@ func (q *q) AddPendingIfUnseen(ctx context.Context, ddb *doltdb.DoltDB, id hash.
}
if !c.queued {
c.queued = true
var i int
for i = 0; i < len(q.pending); i++ {
if q.pending[i].height > c.height {
break
}
if q.pending[i].height < c.height {
continue
}
// if the commits have equal height, tiebreak on timestamp
pendingMeta := q.pending[i].meta
commitMeta := c.meta
if pendingMeta.UserTimestamp > commitMeta.UserTimestamp {
break
}
}
q.pending = append(q.pending, nil)
copy(q.pending[i+1:], q.pending[i:])
q.pending[i] = c
heap.Push(q, c)
if !c.invisible {
q.numVisiblePending++
}