Implement version vectors

This commit is contained in:
Jakob Borg
2015-03-25 22:37:35 +01:00
parent b4f45d1e79
commit 6da7f17c4a
9 changed files with 113 additions and 152 deletions

View File

@@ -17,7 +17,6 @@ import (
"github.com/syncthing/protocol"
"github.com/syncthing/syncthing/internal/ignore"
"github.com/syncthing/syncthing/internal/lamport"
"github.com/syncthing/syncthing/internal/symlinks"
"golang.org/x/text/unicode/norm"
)
@@ -61,6 +60,8 @@ type Walker struct {
AutoNormalize bool
// Number of routines to use for hashing
Hashers int
// Our vector clock id
ShortID uint64
}
type TempNamer interface {
@@ -203,6 +204,9 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
rn = normalizedRn
}
var cf protocol.FileInfo
var ok bool
// Index wise symlinks are always files, regardless of what the target
// is, because symlinks carry their target path as their content.
if info.Mode()&os.ModeSymlink == os.ModeSymlink {
@@ -243,7 +247,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
// - it wasn't invalid
// - the symlink type (file/dir) was the same
// - the block list (i.e. hash of target) was the same
cf, ok := w.CurrentFiler.CurrentFile(rn)
cf, ok = w.CurrentFiler.CurrentFile(rn)
if ok && !cf.IsDeleted() && cf.IsSymlink() && !cf.IsInvalid() && SymlinkTypeEqual(flags, cf.Flags) && BlocksEqual(cf.Blocks, blocks) {
return skip
}
@@ -251,7 +255,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
f := protocol.FileInfo{
Name: rn,
Version: lamport.Default.Tick(0),
Version: cf.Version.Update(w.ShortID),
Flags: protocol.FlagSymlink | flags | protocol.FlagNoPermBits | 0666,
Modified: 0,
Blocks: blocks,
@@ -275,7 +279,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
// - was a directory previously (not a file or something else)
// - was not a symlink (since it's a directory now)
// - was not invalid (since it looks valid now)
cf, ok := w.CurrentFiler.CurrentFile(rn)
cf, ok = w.CurrentFiler.CurrentFile(rn)
permUnchanged := w.IgnorePerms || !cf.HasPermissionBits() || PermsEqual(cf.Flags, uint32(info.Mode()))
if ok && permUnchanged && !cf.IsDeleted() && cf.IsDirectory() && !cf.IsSymlink() && !cf.IsInvalid() {
return nil
@@ -290,7 +294,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
}
f := protocol.FileInfo{
Name: rn,
Version: lamport.Default.Tick(0),
Version: cf.Version.Update(w.ShortID),
Flags: flags,
Modified: info.ModTime().Unix(),
}
@@ -312,7 +316,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
// - was not a symlink (since it's a file now)
// - was not invalid (since it looks valid now)
// - has the same size as previously
cf, ok := w.CurrentFiler.CurrentFile(rn)
cf, ok = w.CurrentFiler.CurrentFile(rn)
permUnchanged := w.IgnorePerms || !cf.HasPermissionBits() || PermsEqual(cf.Flags, uint32(info.Mode()))
if ok && permUnchanged && !cf.IsDeleted() && cf.Modified == info.ModTime().Unix() && !cf.IsDirectory() &&
!cf.IsSymlink() && !cf.IsInvalid() && cf.Size() == info.Size() {
@@ -331,7 +335,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
f := protocol.FileInfo{
Name: rn,
Version: lamport.Default.Tick(0),
Version: cf.Version.Update(w.ShortID),
Flags: flags,
Modified: info.ModTime().Unix(),
}