Fix ChangeDetector to keep the dirMap from last scan

This commit is contained in:
Deluan 2020-01-17 22:41:10 -05:00
parent e55dfff485
commit ea9ed4a287
5 changed files with 32 additions and 27 deletions

View File

@ -118,6 +118,9 @@ func (r *mediaFileRepository) DeleteByPath(path string) error {
} }
filtered = append(filtered, mf.ID) filtered = append(filtered, mf.ID)
} }
if len(filtered) == 0 {
return nil
}
_, err = r.newQuery(o).Filter("id__in", filtered).Delete() _, err = r.newQuery(o).Filter("id__in", filtered).Delete()
return err return err
} }

View File

@ -11,26 +11,24 @@ import (
type ChangeDetector struct { type ChangeDetector struct {
rootFolder string rootFolder string
lastUpdate time.Time
dirMap map[string]time.Time dirMap map[string]time.Time
} }
func NewChangeDetector(rootFolder string, lastUpdate time.Time) *ChangeDetector { func NewChangeDetector(rootFolder string) *ChangeDetector {
return &ChangeDetector{ return &ChangeDetector{
rootFolder: rootFolder, rootFolder: rootFolder,
lastUpdate: lastUpdate,
dirMap: map[string]time.Time{}, dirMap: map[string]time.Time{},
} }
} }
func (s *ChangeDetector) Scan() (changed []string, deleted []string, err error) { func (s *ChangeDetector) Scan(lastModifiedSince time.Time) (changed []string, deleted []string, err error) {
start := time.Now() start := time.Now()
newMap := make(map[string]time.Time) newMap := make(map[string]time.Time)
err = s.loadMap(s.rootFolder, newMap) err = s.loadMap(s.rootFolder, newMap)
if err != nil { if err != nil {
return return
} }
changed, deleted, err = s.checkForUpdates(s.dirMap, newMap) changed, deleted, err = s.checkForUpdates(lastModifiedSince, newMap)
if err != nil { if err != nil {
return return
} }
@ -95,17 +93,17 @@ func (s *ChangeDetector) getRelativePath(subfolder string) string {
return dir return dir
} }
func (s *ChangeDetector) checkForUpdates(oldMap map[string]time.Time, newMap map[string]time.Time) (changed []string, deleted []string, err error) { func (s *ChangeDetector) checkForUpdates(lastModifiedSince time.Time, newMap map[string]time.Time) (changed []string, deleted []string, err error) {
for dir, lastUpdated := range newMap { for dir, lastUpdated := range newMap {
oldLastUpdated, ok := oldMap[dir] oldLastUpdated, ok := s.dirMap[dir]
if !ok { if !ok {
oldLastUpdated = s.lastUpdate oldLastUpdated = lastModifiedSince
} }
if lastUpdated.After(oldLastUpdated) { if lastUpdated.After(oldLastUpdated) {
changed = append(changed, dir) changed = append(changed, dir)
} }
} }
for dir := range oldMap { for dir := range s.dirMap {
if _, ok := newMap[dir]; !ok { if _, ok := newMap[dir]; !ok {
deleted = append(deleted, dir) deleted = append(deleted, dir)
} }

View File

@ -14,18 +14,20 @@ var _ = Describe("ChangeDetector", func() {
var testFolder string var testFolder string
var scanner *ChangeDetector var scanner *ChangeDetector
lastModifiedSince := time.Time{}
BeforeEach(func() { BeforeEach(func() {
testFolder, _ = ioutil.TempDir("", "cloudsonic_tests") testFolder, _ = ioutil.TempDir("", "cloudsonic_tests")
err := os.MkdirAll(testFolder, 0700) err := os.MkdirAll(testFolder, 0700)
if err != nil { if err != nil {
panic(err) panic(err)
} }
scanner = NewChangeDetector(testFolder, time.Time{}) scanner = NewChangeDetector(testFolder)
}) })
It("detects changes recursively", func() { It("detects changes recursively", func() {
// Scan empty folder // Scan empty folder
changed, deleted, err := scanner.Scan() changed, deleted, err := scanner.Scan(lastModifiedSince)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(deleted).To(BeEmpty()) Expect(deleted).To(BeEmpty())
Expect(changed).To(ConsistOf(".")) Expect(changed).To(ConsistOf("."))
@ -35,7 +37,7 @@ var _ = Describe("ChangeDetector", func() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
changed, deleted, err = scanner.Scan() changed, deleted, err = scanner.Scan(lastModifiedSince)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(deleted).To(BeEmpty()) Expect(deleted).To(BeEmpty())
Expect(changed).To(ConsistOf(".", "/a")) Expect(changed).To(ConsistOf(".", "/a"))
@ -45,13 +47,13 @@ var _ = Describe("ChangeDetector", func() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
changed, deleted, err = scanner.Scan() changed, deleted, err = scanner.Scan(lastModifiedSince)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(deleted).To(BeEmpty()) Expect(deleted).To(BeEmpty())
Expect(changed).To(ConsistOf("/a", "/a/b", "/a/b/c")) Expect(changed).To(ConsistOf("/a", "/a/b", "/a/b/c"))
// Scan with no changes // Scan with no changes
changed, deleted, err = scanner.Scan() changed, deleted, err = scanner.Scan(lastModifiedSince)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(deleted).To(BeEmpty()) Expect(deleted).To(BeEmpty())
Expect(changed).To(BeEmpty()) Expect(changed).To(BeEmpty())
@ -61,7 +63,7 @@ var _ = Describe("ChangeDetector", func() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
changed, deleted, err = scanner.Scan() changed, deleted, err = scanner.Scan(lastModifiedSince)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(deleted).To(BeEmpty()) Expect(deleted).To(BeEmpty())
Expect(changed).To(ConsistOf("/a/b")) Expect(changed).To(ConsistOf("/a/b"))
@ -71,7 +73,7 @@ var _ = Describe("ChangeDetector", func() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
changed, deleted, err = scanner.Scan() changed, deleted, err = scanner.Scan(lastModifiedSince)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(deleted).To(BeEmpty()) Expect(deleted).To(BeEmpty())
Expect(changed).To(ConsistOf("/a/b")) Expect(changed).To(ConsistOf("/a/b"))
@ -81,21 +83,22 @@ var _ = Describe("ChangeDetector", func() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
changed, deleted, err = scanner.Scan() changed, deleted, err = scanner.Scan(lastModifiedSince)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(deleted).To(ConsistOf("/a/b/c")) Expect(deleted).To(ConsistOf("/a/b/c"))
Expect(changed).To(ConsistOf("/a/b")) Expect(changed).To(ConsistOf("/a/b"))
// Only returns changes after lastUpdate // Only returns changes after lastModifiedSince
newScanner := NewChangeDetector(testFolder, time.Now()) lastModifiedSince = time.Now()
changed, deleted, err = newScanner.Scan() newScanner := NewChangeDetector(testFolder)
changed, deleted, err = newScanner.Scan(lastModifiedSince)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(deleted).To(BeEmpty()) Expect(deleted).To(BeEmpty())
Expect(changed).To(BeEmpty()) Expect(changed).To(BeEmpty())
Expect(changed).To(BeEmpty()) Expect(changed).To(BeEmpty())
_, err = os.Create(path.Join(testFolder, "a", "b", "new.txt")) _, err = os.Create(path.Join(testFolder, "a", "b", "new.txt"))
changed, deleted, err = newScanner.Scan() changed, deleted, err = newScanner.Scan(lastModifiedSince)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(deleted).To(BeEmpty()) Expect(deleted).To(BeEmpty())
Expect(changed).To(ConsistOf("/a/b")) Expect(changed).To(ConsistOf("/a/b"))

View File

@ -76,16 +76,16 @@ func (s *Scanner) RescanAll(fullRescan bool) error {
func (s *Scanner) Status() []StatusInfo { return nil } func (s *Scanner) Status() []StatusInfo { return nil }
func (i *Scanner) getLastModifiedSince(folder string) time.Time { func (s *Scanner) getLastModifiedSince(folder string) time.Time {
ms, err := i.repos.property.Get(model.PropLastScan + "-" + folder) ms, err := s.repos.property.Get(model.PropLastScan + "-" + folder)
if err != nil { if err != nil {
return time.Time{} return time.Time{}
} }
if ms == "" { if ms == "" {
return time.Time{} return time.Time{}
} }
s, _ := strconv.ParseInt(ms, 10, 64) i, _ := strconv.ParseInt(ms, 10, 64)
return time.Unix(0, s*int64(time.Millisecond)) return time.Unix(0, i*int64(time.Millisecond))
} }
func (s *Scanner) updateLastModifiedSince(folder string, t time.Time) { func (s *Scanner) updateLastModifiedSince(folder string, t time.Time) {

View File

@ -18,12 +18,14 @@ import (
type TagScanner struct { type TagScanner struct {
rootFolder string rootFolder string
repos Repositories repos Repositories
detector *ChangeDetector
} }
func NewTagScanner(rootFolder string, repos Repositories) *TagScanner { func NewTagScanner(rootFolder string, repos Repositories) *TagScanner {
return &TagScanner{ return &TagScanner{
rootFolder: rootFolder, rootFolder: rootFolder,
repos: repos, repos: repos,
detector: NewChangeDetector(rootFolder),
} }
} }
@ -41,8 +43,7 @@ func NewTagScanner(rootFolder string, repos Repositories) *TagScanner {
// Delete all empty albums, delete all empty Artists // Delete all empty albums, delete all empty Artists
// Recreate ArtistIndex // Recreate ArtistIndex
func (s *TagScanner) Scan(ctx context.Context, lastModifiedSince time.Time) error { func (s *TagScanner) Scan(ctx context.Context, lastModifiedSince time.Time) error {
detector := NewChangeDetector(s.rootFolder, lastModifiedSince) changed, deleted, err := s.detector.Scan(lastModifiedSince)
changed, deleted, err := detector.Scan()
if err != nil { if err != nil {
return err return err
} }