diff --git a/internal/cache/cache.go b/internal/cache/cache.go index d10469e..2cacf78 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -64,6 +64,19 @@ func Close() error { return db.Close() } +func getFileInfo(bucket *bolt.Bucket, path string) (*FileInfo, error) { + b := bucket.Get([]byte(path)) + if b != nil { + var cached FileInfo + if err := msgpack.Unmarshal(b, &cached); err != nil { + return nil, errors.Annotatef(err, "failed to unmarshal cache info for path '%v'", path) + } + return &cached, nil + } else { + return nil, nil + } +} + func ChangeSet(ctx context.Context, root string, pathsCh chan<- string) error { return db.Update(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(modifiedBucket)) @@ -83,17 +96,12 @@ func ChangeSet(ctx context.Context, root string, pathsCh chan<- string) error { return nil } - b := bucket.Get([]byte(path)) - - var cached FileInfo - - if b != nil { - if err = msgpack.Unmarshal(b, &cached); err != nil { - return errors.Annotatef(err, "failed to unmarshal cache info for path '%v'", path) - } + cached, err := getFileInfo(bucket, path) + if err != nil { + return err } - changedOrNew := !(cached.Modified == info.ModTime() && cached.Size == info.Size()) + changedOrNew := cached == nil || !(cached.Modified == info.ModTime() && cached.Size == info.Size()) if !changedOrNew { // no change @@ -107,23 +115,38 @@ func ChangeSet(ctx context.Context, root string, pathsCh chan<- string) error { }) } -func WriteModTime(paths []string) error { +func Update(paths []string) (int, error) { if len(paths) == 0 { - return nil + return 0, nil } - return db.Update(func(tx *bolt.Tx) error { + var changes int + + return changes, db.Update(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(modifiedBucket)) for _, path := range paths { if path == "" { continue } + + cached, err := getFileInfo(bucket, path) + if err != nil { + return err + } + pathInfo, err := os.Stat(path) if err != nil { return err } + if cached == nil || !(cached.Modified == pathInfo.ModTime() && cached.Size == pathInfo.Size()) { + changes += 1 + } else { + // no change to write + continue + } + cacheInfo := FileInfo{ Size: pathInfo.Size(), Modified: pathInfo.ModTime(), diff --git a/internal/cli/format.go b/internal/cli/format.go index 2bbf071..0461b5a 100644 --- a/internal/cli/format.go +++ b/internal/cli/format.go @@ -80,7 +80,7 @@ func (f *Format) Run() error { batchSize := 1024 batch := make([]string, batchSize) - var pending, completed int + var pending, completed, changes int LOOP: for { @@ -98,9 +98,11 @@ func (f *Format) Run() error { } batch = append(batch, path) if len(batch) == batchSize { - if err := cache.WriteModTime(batch); err != nil { + count, err := cache.Update(batch) + if err != nil { return err } + changes += count batch = batch[:0] } @@ -113,11 +115,13 @@ func (f *Format) Run() error { } // final flush - if err := cache.WriteModTime(batch); err != nil { + count, err := cache.Update(batch) + if err != nil { return err } + changes += count - println(fmt.Sprintf("%v files changed in %v", completed, time.Now().Sub(start))) + println(fmt.Sprintf("%v files changed in %v", changes, time.Now().Sub(start))) return nil })