diff options
| author | Petter Rasmussen | 2016-02-06 19:33:42 +0100 | 
|---|---|---|
| committer | Petter Rasmussen | 2016-02-06 21:34:35 +0100 | 
| commit | 69fb273d2f99604aa3fb80e88fb58f48fc1998c0 (patch) | |
| tree | 1579e3ca79517c5c92e619e22f21a0eedc23eb4b /compare.go | |
| parent | b7e45b080ffe13d286be65ce396da47b36a16944 (diff) | |
| download | gdrive-69fb273d2f99604aa3fb80e88fb58f48fc1998c0.tar.bz2 | |
CachedMd5Comparer
Diffstat (limited to 'compare.go')
| -rw-r--r-- | compare.go | 67 | 
1 files changed, 57 insertions, 10 deletions
| @@ -1,27 +1,74 @@  package main  import ( -	"fmt"      "os" -    "io" -    "crypto/md5" +    "encoding/json"  	"./drive"  ) +const MinCacheFileSize = 5 * 1024 * 1024 +  type Md5Comparer struct {}  func (self Md5Comparer) Changed(local *drive.LocalFile, remote *drive.RemoteFile) bool {      return remote.Md5() != md5sum(local.AbsPath())  } -func md5sum(path string) string { -    h := md5.New() +type CachedFileInfo struct { +    Size int64 `json:"size"` +    Modified int64 `json:"modified"` +    Md5 string `json:"md5"` +} + +func NewCachedMd5Comparer(path string) CachedMd5Comparer { +    cache := map[string]*CachedFileInfo{} +      f, err := os.Open(path) -    if err != nil { -        return "" +    if err == nil { +        json.NewDecoder(f).Decode(&cache) +    } +    f.Close() +    return CachedMd5Comparer{path, cache} +} + +type CachedMd5Comparer struct { +    path string +    cache map[string]*CachedFileInfo +} + +func (self CachedMd5Comparer) Changed(local *drive.LocalFile, remote *drive.RemoteFile) bool { +    return remote.Md5() != self.md5(local) +} + +func (self CachedMd5Comparer) md5(local *drive.LocalFile) string { +    // See if file exist in cache +    cached, found := self.cache[local.AbsPath()] + +    // If found and modification time and size has not changed, return cached md5 +    if found && local.Modified().UnixNano() == cached.Modified && local.Size() == cached.Size { +        return cached.Md5 +    } + +    // Calculate new md5 sum +    md5 := md5sum(local.AbsPath()) + +    // Cache file info if file meets size criteria +    if local.Size() > MinCacheFileSize { +        self.cacheAdd(local, md5) +        self.persist()      } -    defer f.Close() -    io.Copy(h, f) -    return fmt.Sprintf("%x", h.Sum(nil)) +    return md5 +} + +func (self CachedMd5Comparer) cacheAdd(lf *drive.LocalFile, md5 string) { +    self.cache[lf.AbsPath()] = &CachedFileInfo{ +        Size: lf.Size(), +        Modified: lf.Modified().UnixNano(), +        Md5: md5, +    } +} + +func (self CachedMd5Comparer) persist() { +    writeJson(self.path, self.cache)  } | 
