diff options
Diffstat (limited to 'format/pack')
| -rw-r--r-- | format/pack/ingest/api.go | 4 | ||||
| -rw-r--r-- | format/pack/ingest/ingest.go | 14 | ||||
| -rw-r--r-- | format/pack/ingest/progress_step.go | 9 | ||||
| -rw-r--r-- | format/pack/ingest/resolve_all.go | 29 | ||||
| -rw-r--r-- | format/pack/ingest/scan.go | 15 | ||||
| -rw-r--r-- | format/pack/ingest/thin_fix.go | 16 |
6 files changed, 83 insertions, 4 deletions
diff --git a/format/pack/ingest/api.go b/format/pack/ingest/api.go index f24bf83d..eb00ded3 100644 --- a/format/pack/ingest/api.go +++ b/format/pack/ingest/api.go @@ -16,6 +16,10 @@ type Options struct { WriteRev bool // Base supplies existing objects for thin-pack fixup. Base objectstore.Store + // Progress receives human-readable progress messages. + // + // When nil, no progress output is emitted. + Progress io.Writer // 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 22007d27..5f204c2b 100644 --- a/format/pack/ingest/ingest.go +++ b/format/pack/ingest/ingest.go @@ -1,6 +1,10 @@ package ingest -import "fmt" +import ( + "fmt" + + "codeberg.org/lindenii/furgit/internal/utils" +) // ingest initializes transaction state and executes the ingest pipeline. func ingest(state *ingestState) (out Result, err error) { @@ -47,6 +51,7 @@ func ingest(state *ingestState) (out Result, err error) { return Result{}, err } + utils.WriteProgressf(state.opts.Progress, "writing index: start\n") err = state.packFile.Sync() if err != nil { return Result{}, &DestinationWriteError{Op: fmt.Sprintf("sync pack: %v", err)} @@ -56,11 +61,18 @@ func ingest(state *ingestState) (out Result, err error) { if err != nil { return Result{}, err } + utils.WriteProgressf(state.opts.Progress, "writing index: done\n") + if state.opts.WriteRev { + utils.WriteProgressf(state.opts.Progress, "writing reverse index: start\n") + } err = writeRev(state) if err != nil { return Result{}, err } + if state.opts.WriteRev { + utils.WriteProgressf(state.opts.Progress, "writing reverse index: done\n") + } return finalizeArtifacts(state) } diff --git a/format/pack/ingest/progress_step.go b/format/pack/ingest/progress_step.go new file mode 100644 index 00000000..cdfc2322 --- /dev/null +++ b/format/pack/ingest/progress_step.go @@ -0,0 +1,9 @@ +package ingest + +func progressStep(total uint32) uint32 { + if total <= 200 { + return 1 + } + + return total / 200 +} diff --git a/format/pack/ingest/resolve_all.go b/format/pack/ingest/resolve_all.go index 992d87ae..e71d38d1 100644 --- a/format/pack/ingest/resolve_all.go +++ b/format/pack/ingest/resolve_all.go @@ -1,16 +1,41 @@ package ingest -import "errors" +import ( + "errors" + + "codeberg.org/lindenii/furgit/internal/utils" +) // resolveAll resolves all delta records and finalizes ObjectID/RealType for every record. func resolveAll(state *ingestState) error { state.unresolvedRefDeltas = state.unresolvedRefDeltas[:0] + var pending uint32 + for idx := range state.records { + if !state.records[idx].resolved { + pending++ + } + } + + if pending == 0 { + return nil + } + + step := progressStep(pending) + var done uint32 + utils.WriteProgressf(state.opts.Progress, "resolving deltas: 0%% (0/%d)\r", pending) + for idx := range state.records { if state.records[idx].resolved { continue } + done++ + if done%step == 0 || done == pending { + percent := done * 100 / pending + utils.WriteProgressf(state.opts.Progress, "resolving deltas: %3d%% (%d/%d)\r", percent, done, pending) + } + visiting := make(map[int]struct{}) ty, content, err := resolveRecord(state, idx, visiting) @@ -37,5 +62,7 @@ func resolveAll(state *ingestState) error { state.baseCache.add(idx, ty, content) } + utils.WriteProgressf(state.opts.Progress, "resolving deltas: 100%% (%d/%d), done.\n", pending, pending) + return nil } diff --git a/format/pack/ingest/scan.go b/format/pack/ingest/scan.go index d1252d00..a0d06dac 100644 --- a/format/pack/ingest/scan.go +++ b/format/pack/ingest/scan.go @@ -3,6 +3,7 @@ package ingest import ( "fmt" + "codeberg.org/lindenii/furgit/internal/utils" "codeberg.org/lindenii/furgit/objectid" ) @@ -29,7 +30,11 @@ func streamPackAndScan(state *ingestState) error { state.ofsDeltas = make([]ofsDeltaRef, 0, state.objectCountHeader) state.refDeltas = make([]refDeltaRef, 0, state.objectCountHeader) - for range state.objectCountHeader { + total := state.objectCountHeader + step := progressStep(total) + utils.WriteProgressf(state.opts.Progress, "receiving objects: 0%% (0/%d)\r", total) + + for i := uint32(0); i < total; i++ { nextOffset, err := scanOneEntry(state, state.stream.consumed) if err != nil { return err @@ -38,8 +43,16 @@ func streamPackAndScan(state *ingestState) error { if nextOffset != state.stream.consumed { return fmt.Errorf("format/pack/ingest: internal stream offset mismatch") } + + done := i + 1 + if done%step == 0 || done == total { + percent := done * 100 / total + utils.WriteProgressf(state.opts.Progress, "receiving objects: %3d%% (%d/%d)\r", percent, done, total) + } } + utils.WriteProgressf(state.opts.Progress, "receiving objects: 100%% (%d/%d), done.\n", total, total) + err = state.stream.finishAndFlushTrailer(state.opts.RequireTrailingEOF) if err != nil { return err diff --git a/format/pack/ingest/thin_fix.go b/format/pack/ingest/thin_fix.go index cdee8748..42e356b6 100644 --- a/format/pack/ingest/thin_fix.go +++ b/format/pack/ingest/thin_fix.go @@ -4,6 +4,7 @@ import ( "fmt" "codeberg.org/lindenii/furgit/internal/intconv" + "codeberg.org/lindenii/furgit/internal/utils" ) // maybeFixThin appends missing bases and rewrites pack header/trailer when needed. @@ -12,6 +13,12 @@ func maybeFixThin(state *ingestState) error { return nil } + utils.WriteProgressf( + state.opts.Progress, + "fixing thin pack: %d unresolved bases\r", + len(state.unresolvedRefDeltas), + ) + if !state.opts.FixThin { return &ThinPackUnresolvedError{Count: len(state.unresolvedRefDeltas)} } @@ -47,7 +54,8 @@ func maybeFixThin(state *ingestState) error { state.stream.consumed = consumed baseIDs := unresolvedThinBaseIDs(state) - for _, id := range baseIDs { + total := len(baseIDs) + for i, id := range baseIDs { ty, content, err := state.opts.Base.ReadBytesContent(id) if err != nil { continue @@ -59,6 +67,8 @@ func maybeFixThin(state *ingestState) error { } state.thinFixed = true + + utils.WriteProgressf(state.opts.Progress, "fixing thin pack: %d/%d\r", i+1, total) } err = rewritePackHeaderAndTrailer(state) @@ -66,5 +76,9 @@ func maybeFixThin(state *ingestState) error { return err } + if state.thinFixed { + utils.WriteProgressf(state.opts.Progress, "fixing thin pack: done.\n") + } + return nil } |
