diff options
| -rw-r--r-- | format/pack/ingest/api.go | 4 | ||||
| -rw-r--r-- | format/pack/ingest/ingest.go | 10 | ||||
| -rw-r--r-- | format/pack/ingest/progress_step.go | 9 | ||||
| -rw-r--r-- | format/pack/ingest/progress_write.go | 10 | ||||
| -rw-r--r-- | format/pack/ingest/resolve_all.go | 18 | ||||
| -rw-r--r-- | format/pack/ingest/scan.go | 22 | ||||
| -rw-r--r-- | format/pack/ingest/thin_fix.go | 21 |
7 files changed, 51 insertions, 43 deletions
diff --git a/format/pack/ingest/api.go b/format/pack/ingest/api.go index 227f6a23..5df09213 100644 --- a/format/pack/ingest/api.go +++ b/format/pack/ingest/api.go @@ -23,6 +23,10 @@ type Options struct { // // When nil, no progress output is emitted. Progress io.Writer + // ProgressFlush flushes transport output after progress writes. + // + // When nil, no explicit flush is attempted. + ProgressFlush func() error // RequireTrailingEOF requires the source to hit EOF after the pack trailer. // // This is suitable for exact pack-file readers, but should be disabled for diff --git a/format/pack/ingest/ingest.go b/format/pack/ingest/ingest.go index e593510b..493942a0 100644 --- a/format/pack/ingest/ingest.go +++ b/format/pack/ingest/ingest.go @@ -2,8 +2,6 @@ package ingest import ( "fmt" - - "codeberg.org/lindenii/furgit/internal/utils" ) // ingest initializes transaction state and executes the ingest pipeline. @@ -51,7 +49,7 @@ func ingest(state *ingestState) (out Result, err error) { return Result{}, err } - utils.BestEffortFprintf(state.opts.Progress, "writing index...\r") + writeProgress(state, "writing index...\r") err = state.packFile.Sync() if err != nil { @@ -63,10 +61,10 @@ func ingest(state *ingestState) (out Result, err error) { return Result{}, err } - utils.BestEffortFprintf(state.opts.Progress, "writing index: done.\n") + writeProgress(state, "writing index: done.\n") if state.opts.WriteRev { - utils.BestEffortFprintf(state.opts.Progress, "writing reverse index...\r") + writeProgress(state, "writing reverse index...\r") } err = writeRev(state) @@ -75,7 +73,7 @@ func ingest(state *ingestState) (out Result, err error) { } if state.opts.WriteRev { - utils.BestEffortFprintf(state.opts.Progress, "writing reverse index: done.\n") + writeProgress(state, "writing reverse index: done.\n") } return finalizeArtifacts(state) diff --git a/format/pack/ingest/progress_step.go b/format/pack/ingest/progress_step.go deleted file mode 100644 index cdfc2322..00000000 --- a/format/pack/ingest/progress_step.go +++ /dev/null @@ -1,9 +0,0 @@ -package ingest - -func progressStep(total uint32) uint32 { - if total <= 200 { - return 1 - } - - return total / 200 -} diff --git a/format/pack/ingest/progress_write.go b/format/pack/ingest/progress_write.go new file mode 100644 index 00000000..3150032b --- /dev/null +++ b/format/pack/ingest/progress_write.go @@ -0,0 +1,10 @@ +package ingest + +import "codeberg.org/lindenii/furgit/internal/utils" + +func writeProgress(state *ingestState, format string, args ...any) { + utils.BestEffortFprintf(state.opts.Progress, format, args...) + if state.opts.ProgressFlush != nil { + _ = state.opts.ProgressFlush() + } +} diff --git a/format/pack/ingest/resolve_all.go b/format/pack/ingest/resolve_all.go index 65cfe44b..e0ad2281 100644 --- a/format/pack/ingest/resolve_all.go +++ b/format/pack/ingest/resolve_all.go @@ -3,7 +3,7 @@ package ingest import ( "errors" - "codeberg.org/lindenii/furgit/internal/utils" + "codeberg.org/lindenii/furgit/internal/progress" ) // resolveAll resolves all delta records and finalizes ObjectID/RealType for every record. @@ -22,11 +22,14 @@ func resolveAll(state *ingestState) error { return nil } - step := progressStep(pending) - var done uint32 - utils.BestEffortFprintf(state.opts.Progress, "resolving deltas: 0%% (0/%d)\r", pending) + meter := progress.New(progress.Options{ + Writer: state.opts.Progress, + Flush: state.opts.ProgressFlush, + Title: "resolving deltas", + Total: uint64(pending), + }) for idx := range state.records { if state.records[idx].resolved { @@ -34,10 +37,7 @@ func resolveAll(state *ingestState) error { } done++ - if done%step == 0 || done == pending { - percent := done * 100 / pending - utils.BestEffortFprintf(state.opts.Progress, "resolving deltas: %3d%% (%d/%d)\r", percent, done, pending) - } + meter.Set(uint64(done), 0) visiting := make(map[int]struct{}) @@ -65,7 +65,7 @@ func resolveAll(state *ingestState) error { state.baseCache.add(idx, ty, content) } - utils.BestEffortFprintf(state.opts.Progress, "resolving deltas: 100%% (%d/%d), done.\n", pending, pending) + meter.Stop("done") return nil } diff --git a/format/pack/ingest/scan.go b/format/pack/ingest/scan.go index bb94ebc3..8fe08ac3 100644 --- a/format/pack/ingest/scan.go +++ b/format/pack/ingest/scan.go @@ -3,7 +3,7 @@ package ingest import ( "fmt" - "codeberg.org/lindenii/furgit/internal/utils" + "codeberg.org/lindenii/furgit/internal/progress" "codeberg.org/lindenii/furgit/objectid" ) @@ -21,22 +21,27 @@ func streamPackAndScan(state *ingestState) error { state.algo.Size(), ) - utils.BestEffortFprintf(state.opts.Progress, "validating pack header...\r") + writeProgress(state, "validating pack header...\r") err = seedStreamWithPackHeader(state) if err != nil { return err } - utils.BestEffortFprintf(state.opts.Progress, "validating pack header: done.\n") + writeProgress(state, "validating pack header: done.\n") state.records = make([]objectRecord, 0, state.objectCountHeader) state.ofsDeltas = make([]ofsDeltaRef, 0, state.objectCountHeader) state.refDeltas = make([]refDeltaRef, 0, state.objectCountHeader) total := state.objectCountHeader - step := progressStep(total) - utils.BestEffortFprintf(state.opts.Progress, "receiving objects: 0%% (0/%d)\r", total) + meter := progress.New(progress.Options{ + Writer: state.opts.Progress, + Flush: state.opts.ProgressFlush, + Title: "receiving objects", + Total: uint64(total), + Throughput: true, + }) for i := range total { nextOffset, err := scanOneEntry(state, state.stream.consumed) @@ -49,13 +54,10 @@ func streamPackAndScan(state *ingestState) error { } done := i + 1 - if done%step == 0 || done == total { - percent := done * 100 / total - utils.BestEffortFprintf(state.opts.Progress, "receiving objects: %3d%% (%d/%d)\r", percent, done, total) - } + meter.Set(uint64(done), state.stream.consumed) } - utils.BestEffortFprintf(state.opts.Progress, "receiving objects: 100%% (%d/%d), done.\n", total, total) + meter.Stop("done") err = state.stream.finishAndFlushTrailer(state.opts.RequireTrailingEOF) if err != nil { diff --git a/format/pack/ingest/thin_fix.go b/format/pack/ingest/thin_fix.go index 634f0367..22c237d2 100644 --- a/format/pack/ingest/thin_fix.go +++ b/format/pack/ingest/thin_fix.go @@ -4,7 +4,7 @@ import ( "fmt" "codeberg.org/lindenii/furgit/internal/intconv" - "codeberg.org/lindenii/furgit/internal/utils" + "codeberg.org/lindenii/furgit/internal/progress" ) // maybeFixThin appends missing bases and rewrites pack header/trailer when needed. @@ -13,8 +13,8 @@ func maybeFixThin(state *ingestState) error { return nil } - utils.BestEffortFprintf( - state.opts.Progress, + writeProgress( + state, "fixing thin pack: %d unresolved bases\r", len(state.unresolvedRefDeltas), ) @@ -56,9 +56,13 @@ func maybeFixThin(state *ingestState) error { baseIDs := unresolvedThinBaseIDs(state) total := len(baseIDs) - if total > 0 { - utils.BestEffortFprintf(state.opts.Progress, "fixing thin pack: 0%% (0/%d)\r", total) - } + meter := progress.New(progress.Options{ + Writer: state.opts.Progress, + Flush: state.opts.ProgressFlush, + Title: "fixing thin pack", + Total: uint64(total), + Sparse: true, + }) for i, id := range baseIDs { ty, content, err := state.opts.Base.ReadBytesContent(id) @@ -74,8 +78,7 @@ func maybeFixThin(state *ingestState) error { state.thinFixed = true done := i + 1 - percent := done * 100 / total - utils.BestEffortFprintf(state.opts.Progress, "fixing thin pack: %3d%% (%d/%d)\r", percent, done, total) + meter.Set(uint64(done), 0) } err = rewritePackHeaderAndTrailer(state) @@ -84,7 +87,7 @@ func maybeFixThin(state *ingestState) error { } if state.thinFixed { - utils.BestEffortFprintf(state.opts.Progress, "fixing thin pack: 100%% (%d/%d), done.\n", total, total) + meter.Stop("done") } return nil |
