feat: compare with cache before reporting a file as changed

This commit is contained in:
Brian McGee 2023-12-23 13:31:08 +00:00
parent 12aa9a7bef
commit 18bdb7210d
Signed by: brianmcgee
GPG Key ID: D49016E76AD1E8C0
2 changed files with 43 additions and 16 deletions

View File

@ -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(),

View File

@ -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
})