diff --git a/go/libraries/doltcore/doltdb/commit.go b/go/libraries/doltcore/doltdb/commit.go index c5f7274771..086c048511 100644 --- a/go/libraries/doltcore/doltdb/commit.go +++ b/go/libraries/doltcore/doltdb/commit.go @@ -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) { diff --git a/go/libraries/doltcore/env/actions/commitwalk/commitwalk.go b/go/libraries/doltcore/env/actions/commitwalk/commitwalk.go index b09a427a52..2d90369e55 100644 --- a/go/libraries/doltcore/env/actions/commitwalk/commitwalk.go +++ b/go/libraries/doltcore/env/actions/commitwalk/commitwalk.go @@ -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++ }