@@ -7,12 +7,16 @@ package verifier
77import (
88 "context"
99 "fmt"
10+ "slices"
11+ "strconv"
1012 "strings"
1113 "time"
1214
1315 "github.com/10gen/migration-verifier/internal/reportutils"
1416 "github.com/10gen/migration-verifier/internal/types"
1517 "github.com/olekukonko/tablewriter"
18+ "github.com/samber/lo"
19+ "golang.org/x/exp/maps"
1620)
1721
1822// NOTE: Each of the following should print one trailing and one final
@@ -362,3 +366,67 @@ func (verifier *Verifier) printMismatchInvestigationNotes(strBuilder *strings.Bu
362366 strBuilder .WriteString (line + "\n " )
363367 }
364368}
369+
370+ func (verifier * Verifier ) printChangeEventStatistics (builder * strings.Builder ) {
371+ nsStats := verifier .generationEventRecorder .Read ()
372+
373+ activeNamespacesCount := len (nsStats )
374+
375+ totalEvents := 0
376+ nsTotals := map [string ]int {}
377+ for ns , events := range nsStats {
378+ nsTotals [ns ] = events .Total ()
379+ totalEvents += nsTotals [ns ]
380+ }
381+
382+ eventsDescr := lo .Ternary (
383+ totalEvents == 0 ,
384+ "0" ,
385+ fmt .Sprintf ("%d total, across %d namespace(s)" , totalEvents , activeNamespacesCount ),
386+ )
387+ builder .WriteString (fmt .Sprintf ("Change events this generation: %s\n " , eventsDescr ))
388+
389+ if totalEvents == 0 {
390+ return
391+ }
392+
393+ sortedNamespaces := maps .Keys (nsTotals )
394+ slices .SortFunc (
395+ sortedNamespaces ,
396+ func (ns1 , ns2 string ) int {
397+ if nsTotals [ns1 ] < nsTotals [ns2 ] {
398+ return 1
399+ }
400+
401+ if nsTotals [ns1 ] > nsTotals [ns2 ] {
402+ return - 1
403+ }
404+
405+ return 0
406+ },
407+ )
408+
409+ // Only report the busiest namespaces.
410+ sortedNamespaces = sortedNamespaces [:10 ]
411+
412+ table := tablewriter .NewWriter (builder )
413+ table .SetHeader ([]string {"Namespace" , "Insert" , "Update" , "Replace" , "Delete" , "Total" })
414+
415+ for _ , ns := range sortedNamespaces {
416+ curNsStats := nsStats [ns ]
417+
418+ table .Append (
419+ append (
420+ []string {ns },
421+ strconv .Itoa (curNsStats .Insert ),
422+ strconv .Itoa (curNsStats .Update ),
423+ strconv .Itoa (curNsStats .Replace ),
424+ strconv .Itoa (curNsStats .Delete ),
425+ strconv .Itoa (curNsStats .Total ()),
426+ ),
427+ )
428+ }
429+
430+ builder .WriteString ("\n Most frequently-changing namespaces:\n " )
431+ table .Render ()
432+ }
0 commit comments