Rename dolt diff --summary to dolt diff --stat, remove some unused code

This commit is contained in:
Taylor Bantle
2023-02-22 13:41:46 -08:00
parent 203191e4ae
commit be862d796c
9 changed files with 74 additions and 412 deletions
+18 -18
View File
@@ -46,7 +46,7 @@ type diffMode int
const (
SchemaOnlyDiff diffPart = 1 // 0b0001
DataOnlyDiff diffPart = 2 // 0b0010
Summary diffPart = 4 // 0b0100
Stat diffPart = 4 // 0b0100
SchemaAndDataDiff = SchemaOnlyDiff | DataOnlyDiff
@@ -54,16 +54,16 @@ const (
SQLDiffOutput diffOutput = 2
JsonDiffOutput diffOutput = 3
DataFlag = "data"
SchemaFlag = "schema"
SummaryFlag = "summary"
whereParam = "where"
limitParam = "limit"
SQLFlag = "sql"
CachedFlag = "cached"
SkinnyFlag = "skinny"
MergeBase = "merge-base"
DiffMode = "diff-mode"
DataFlag = "data"
SchemaFlag = "schema"
StatFlag = "stat"
whereParam = "where"
limitParam = "limit"
SQLFlag = "sql"
CachedFlag = "cached"
SkinnyFlag = "skinny"
MergeBase = "merge-base"
DiffMode = "diff-mode"
)
var diffDocs = cli.CommandDocumentationContent{
@@ -138,7 +138,7 @@ func (cmd DiffCmd) ArgParser() *argparser.ArgParser {
ap := argparser.NewArgParser()
ap.SupportsFlag(DataFlag, "d", "Show only the data changes, do not show the schema changes (Both shown by default).")
ap.SupportsFlag(SchemaFlag, "s", "Show only the schema changes, do not show the data changes (Both shown by default).")
ap.SupportsFlag(SummaryFlag, "", "Show summary of data changes")
ap.SupportsFlag(StatFlag, "", "Show stats of data changes")
ap.SupportsString(FormatFlag, "r", "result output format", "How to format diff output. Valid values are tabular, sql, json. Defaults to tabular.")
ap.SupportsString(whereParam, "", "column", "filters columns based on values in the diff. See {{.EmphasisLeft}}dolt diff --help{{.EmphasisRight}} for details.")
ap.SupportsInt(limitParam, "", "record_count", "limits to the first N diffs.")
@@ -173,9 +173,9 @@ func (cmd DiffCmd) Exec(ctx context.Context, commandStr string, args []string, d
}
func (cmd DiffCmd) validateArgs(apr *argparser.ArgParseResults) errhand.VerboseError {
if apr.Contains(SummaryFlag) {
if apr.Contains(StatFlag) {
if apr.Contains(SchemaFlag) || apr.Contains(DataFlag) {
return errhand.BuildDError("invalid Arguments: --summary cannot be combined with --schema or --data").Build()
return errhand.BuildDError("invalid Arguments: --stat cannot be combined with --schema or --data").Build()
}
}
@@ -197,8 +197,8 @@ func parseDiffArgs(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgPar
dArgs.diffParts = DataOnlyDiff
} else if apr.Contains(SchemaFlag) && !apr.Contains(DataFlag) {
dArgs.diffParts = SchemaOnlyDiff
} else if apr.Contains(SummaryFlag) {
dArgs.diffParts = Summary
} else if apr.Contains(StatFlag) {
dArgs.diffParts = Stat
}
dArgs.skinny = apr.Contains(SkinnyFlag)
@@ -532,8 +532,8 @@ func diffUserTable(
return errhand.BuildDError("cannot retrieve schema for table %s", td.ToName).AddCause(err).Build()
}
if dArgs.diffParts&Summary != 0 {
return printDiffSummary(ctx, td, fromSch.GetAllCols().Size(), toSch.GetAllCols().Size())
if dArgs.diffParts&Stat != 0 {
return printDiffStat(ctx, td, fromSch.GetAllCols().Size(), toSch.GetAllCols().Size())
}
if dArgs.diffParts&SchemaOnlyDiff != 0 {
+8 -8
View File
@@ -65,18 +65,18 @@ func newDiffWriter(diffOutput diffOutput) (diffWriter, error) {
}
}
func printDiffSummary(ctx context.Context, td diff.TableDelta, oldColLen, newColLen int) errhand.VerboseError {
func printDiffStat(ctx context.Context, td diff.TableDelta, oldColLen, newColLen int) errhand.VerboseError {
// todo: use errgroup.Group
ae := atomicerr.New()
ch := make(chan diff.DiffSummaryProgress)
ch := make(chan diff.DiffStatProgress)
go func() {
defer close(ch)
err := diff.SummaryForTableDelta(ctx, ch, td)
err := diff.StatForTableDelta(ctx, ch, td)
ae.SetIfError(err)
}()
acc := diff.DiffSummaryProgress{}
acc := diff.DiffStatProgress{}
var count int64
var pos int
eP := cli.NewEphemeralPrinter()
@@ -119,15 +119,15 @@ func printDiffSummary(ctx context.Context, td diff.TableDelta, oldColLen, newCol
}
if keyless {
printKeylessSummary(acc)
printKeylessStat(acc)
} else {
printSummary(acc, oldColLen, newColLen)
printStat(acc, oldColLen, newColLen)
}
return nil
}
func printSummary(acc diff.DiffSummaryProgress, oldColLen, newColLen int) {
func printStat(acc diff.DiffStatProgress, oldColLen, newColLen int) {
numCellInserts, numCellDeletes := sqle.GetCellsAddedAndDeleted(acc, newColLen)
rowsUnmodified := uint64(acc.OldRowSize - acc.Changes - acc.Removes)
unmodified := pluralize("Row Unmodified", "Rows Unmodified", rowsUnmodified)
@@ -161,7 +161,7 @@ func printSummary(acc diff.DiffSummaryProgress, oldColLen, newColLen int) {
cli.Printf("(%s vs %s)\n\n", oldValues, newValues)
}
func printKeylessSummary(acc diff.DiffSummaryProgress) {
func printKeylessStat(acc diff.DiffStatProgress) {
insertions := pluralize("Row Added", "Rows Added", acc.Adds)
deletions := pluralize("Row Deleted", "Rows Deleted", acc.Removes)
@@ -34,16 +34,16 @@ import (
var ErrPrimaryKeySetChanged = errors.New("primary key set changed")
type DiffSummaryProgress struct {
type DiffStatProgress struct {
Adds, Removes, Changes, CellChanges, NewRowSize, OldRowSize, NewCellSize, OldCellSize uint64
}
type prollyReporter func(ctx context.Context, vMapping val.OrdinalMapping, fromD, toD val.TupleDesc, change tree.Diff, ch chan<- DiffSummaryProgress) error
type nomsReporter func(ctx context.Context, change *diff.Difference, fromSch, toSch schema.Schema, ch chan<- DiffSummaryProgress) error
type prollyReporter func(ctx context.Context, vMapping val.OrdinalMapping, fromD, toD val.TupleDesc, change tree.Diff, ch chan<- DiffStatProgress) error
type nomsReporter func(ctx context.Context, change *diff.Difference, fromSch, toSch schema.Schema, ch chan<- DiffStatProgress) error
// Summary reports a summary of diff changes between two values
// Stat reports a stat of diff changes between two values
// todo: make package private once dolthub is migrated
func Summary(ctx context.Context, ch chan DiffSummaryProgress, from, to durable.Index, fromSch, toSch schema.Schema) (err error) {
func Stat(ctx context.Context, ch chan DiffStatProgress, from, to durable.Index, fromSch, toSch schema.Schema) (err error) {
fc, err := from.Count()
if err != nil {
return err
@@ -52,7 +52,7 @@ func Summary(ctx context.Context, ch chan DiffSummaryProgress, from, to durable.
if err != nil {
return err
}
ch <- DiffSummaryProgress{OldRowSize: fc, NewRowSize: tc}
ch <- DiffStatProgress{OldRowSize: fc, NewRowSize: tc}
fk, tk := schema.IsKeyless(fromSch), schema.IsKeyless(toSch)
var keyless bool
@@ -69,15 +69,15 @@ func Summary(ctx context.Context, ch chan DiffSummaryProgress, from, to durable.
return diffNomsMaps(ctx, ch, keyless, from, to, fromSch, toSch)
}
// SummaryForTableDelta pushes diff summary progress messages for the table delta given to the channel given
func SummaryForTableDelta(ctx context.Context, ch chan DiffSummaryProgress, td TableDelta) error {
// StatForTableDelta pushes diff stat progress messages for the table delta given to the channel given
func StatForTableDelta(ctx context.Context, ch chan DiffStatProgress, td TableDelta) error {
fromSch, toSch, err := td.GetSchemas(ctx)
if err != nil {
return errhand.BuildDError("cannot retrieve schema for table %s", td.ToName).AddCause(err).Build()
}
if !schema.ArePrimaryKeySetsDiffable(td.Format(), fromSch, toSch) {
return fmt.Errorf("failed to compute diff summary for table %s: %w", td.CurName(), ErrPrimaryKeySetChanged)
return fmt.Errorf("failed to compute diff stat for table %s: %w", td.CurName(), ErrPrimaryKeySetChanged)
}
keyless, err := td.IsKeyless(ctx)
@@ -97,7 +97,7 @@ func SummaryForTableDelta(ctx context.Context, ch chan DiffSummaryProgress, td T
}
}
func diffProllyTrees(ctx context.Context, ch chan DiffSummaryProgress, keyless bool, from, to durable.Index, fromSch, toSch schema.Schema) error {
func diffProllyTrees(ctx context.Context, ch chan DiffStatProgress, keyless bool, from, to durable.Index, fromSch, toSch schema.Schema) error {
_, vMapping, err := schema.MapSchemaBasedOnTagAndName(fromSch, toSch)
if err != nil {
return err
@@ -123,7 +123,7 @@ func diffProllyTrees(ctx context.Context, ch chan DiffSummaryProgress, keyless b
}
ctc := uint64(len(toSch.GetAllCols().GetColumns())) * tc
rpr = reportPkChanges
ch <- DiffSummaryProgress{
ch <- DiffStatProgress{
OldRowSize: fc,
NewRowSize: tc,
OldCellSize: cfc,
@@ -140,7 +140,7 @@ func diffProllyTrees(ctx context.Context, ch chan DiffSummaryProgress, keyless b
return nil
}
func diffNomsMaps(ctx context.Context, ch chan DiffSummaryProgress, keyless bool, fromRows durable.Index, toRows durable.Index, fromSch, toSch schema.Schema) error {
func diffNomsMaps(ctx context.Context, ch chan DiffStatProgress, keyless bool, fromRows durable.Index, toRows durable.Index, fromSch, toSch schema.Schema) error {
var rpr nomsReporter
if keyless {
rpr = reportNomsKeylessChanges
@@ -156,7 +156,7 @@ func diffNomsMaps(ctx context.Context, ch chan DiffSummaryProgress, keyless bool
}
ctc := uint64(len(toSch.GetAllCols().GetColumns())) * tc
rpr = reportNomsPkChanges
ch <- DiffSummaryProgress{
ch <- DiffStatProgress{
OldRowSize: fc,
NewRowSize: tc,
OldCellSize: cfc,
@@ -164,10 +164,10 @@ func diffNomsMaps(ctx context.Context, ch chan DiffSummaryProgress, keyless bool
}
}
return summaryWithReporter(ctx, ch, durable.NomsMapFromIndex(fromRows), durable.NomsMapFromIndex(toRows), rpr, fromSch, toSch)
return statWithReporter(ctx, ch, durable.NomsMapFromIndex(fromRows), durable.NomsMapFromIndex(toRows), rpr, fromSch, toSch)
}
func summaryWithReporter(ctx context.Context, ch chan DiffSummaryProgress, from, to types.Map, rpr nomsReporter, fromSch, toSch schema.Schema) (err error) {
func statWithReporter(ctx context.Context, ch chan DiffStatProgress, from, to types.Map, rpr nomsReporter, fromSch, toSch schema.Schema) (err error) {
ad := NewAsyncDiffer(1024)
ad.Start(ctx, from, to)
defer func() {
@@ -199,8 +199,8 @@ func summaryWithReporter(ctx context.Context, ch chan DiffSummaryProgress, from,
return nil
}
func reportPkChanges(ctx context.Context, vMapping val.OrdinalMapping, fromD, toD val.TupleDesc, change tree.Diff, ch chan<- DiffSummaryProgress) error {
var sum DiffSummaryProgress
func reportPkChanges(ctx context.Context, vMapping val.OrdinalMapping, fromD, toD val.TupleDesc, change tree.Diff, ch chan<- DiffStatProgress) error {
var sum DiffStatProgress
switch change.Type {
case tree.AddedDiff:
sum.Adds++
@@ -220,8 +220,8 @@ func reportPkChanges(ctx context.Context, vMapping val.OrdinalMapping, fromD, to
}
}
func reportKeylessChanges(ctx context.Context, vMapping val.OrdinalMapping, fromD, toD val.TupleDesc, change tree.Diff, ch chan<- DiffSummaryProgress) error {
var sum DiffSummaryProgress
func reportKeylessChanges(ctx context.Context, vMapping val.OrdinalMapping, fromD, toD val.TupleDesc, change tree.Diff, ch chan<- DiffStatProgress) error {
var sum DiffStatProgress
var n, n2 uint64
switch change.Type {
case tree.AddedDiff:
@@ -280,13 +280,13 @@ func prollyCountCellDiff(mapping val.OrdinalMapping, fromD, toD val.TupleDesc, f
return changed
}
func reportNomsPkChanges(ctx context.Context, change *diff.Difference, fromSch, toSch schema.Schema, ch chan<- DiffSummaryProgress) error {
var summary DiffSummaryProgress
func reportNomsPkChanges(ctx context.Context, change *diff.Difference, fromSch, toSch schema.Schema, ch chan<- DiffStatProgress) error {
var stat DiffStatProgress
switch change.ChangeType {
case types.DiffChangeAdded:
summary = DiffSummaryProgress{Adds: 1}
stat = DiffStatProgress{Adds: 1}
case types.DiffChangeRemoved:
summary = DiffSummaryProgress{Removes: 1}
stat = DiffStatProgress{Removes: 1}
case types.DiffChangeModified:
oldTuple := change.OldValue.(types.Tuple)
newTuple := change.NewValue.(types.Tuple)
@@ -294,19 +294,19 @@ func reportNomsPkChanges(ctx context.Context, change *diff.Difference, fromSch,
if err != nil {
return err
}
summary = DiffSummaryProgress{Changes: 1, CellChanges: cellChanges}
stat = DiffStatProgress{Changes: 1, CellChanges: cellChanges}
default:
return errors.New("unknown change type")
}
select {
case ch <- summary:
case ch <- stat:
return nil
case <-ctx.Done():
return ctx.Err()
}
}
func reportNomsKeylessChanges(ctx context.Context, change *diff.Difference, fromSch, toSch schema.Schema, ch chan<- DiffSummaryProgress) error {
func reportNomsKeylessChanges(ctx context.Context, change *diff.Difference, fromSch, toSch schema.Schema, ch chan<- DiffStatProgress) error {
var oldCard uint64
if change.OldValue != nil {
v, err := change.OldValue.(types.Tuple).Get(row.KeylessCardinalityValIdx)
@@ -325,18 +325,18 @@ func reportNomsKeylessChanges(ctx context.Context, change *diff.Difference, from
newCard = uint64(v.(types.Uint))
}
var summary DiffSummaryProgress
var stat DiffStatProgress
delta := int64(newCard) - int64(oldCard)
if delta > 0 {
summary = DiffSummaryProgress{Adds: uint64(delta)}
stat = DiffStatProgress{Adds: uint64(delta)}
} else if delta < 0 {
summary = DiffSummaryProgress{Removes: uint64(-delta)}
stat = DiffStatProgress{Removes: uint64(-delta)}
} else {
return fmt.Errorf("diff with delta = 0 for key: %s", change.KeyValue.HumanReadableString())
}
select {
case ch <- summary:
case ch <- stat:
return nil
case <-ctx.Done():
return ctx.Err()
+2 -2
View File
@@ -486,10 +486,10 @@ func calcTableMergeStats(ctx context.Context, tbl *doltdb.Table, mergeTbl *doltd
}
ae := atomicerr.New()
ch := make(chan diff.DiffSummaryProgress)
ch := make(chan diff.DiffStatProgress)
go func() {
defer close(ch)
err := diff.Summary(ctx, ch, rows, mergeRows, sch, mergeSch)
err := diff.Stat(ctx, ch, rows, mergeRows, sch, mergeSch)
ae.SetIfError(err)
}()
@@ -275,7 +275,7 @@ func (ds *DiffSummaryTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.
return nil, err
}
// If tableNameExpr defined, return a single table diff summary result
// If tableNameExpr defined, return a single table diff stat result
if ds.tableNameExpr != nil {
delta := findMatchingDelta(deltas, tableName)
diffSum, hasDiff, err := getDiffSummaryNodeFromDelta(ctx, delta, fromRoot, toRoot, tableName)
@@ -352,7 +352,7 @@ func (ds *DiffSummaryTableFunction) evaluateArguments() (interface{}, interface{
}
// getDiffSummaryNodeFromDelta returns diffSummaryNode object and whether there is data diff or not. It gets tables
// from roots and diff summary if there is a valid table exists in both fromRoot and toRoot.
// from roots and diff stat if there is a valid table exists in both fromRoot and toRoot.
func getDiffSummaryNodeFromDelta(ctx *sql.Context, delta diff.TableDelta, fromRoot, toRoot *doltdb.RootValue, tableName string) (diffSummaryNode, bool, error) {
var oldColLen int
var newColLen int
@@ -399,20 +399,20 @@ func getDiffSummaryNodeFromDelta(ctx *sql.Context, delta diff.TableDelta, fromRo
return diffSummaryNode{tableName, diffSum, oldColLen, newColLen, keyless}, hasDiff, nil
}
// getDiffSummary returns diff.DiffSummaryProgress object and whether there is a data diff or not.
func getDiffSummary(ctx *sql.Context, td diff.TableDelta) (diff.DiffSummaryProgress, bool, bool, error) {
// getDiffSummary returns diff.DiffStatProgress object and whether there is a data diff or not.
func getDiffSummary(ctx *sql.Context, td diff.TableDelta) (diff.DiffStatProgress, bool, bool, error) {
// got this method from diff_output.go
ch := make(chan diff.DiffSummaryProgress)
ch := make(chan diff.DiffStatProgress)
grp, ctx2 := errgroup.WithContext(ctx)
grp.Go(func() error {
defer close(ch)
err := diff.SummaryForTableDelta(ctx2, ch, td)
err := diff.StatForTableDelta(ctx2, ch, td)
return err
})
acc := diff.DiffSummaryProgress{}
acc := diff.DiffStatProgress{}
var count int64
grp.Go(func() error {
for {
@@ -437,16 +437,16 @@ func getDiffSummary(ctx *sql.Context, td diff.TableDelta) (diff.DiffSummaryProgr
})
if err := grp.Wait(); err != nil {
return diff.DiffSummaryProgress{}, false, false, err
return diff.DiffStatProgress{}, false, false, err
}
keyless, err := td.IsKeyless(ctx)
if err != nil {
return diff.DiffSummaryProgress{}, false, keyless, err
return diff.DiffStatProgress{}, false, keyless, err
}
if (acc.Adds+acc.Removes+acc.Changes) == 0 && (acc.OldCellSize-acc.NewCellSize) == 0 {
return diff.DiffSummaryProgress{}, false, keyless, nil
return diff.DiffStatProgress{}, false, keyless, nil
}
return acc, true, keyless, nil
@@ -473,7 +473,7 @@ func (d *diffSummaryTableFunctionRowIter) incrementIndexes() {
type diffSummaryNode struct {
tblName string
diffSummary diff.DiffSummaryProgress
diffSummary diff.DiffStatProgress
oldColLen int
newColLen int
keyless bool
@@ -503,10 +503,10 @@ func (d *diffSummaryTableFunctionRowIter) Close(context *sql.Context) error {
return nil
}
// getRowFromDiffSummary takes diff.DiffSummaryProgress and calculates the row_modified, cell_added, cell_deleted.
// getRowFromDiffSummary takes diff.DiffStatProgress and calculates the row_modified, cell_added, cell_deleted.
// If the number of cell change from old to new cell count does not equal to cell_added and/or cell_deleted, there
// must be schema changes that affects cell_added and cell_deleted value addition to the row count * col length number.
func getRowFromDiffSummary(tblName string, dsp diff.DiffSummaryProgress, newColLen, oldColLen int, keyless bool) sql.Row {
func getRowFromDiffSummary(tblName string, dsp diff.DiffStatProgress, newColLen, oldColLen int, keyless bool) sql.Row {
// if table is keyless table, match current CLI command result
if keyless {
return sql.Row{
@@ -544,10 +544,10 @@ func getRowFromDiffSummary(tblName string, dsp diff.DiffSummaryProgress, newColL
}
}
// GetCellsAddedAndDeleted calculates cells added and deleted given diff.DiffSummaryProgress and toCommit table
// GetCellsAddedAndDeleted calculates cells added and deleted given diff.DiffStatProgress and toCommit table
// column length. We use rows added and deleted to calculate cells added and deleted, but it does not include
// cells added and deleted from schema changes. Here we fill those in using total number of cells in each commit table.
func GetCellsAddedAndDeleted(acc diff.DiffSummaryProgress, newColLen int) (uint64, uint64) {
func GetCellsAddedAndDeleted(acc diff.DiffStatProgress, newColLen int) (uint64, uint64) {
var numCellInserts, numCellDeletes float64
rowToCellInserts := float64(acc.Adds) * float64(newColLen)
rowToCellDeletes := float64(acc.Removes) * float64(newColLen)
@@ -2015,7 +2015,7 @@ inner join t as of @Commit3 on rows_unmodified = t.pk;`,
Assertions: []queries.ScriptTestAssertion{
{
Query: "SELECT * from dolt_diff_summary('HEAD~', 'HEAD', 't');",
ExpectedErrStr: "failed to compute diff summary for table t: primary key set changed",
ExpectedErrStr: "failed to compute diff stat for table t: primary key set changed",
},
},
},
-331
View File
@@ -1,331 +0,0 @@
// Copyright 2019 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// This file incorporates work covered by the following copyright and
// permission notice:
//
// Copyright 2016 Attic Labs, Inc. All rights reserved.
// Licensed under the Apache License, version 2.0:
// http://www.apache.org/licenses/LICENSE-2.0
package diff
import (
"context"
"fmt"
"sync/atomic"
humanize "github.com/dustin/go-humanize"
"golang.org/x/sync/errgroup"
"github.com/dolthub/dolt/go/store/d"
"github.com/dolthub/dolt/go/store/datas"
"github.com/dolthub/dolt/go/store/types"
"github.com/dolthub/dolt/go/store/util/status"
)
// Summary prints a summary of the diff between two values to stdout.
func Summary(ctx context.Context, vr1 types.ValueReader, vr2 types.ValueReader, value1, value2 types.Value) {
if is1, err := datas.IsCommit(value1); err != nil {
panic(err)
} else if is1 {
if is2, err := datas.IsCommit(value2); err != nil {
panic(err)
} else if is2 {
fmt.Println("Comparing commit values")
var err error
value1, err = datas.GetCommittedValue(ctx, vr1, value1)
d.PanicIfError(err)
value2, err = datas.GetCommittedValue(ctx, vr2, value2)
d.PanicIfError(err)
}
}
var singular, plural string
if value1.Kind() == value2.Kind() {
switch value1.Kind() {
case types.StructKind:
singular = "field"
plural = "fields"
case types.MapKind:
singular = "entry"
plural = "entries"
default:
singular = "value"
plural = "values"
}
}
eg, ctx := errgroup.WithContext(ctx)
var rp atomic.Value
ch := make(chan diffSummaryProgress)
eg.Go(func() (err error) {
defer close(ch)
defer func() {
if r := recover(); r != nil {
rp.Store(r)
err = fmt.Errorf("panic")
}
}()
err = diffSummary(ctx, ch, value1, value2)
return
})
eg.Go(func() error {
acc := diffSummaryProgress{}
LOOP:
for {
select {
case p, ok := <-ch:
if !ok {
break LOOP
}
acc.Adds += p.Adds
acc.Removes += p.Removes
acc.Changes += p.Changes
acc.NewSize += p.NewSize
acc.OldSize += p.OldSize
if status.WillPrint() {
formatStatus(acc, singular, plural)
}
case <-ctx.Done():
return ctx.Err()
}
}
formatStatus(acc, singular, plural)
status.Done()
return nil
})
if err := eg.Wait(); err != nil {
if r := rp.Load(); r != nil {
panic(r)
}
panic(err)
}
}
type diffSummaryProgress struct {
Adds, Removes, Changes, NewSize, OldSize uint64
}
func diffSummary(ctx context.Context, ch chan diffSummaryProgress, v1, v2 types.Value) error {
if !v1.Equals(v2) {
if ShouldDescend(v1, v2) {
var err error
switch v1.Kind() {
case types.ListKind:
err = diffSummaryList(ctx, ch, v1.(types.List), v2.(types.List))
case types.MapKind:
err = diffSummaryMap(ctx, ch, v1.(types.Map), v2.(types.Map))
case types.SetKind:
err = diffSummarySet(ctx, ch, v1.(types.Set), v2.(types.Set))
case types.StructKind:
err = diffSummaryStructs(ctx, ch, v1.(types.Struct), v2.(types.Struct))
default:
panic("Unrecognized type in diff function")
}
if err != nil {
return err
}
} else {
ch <- diffSummaryProgress{Adds: 1, Removes: 1, NewSize: 1, OldSize: 1}
}
}
return nil
}
func diffSummaryList(ctx context.Context, ch chan<- diffSummaryProgress, v1, v2 types.List) error {
select {
case ch <- diffSummaryProgress{OldSize: v1.Len(), NewSize: v2.Len()}:
case <-ctx.Done():
return ctx.Err()
}
spliceChan := make(chan types.Splice)
eg, ctx := errgroup.WithContext(ctx)
var rp atomic.Value
eg.Go(func() (err error) {
defer close(spliceChan)
defer func() {
if r := recover(); r != nil {
rp.Store(r)
err = fmt.Errorf("panic")
}
}()
return v2.Diff(ctx, v1, spliceChan)
})
eg.Go(func() (err error) {
defer func() {
if r := recover(); r != nil {
rp.Store(r)
err = fmt.Errorf("panic")
}
}()
LOOP:
for {
select {
case splice, ok := <-spliceChan:
if !ok {
break LOOP
}
var summary diffSummaryProgress
if splice.SpRemoved == splice.SpAdded {
summary = diffSummaryProgress{Changes: splice.SpRemoved}
} else {
summary = diffSummaryProgress{Adds: splice.SpAdded, Removes: splice.SpRemoved}
}
select {
case ch <- summary:
case <-ctx.Done():
return ctx.Err()
}
case <-ctx.Done():
return ctx.Err()
}
}
return nil
})
if err := eg.Wait(); err != nil {
if r := rp.Load(); r != nil {
panic(r)
}
return err
}
return nil
}
func diffSummaryMap(ctx context.Context, ch chan<- diffSummaryProgress, v1, v2 types.Map) error {
return diffSummaryValueChanged(ctx, ch, v1.Len(), v2.Len(), func(ctx context.Context, changeChan chan<- types.ValueChanged) error {
return v2.Diff(ctx, v1, changeChan)
})
}
func diffSummarySet(ctx context.Context, ch chan<- diffSummaryProgress, v1, v2 types.Set) error {
return diffSummaryValueChanged(ctx, ch, v1.Len(), v2.Len(), func(ctx context.Context, changeChan chan<- types.ValueChanged) error {
return v2.Diff(ctx, v1, changeChan)
})
}
func diffSummaryStructs(ctx context.Context, ch chan<- diffSummaryProgress, v1, v2 types.Struct) error {
// TODO: Operate on values directly
t1, err := types.TypeOf(v1)
if err != nil {
return err
}
t2, err := types.TypeOf(v2)
if err != nil {
return err
}
size1 := uint64(t1.Desc.(types.StructDesc).Len())
size2 := uint64(t2.Desc.(types.StructDesc).Len())
return diffSummaryValueChanged(ctx, ch, size1, size2, func(ctx context.Context, changeChan chan<- types.ValueChanged) error {
return v2.Diff(ctx, v1, changeChan)
})
}
func diffSummaryValueChanged(ctx context.Context, ch chan<- diffSummaryProgress, oldSize, newSize uint64, f diffFunc) error {
select {
case ch <- diffSummaryProgress{OldSize: oldSize, NewSize: newSize}:
case <-ctx.Done():
return ctx.Err()
}
changeChan := make(chan types.ValueChanged)
eg, ctx := errgroup.WithContext(ctx)
var rp atomic.Value
eg.Go(func() (err error) {
defer close(changeChan)
defer func() {
if r := recover(); r != nil {
rp.Store(r)
err = fmt.Errorf("panic")
}
}()
return f(ctx, changeChan)
})
eg.Go(func() error {
return reportChanges(ctx, ch, changeChan)
})
if err := eg.Wait(); err != nil {
if r := rp.Load(); r != nil {
panic(r)
}
return err
}
return nil
}
func reportChanges(ctx context.Context, ch chan<- diffSummaryProgress, changeChan chan types.ValueChanged) error {
LOOP:
for {
select {
case change, ok := <-changeChan:
if !ok {
break LOOP
}
var summary diffSummaryProgress
switch change.ChangeType {
case types.DiffChangeAdded:
summary = diffSummaryProgress{Adds: 1}
case types.DiffChangeRemoved:
summary = diffSummaryProgress{Removes: 1}
case types.DiffChangeModified:
summary = diffSummaryProgress{Changes: 1}
default:
panic("unknown change type")
}
select {
case ch <- summary:
return nil
case <-ctx.Done():
return ctx.Err()
}
case <-ctx.Done():
return ctx.Err()
}
}
return nil
}
func formatStatus(acc diffSummaryProgress, singular, plural string) {
pluralize := func(singular, plural string, n uint64) string {
var noun string
if n != 1 {
noun = plural
} else {
noun = singular
}
return fmt.Sprintf("%s %s", humanize.Comma(int64(n)), noun)
}
insertions := pluralize("insertion", "insertions", acc.Adds)
deletions := pluralize("deletion", "deletions", acc.Removes)
changes := pluralize("change", "changes", acc.Changes)
oldValues := pluralize(singular, plural, acc.OldSize)
newValues := pluralize(singular, plural, acc.NewSize)
status.Printf("%s (%.2f%%), %s (%.2f%%), %s (%.2f%%), (%s vs %s)", insertions, (float64(100*acc.Adds) / float64(acc.OldSize)), deletions, (float64(100*acc.Removes) / float64(acc.OldSize)), changes, (float64(100*acc.Changes) / float64(acc.OldSize)), oldValues, newValues)
}
-6
View File
@@ -35,12 +35,6 @@ type Map struct {
valDesc val.TupleDesc
}
type DiffSummary struct {
Adds, Removes uint64
Changes, CellChanges uint64
NewSize, OldSize uint64
}
// NewMap creates an empty prolly Tree Map
func NewMap(node tree.Node, ns tree.NodeStore, keyDesc, valDesc val.TupleDesc) Map {
tuples := tree.StaticMap[val.Tuple, val.Tuple, val.TupleDesc]{
-1
View File
@@ -137,7 +137,6 @@ var CopiedNomsFiles []CopiedNomsFile = []CopiedNomsFile{
{Path: "store/diff/patch.go", NomsPath: "go/diff/patch.go", HadCopyrightNotice: true},
{Path: "store/diff/patch_test.go", NomsPath: "go/diff/patch_test.go", HadCopyrightNotice: true},
{Path: "store/diff/print_diff.go", NomsPath: "go/diff/print_diff.go", HadCopyrightNotice: true},
{Path: "store/diff/summary.go", NomsPath: "go/diff/summary.go", HadCopyrightNotice: true},
{Path: "store/hash/base32.go", NomsPath: "go/hash/base32.go", HadCopyrightNotice: true},
{Path: "store/hash/base32_test.go", NomsPath: "go/hash/base32_test.go", HadCopyrightNotice: true},
{Path: "store/hash/hash.go", NomsPath: "go/hash/hash.go", HadCopyrightNotice: true},