2024-11-26 17:21:41 +00:00
|
|
|
package files
|
|
|
|
|
|
|
|
import (
|
2025-01-21 14:02:43 +00:00
|
|
|
"fmt"
|
2024-11-26 17:21:41 +00:00
|
|
|
"time"
|
2025-01-21 14:02:43 +00:00
|
|
|
|
|
|
|
"github.com/gtsteffaniak/filebrowser/backend/logger"
|
2024-11-26 17:21:41 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// schedule in minutes
|
|
|
|
var scanSchedule = []time.Duration{
|
|
|
|
5 * time.Minute, // 5 minute quick scan & 25 minutes for a full scan
|
|
|
|
10 * time.Minute,
|
|
|
|
20 * time.Minute, // [3] element is 20 minutes, reset anchor for full scan
|
|
|
|
40 * time.Minute,
|
|
|
|
1 * time.Hour,
|
|
|
|
2 * time.Hour,
|
|
|
|
3 * time.Hour,
|
|
|
|
4 * time.Hour, // 4 hours for quick scan & 20 hours for a full scan
|
|
|
|
}
|
|
|
|
|
2025-01-05 19:05:33 +00:00
|
|
|
func (idx *Index) newScanner(origin string) {
|
2024-11-26 17:21:41 +00:00
|
|
|
fullScanAnchor := 3
|
|
|
|
fullScanCounter := 0 // every 5th scan is a full scan
|
|
|
|
for {
|
|
|
|
// Determine sleep time with modifiers
|
|
|
|
fullScanCounter++
|
2025-01-05 19:05:33 +00:00
|
|
|
sleepTime := scanSchedule[idx.currentSchedule] + idx.SmartModifier
|
|
|
|
if idx.assessment == "simple" {
|
|
|
|
sleepTime = scanSchedule[idx.currentSchedule] - idx.SmartModifier
|
2024-11-26 17:21:41 +00:00
|
|
|
}
|
2025-01-05 19:05:33 +00:00
|
|
|
if idx.Source.Config.IndexingInterval > 0 {
|
|
|
|
sleepTime = time.Duration(idx.Source.Config.IndexingInterval) * time.Minute
|
2024-11-26 17:21:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Log and sleep before indexing
|
2025-01-26 00:31:40 +00:00
|
|
|
logger.Debug(fmt.Sprintf("Next scan in %v", sleepTime))
|
2024-11-26 17:21:41 +00:00
|
|
|
time.Sleep(sleepTime)
|
|
|
|
|
2025-01-05 19:05:33 +00:00
|
|
|
idx.scannerMu.Lock()
|
2024-11-26 17:21:41 +00:00
|
|
|
if fullScanCounter == 5 {
|
2025-01-05 19:05:33 +00:00
|
|
|
idx.RunIndexing(origin, false) // Full scan
|
2024-11-26 17:21:41 +00:00
|
|
|
fullScanCounter = 0
|
|
|
|
} else {
|
2025-01-05 19:05:33 +00:00
|
|
|
idx.RunIndexing(origin, true) // Quick scan
|
2024-11-26 17:21:41 +00:00
|
|
|
}
|
2025-01-05 19:05:33 +00:00
|
|
|
idx.scannerMu.Unlock()
|
2024-11-26 17:21:41 +00:00
|
|
|
|
|
|
|
// Adjust schedule based on file changes
|
2025-01-05 19:05:33 +00:00
|
|
|
if idx.FilesChangedDuringIndexing {
|
2024-11-26 17:21:41 +00:00
|
|
|
// Move to at least the full-scan anchor or reduce interval
|
2025-01-05 19:05:33 +00:00
|
|
|
if idx.currentSchedule > fullScanAnchor {
|
|
|
|
idx.currentSchedule = fullScanAnchor
|
|
|
|
} else if idx.currentSchedule > 0 {
|
|
|
|
idx.currentSchedule--
|
2024-11-26 17:21:41 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Increment toward the longest interval if no changes
|
2025-01-05 19:05:33 +00:00
|
|
|
if idx.currentSchedule < len(scanSchedule)-1 {
|
|
|
|
idx.currentSchedule++
|
2024-11-26 17:21:41 +00:00
|
|
|
}
|
|
|
|
}
|
2025-01-05 19:05:33 +00:00
|
|
|
if idx.assessment == "simple" && idx.currentSchedule > 3 {
|
|
|
|
idx.currentSchedule = 3
|
2024-11-26 17:21:41 +00:00
|
|
|
}
|
|
|
|
// Ensure `currentSchedule` stays within bounds
|
2025-01-05 19:05:33 +00:00
|
|
|
if idx.currentSchedule < 0 {
|
|
|
|
idx.currentSchedule = 0
|
|
|
|
} else if idx.currentSchedule >= len(scanSchedule) {
|
|
|
|
idx.currentSchedule = len(scanSchedule) - 1
|
2024-11-26 17:21:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-05 19:05:33 +00:00
|
|
|
func (idx *Index) RunIndexing(origin string, quick bool) {
|
|
|
|
prevNumDirs := idx.NumDirs
|
|
|
|
prevNumFiles := idx.NumFiles
|
2024-11-26 17:21:41 +00:00
|
|
|
if quick {
|
2025-02-16 14:07:38 +00:00
|
|
|
logger.Debug(fmt.Sprintf("Starting quick scan for [%v]", idx.Source.Name))
|
2024-11-26 17:21:41 +00:00
|
|
|
} else {
|
2025-02-16 14:07:38 +00:00
|
|
|
logger.Debug(fmt.Sprintf("Starting full scan for [%v]", idx.Source.Name))
|
2025-01-05 19:05:33 +00:00
|
|
|
idx.NumDirs = 0
|
|
|
|
idx.NumFiles = 0
|
2024-11-26 17:21:41 +00:00
|
|
|
}
|
|
|
|
startTime := time.Now()
|
2025-01-05 19:05:33 +00:00
|
|
|
idx.FilesChangedDuringIndexing = false
|
2024-11-26 17:21:41 +00:00
|
|
|
// Perform the indexing operation
|
2025-01-05 19:05:33 +00:00
|
|
|
err := idx.indexDirectory("/", quick, true)
|
2024-11-26 17:21:41 +00:00
|
|
|
if err != nil {
|
2025-01-21 14:02:43 +00:00
|
|
|
logger.Error(fmt.Sprintf("Error during indexing: %v", err))
|
2024-11-26 17:21:41 +00:00
|
|
|
}
|
2025-01-21 14:02:43 +00:00
|
|
|
firstRun := idx.LastIndexed == time.Time{}
|
2024-11-26 17:21:41 +00:00
|
|
|
// Update the LastIndexed time
|
2025-01-05 19:05:33 +00:00
|
|
|
idx.LastIndexed = time.Now()
|
|
|
|
idx.indexingTime = int(time.Since(startTime).Seconds())
|
2024-11-26 17:21:41 +00:00
|
|
|
if !quick {
|
|
|
|
// update smart indexing
|
2025-01-05 19:05:33 +00:00
|
|
|
if idx.indexingTime < 3 || idx.NumDirs < 10000 {
|
|
|
|
idx.assessment = "simple"
|
|
|
|
idx.SmartModifier = 4 * time.Minute
|
|
|
|
} else if idx.indexingTime > 120 || idx.NumDirs > 500000 {
|
|
|
|
idx.assessment = "complex"
|
|
|
|
modifier := idx.indexingTime / 10 // seconds
|
|
|
|
idx.SmartModifier = time.Duration(modifier) * time.Minute
|
2024-11-26 17:21:41 +00:00
|
|
|
} else {
|
2025-01-05 19:05:33 +00:00
|
|
|
idx.assessment = "normal"
|
2024-11-26 17:21:41 +00:00
|
|
|
}
|
2025-01-21 14:02:43 +00:00
|
|
|
if firstRun {
|
2025-02-16 14:07:38 +00:00
|
|
|
logger.Info(fmt.Sprintf("Index assessment : index=%v complexity=%v directories=%v files=%v", idx.Source.Name, idx.assessment, idx.NumDirs, idx.NumFiles))
|
2025-01-21 14:02:43 +00:00
|
|
|
} else {
|
2025-02-16 14:07:38 +00:00
|
|
|
logger.Debug(fmt.Sprintf("Index assessment : iindex=%v complexity=%v directories=%v files=%v", idx.Source.Name, idx.assessment, idx.NumDirs, idx.NumFiles))
|
2025-01-21 14:02:43 +00:00
|
|
|
}
|
2025-01-05 19:05:33 +00:00
|
|
|
if idx.NumDirs != prevNumDirs || idx.NumFiles != prevNumFiles {
|
|
|
|
idx.FilesChangedDuringIndexing = true
|
2024-11-26 17:21:41 +00:00
|
|
|
}
|
|
|
|
}
|
2025-01-21 14:02:43 +00:00
|
|
|
if firstRun {
|
2025-02-16 14:07:38 +00:00
|
|
|
logger.Info(fmt.Sprintf("Time spent indexing [%v]: %v seconds", idx.Source.Name, idx.indexingTime))
|
2025-01-21 14:02:43 +00:00
|
|
|
} else {
|
2025-02-16 14:07:38 +00:00
|
|
|
logger.Debug(fmt.Sprintf("Time spent indexing [%v]: %v seconds", idx.Source.Name, idx.indexingTime))
|
2025-01-21 14:02:43 +00:00
|
|
|
}
|
2024-11-26 17:21:41 +00:00
|
|
|
}
|
|
|
|
|
2025-01-05 19:05:33 +00:00
|
|
|
func (idx *Index) setupIndexingScanners() {
|
|
|
|
go idx.newScanner("/")
|
2024-11-26 17:21:41 +00:00
|
|
|
}
|