104 lines
3.1 KiB
Go
104 lines
3.1 KiB
Go
package library
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// ScanMetrics holds timing and count data collected during a library scan.
|
|
// Worker-pool fields are protected by a mutex; DB-writer fields are
|
|
// single-threaded and use plain addition.
|
|
type ScanMetrics struct {
|
|
mu sync.Mutex
|
|
|
|
// Top-level phases (wall-clock).
|
|
Total time.Duration `json:"total"`
|
|
LoadExisting time.Duration `json:"loadExisting"`
|
|
WalkDuration time.Duration `json:"walkDuration"`
|
|
ExtractionWallClock time.Duration `json:"extractionWallClock"`
|
|
DBWritesWallClock time.Duration `json:"dbWritesWallClock"`
|
|
OrphanCleanup time.Duration `json:"orphanCleanup"`
|
|
PostScanVariants time.Duration `json:"postScanVariants"`
|
|
|
|
// Per-format extraction (cumulative across workers).
|
|
FormatExtraction map[string]int64 `json:"formatExtraction"`
|
|
FormatCount map[string]int64 `json:"formatCount"`
|
|
|
|
// Sub-operation cumulative times (across workers).
|
|
TagExtraction time.Duration `json:"tagExtraction"`
|
|
DurationExtraction time.Duration `json:"durationExtraction"`
|
|
|
|
// DB sub-operations (cumulative, single-threaded DB writer).
|
|
BatchCommits time.Duration `json:"batchCommits"`
|
|
CoverArtSave time.Duration `json:"coverArtSave"`
|
|
|
|
// Thumbnail generation (async worker pool).
|
|
ThumbnailWallClock time.Duration `json:"thumbnailWallClock"`
|
|
ThumbnailGeneration time.Duration `json:"thumbnailGeneration"`
|
|
ThumbnailSmall time.Duration `json:"thumbnailSmall"`
|
|
ThumbnailMedium time.Duration `json:"thumbnailMedium"`
|
|
ThumbnailLarge time.Duration `json:"thumbnailLarge"`
|
|
|
|
// Full-rescan-specific phases.
|
|
ClearQueue time.Duration `json:"clearQueue"`
|
|
ClearDatabase time.Duration `json:"clearDatabase"`
|
|
ClearCoverFiles time.Duration `json:"clearCoverFiles"`
|
|
|
|
// File counts.
|
|
Added int64 `json:"added"`
|
|
Updated int64 `json:"updated"`
|
|
Skipped int64 `json:"skipped"`
|
|
Removed int64 `json:"removed"`
|
|
}
|
|
|
|
func newScanMetrics() *ScanMetrics {
|
|
return &ScanMetrics{
|
|
FormatExtraction: make(map[string]int64),
|
|
FormatCount: make(map[string]int64),
|
|
}
|
|
}
|
|
|
|
// addExtraction records per-file extraction timing from a worker
|
|
// goroutine. It is safe for concurrent use.
|
|
func (m *ScanMetrics) addExtraction(
|
|
fileType string,
|
|
tagTime, durationTime time.Duration,
|
|
) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
|
|
total := tagTime + durationTime
|
|
m.FormatExtraction[fileType] += total.Milliseconds()
|
|
m.FormatCount[fileType]++
|
|
m.TagExtraction += tagTime
|
|
m.DurationExtraction += durationTime
|
|
}
|
|
|
|
// addCoverArtSave records the time spent saving an original cover
|
|
// art file. Called from the single-threaded DB writer.
|
|
func (m *ScanMetrics) addCoverArtSave(d time.Duration) {
|
|
m.CoverArtSave += d
|
|
}
|
|
|
|
// addThumbnailTier records the time spent generating a single
|
|
// thumbnail tier. Safe for concurrent use from the thumbnail
|
|
// worker pool.
|
|
func (m *ScanMetrics) addThumbnailTier(
|
|
suffix string,
|
|
d time.Duration,
|
|
) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
|
|
m.ThumbnailGeneration += d
|
|
|
|
switch suffix {
|
|
case "_sm":
|
|
m.ThumbnailSmall += d
|
|
case "_md":
|
|
m.ThumbnailMedium += d
|
|
case "_lg":
|
|
m.ThumbnailLarge += d
|
|
}
|
|
}
|