@@ -15,6 +15,7 @@ import (
1515 "strings"
1616 "sync"
1717 "text/tabwriter"
18+ "time"
1819
1920 "github.com/adrg/xdg"
2021 "github.com/klauspost/compress/zstd"
@@ -51,6 +52,7 @@ func runCompare(args []string) error {
5152 textile := fs .Bool ("textile" , false , "render the comparison as a Textile table" )
5253 dump := fs .Bool ("dump" , false , "write parsed file counts to stdout (no index query)" )
5354 noCache := fs .Bool ("no-cache" , false , "skip the local prepared-data cache" )
55+ verbose := fs .Bool ("verbose" , false , "log stage progress and timings to stderr" )
5456 setExamples (fs ,
5557 "span-index compare --file 49.ldj" ,
5658 "span-index compare --file 49.ldj.zst --sid 49" ,
@@ -64,12 +66,19 @@ func runCompare(args []string) error {
6466 if * file == "" {
6567 return fmt .Errorf ("--file is required" )
6668 }
69+ vlog := func (format string , args ... any ) {
70+ if * verbose {
71+ log .Printf (format , args ... )
72+ }
73+ }
6774
6875 // Load: detect prepared dump vs raw JSONL by magic prefix.
69- fc , err := loadFileCounts (* file , ! * noCache )
76+ t0 := time .Now ()
77+ fc , err := loadFileCounts (* file , ! * noCache , vlog )
7078 if err != nil {
7179 return err
7280 }
81+ vlog ("load done in %s" , time .Since (t0 ).Round (time .Millisecond ))
7382 log .Printf ("file: %d records, %d distinct ISILs, %d source(s)" , fc .Total , len (fc .Counts ), len (fc .Sources ))
7483
7584 if * dump {
@@ -95,12 +104,16 @@ func runCompare(args []string) error {
95104 log .Printf ("warning: multiple source_ids in file: %v; pass --sid to scope" , ss )
96105 }
97106
107+ vlog ("query index source_id=%q" , resolvedSID )
108+ t1 := time .Now ()
98109 indexFacets , err := fetchIndexFacets (indexFor (* server ), resolvedSID )
99110 if err != nil {
100111 return err
101112 }
113+ vlog ("index returned %d ISILs in %s" , len (indexFacets ), time .Since (t1 ).Round (time .Millisecond ))
102114
103115 isils := mergeISILs (fc .Counts , indexFacets , * all )
116+ vlog ("render %d rows" , len (isils ))
104117 if * textile {
105118 printTextile (isils , fc .Counts , indexFacets , * empty )
106119 } else {
@@ -111,7 +124,11 @@ func runCompare(args []string) error {
111124
112125// loadFileCounts reads either a prepared dump or a raw JSONL stream and
113126// returns aggregated ISIL counts. Caching is keyed by a fast file fingerprint.
114- func loadFileCounts (path string , useCache bool ) (* fileCounts , error ) {
127+ // vlog receives verbose-only progress; it may be nil.
128+ func loadFileCounts (path string , useCache bool , vlog func (string , ... any )) (* fileCounts , error ) {
129+ if vlog == nil {
130+ vlog = func (string , ... any ) {}
131+ }
115132 // Sniff: open, peek the first bytes for our dump magic.
116133 f , err := os .Open (path )
117134 if err != nil {
@@ -120,6 +137,7 @@ func loadFileCounts(path string, useCache bool) (*fileCounts, error) {
120137 br := bufio .NewReader (f )
121138 head , _ := br .Peek (len (dumpMagic ))
122139 if string (head ) == dumpMagic {
140+ vlog ("reading prepared dump %s" , path )
123141 fc , err := readDump (br )
124142 f .Close ()
125143 return fc , err
@@ -134,9 +152,12 @@ func loadFileCounts(path string, useCache bool) (*fileCounts, error) {
134152 cachePath := compareCachePath (fp )
135153 if useCache {
136154 if fc , ok := readCache (cachePath ); ok {
137- log . Printf ( "compare: loaded cached counts from %s" , cachePath )
155+ vlog ( "cache hit %s" , cachePath )
138156 return fc , nil
139157 }
158+ vlog ("cache miss, parsing %s" , path )
159+ } else {
160+ vlog ("parsing %s (cache disabled)" , path )
140161 }
141162
142163 // Parse the JSONL file.
@@ -152,6 +173,8 @@ func loadFileCounts(path string, useCache bool) (*fileCounts, error) {
152173 if useCache {
153174 if err := writeCache (cachePath , fc ); err != nil {
154175 log .Printf ("compare: failed to write cache %s: %v" , cachePath , err )
176+ } else {
177+ vlog ("wrote cache %s" , cachePath )
155178 }
156179 }
157180 return fc , nil
0 commit comments