configurable scan parallelism based on hdd or sdd
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user