mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-18 02:55:16 +00:00
all: Rename LocalVersion to Sequence (fixes #3461)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3462
This commit is contained in:
parent
a022b0cfff
commit
297240facf
@ -90,8 +90,8 @@ type modelIntf interface {
|
||||
ConnectedTo(deviceID protocol.DeviceID) bool
|
||||
GlobalSize(folder string) (nfiles, deleted int, bytes int64)
|
||||
LocalSize(folder string) (nfiles, deleted int, bytes int64)
|
||||
CurrentLocalVersion(folder string) (int64, bool)
|
||||
RemoteLocalVersion(folder string) (int64, bool)
|
||||
CurrentSequence(folder string) (int64, bool)
|
||||
RemoteSequence(folder string) (int64, bool)
|
||||
State(folder string) (string, time.Time, error)
|
||||
}
|
||||
|
||||
@ -596,10 +596,11 @@ func folderSummary(cfg configIntf, m modelIntf, folder string) map[string]interf
|
||||
res["error"] = err.Error()
|
||||
}
|
||||
|
||||
lv, _ := m.CurrentLocalVersion(folder)
|
||||
rv, _ := m.RemoteLocalVersion(folder)
|
||||
ourSeq, _ := m.CurrentSequence(folder)
|
||||
remoteSeq, _ := m.RemoteSequence(folder)
|
||||
|
||||
res["version"] = lv + rv
|
||||
res["version"] = ourSeq + remoteSeq // legacy
|
||||
res["sequence"] = ourSeq + remoteSeq // new name
|
||||
|
||||
ignorePatterns, _, _ := m.GetIgnores(folder)
|
||||
res["ignorePatterns"] = false
|
||||
@ -1187,7 +1188,7 @@ func (f jsonFileInfo) MarshalJSON() ([]byte, error) {
|
||||
"invalid": f.Invalid,
|
||||
"noPermissions": f.NoPermissions,
|
||||
"modified": time.Unix(f.Modified, 0),
|
||||
"localVersion": f.LocalVersion,
|
||||
"sequence": f.Sequence,
|
||||
"numBlocks": len(f.Blocks),
|
||||
"version": jsonVersionVector(f.Version),
|
||||
})
|
||||
@ -1205,7 +1206,7 @@ func (f jsonDBFileInfo) MarshalJSON() ([]byte, error) {
|
||||
"invalid": f.Invalid,
|
||||
"noPermissions": f.NoPermissions,
|
||||
"modified": time.Unix(f.Modified, 0),
|
||||
"localVersion": f.LocalVersion,
|
||||
"sequence": f.Sequence,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -103,11 +103,11 @@ func (m *mockedModel) LocalSize(folder string) (nfiles, deleted int, bytes int64
|
||||
return 0, 0, 0
|
||||
}
|
||||
|
||||
func (m *mockedModel) CurrentLocalVersion(folder string) (int64, bool) {
|
||||
func (m *mockedModel) CurrentSequence(folder string) (int64, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (m *mockedModel) RemoteLocalVersion(folder string) (int64, bool) {
|
||||
func (m *mockedModel) RemoteSequence(folder string) (int64, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
|
@ -22,15 +22,15 @@ import (
|
||||
)
|
||||
|
||||
type FileSet struct {
|
||||
localVersion int64 // Our local version counter
|
||||
folder string
|
||||
db *Instance
|
||||
blockmap *BlockMap
|
||||
localSize sizeTracker
|
||||
globalSize sizeTracker
|
||||
sequence int64 // Our local sequence number
|
||||
folder string
|
||||
db *Instance
|
||||
blockmap *BlockMap
|
||||
localSize sizeTracker
|
||||
globalSize sizeTracker
|
||||
|
||||
remoteLocalVersion map[protocol.DeviceID]int64 // Highest seen local versions for other devices
|
||||
updateMutex sync.Mutex // protects remoteLocalVersion and database updates
|
||||
remoteSequence map[protocol.DeviceID]int64 // Highest seen sequence numbers for other devices
|
||||
updateMutex sync.Mutex // protects remoteSequence and database updates
|
||||
}
|
||||
|
||||
// FileIntf is the set of methods implemented by both protocol.FileInfo and
|
||||
@ -98,11 +98,11 @@ func (s *sizeTracker) Size() (files, deleted int, bytes int64) {
|
||||
|
||||
func NewFileSet(folder string, db *Instance) *FileSet {
|
||||
var s = FileSet{
|
||||
remoteLocalVersion: make(map[protocol.DeviceID]int64),
|
||||
folder: folder,
|
||||
db: db,
|
||||
blockmap: NewBlockMap(db, db.folderIdx.ID([]byte(folder))),
|
||||
updateMutex: sync.NewMutex(),
|
||||
remoteSequence: make(map[protocol.DeviceID]int64),
|
||||
folder: folder,
|
||||
db: db,
|
||||
blockmap: NewBlockMap(db, db.folderIdx.ID([]byte(folder))),
|
||||
updateMutex: sync.NewMutex(),
|
||||
}
|
||||
|
||||
s.db.checkGlobals([]byte(folder), &s.globalSize)
|
||||
@ -111,16 +111,16 @@ func NewFileSet(folder string, db *Instance) *FileSet {
|
||||
s.db.withAllFolderTruncated([]byte(folder), func(device []byte, f FileInfoTruncated) bool {
|
||||
copy(deviceID[:], device)
|
||||
if deviceID == protocol.LocalDeviceID {
|
||||
if f.LocalVersion > s.localVersion {
|
||||
s.localVersion = f.LocalVersion
|
||||
if f.Sequence > s.sequence {
|
||||
s.sequence = f.Sequence
|
||||
}
|
||||
s.localSize.addFile(f)
|
||||
} else if f.LocalVersion > s.remoteLocalVersion[deviceID] {
|
||||
s.remoteLocalVersion[deviceID] = f.LocalVersion
|
||||
} else if f.Sequence > s.remoteSequence[deviceID] {
|
||||
s.remoteSequence[deviceID] = f.Sequence
|
||||
}
|
||||
return true
|
||||
})
|
||||
l.Debugf("loaded localVersion for %q: %#v", folder, s.localVersion)
|
||||
l.Debugf("loaded sequence for %q: %#v", folder, s.sequence)
|
||||
|
||||
return &s
|
||||
}
|
||||
@ -134,17 +134,17 @@ func (s *FileSet) Replace(device protocol.DeviceID, fs []protocol.FileInfo) {
|
||||
|
||||
if device == protocol.LocalDeviceID {
|
||||
if len(fs) == 0 {
|
||||
s.localVersion = 0
|
||||
s.sequence = 0
|
||||
} else {
|
||||
// Always overwrite LocalVersion on updated files to ensure
|
||||
// Always overwrite Sequence on updated files to ensure
|
||||
// correct ordering. The caller is supposed to leave it set to
|
||||
// zero anyhow.
|
||||
for i := range fs {
|
||||
fs[i].LocalVersion = atomic.AddInt64(&s.localVersion, 1)
|
||||
fs[i].Sequence = atomic.AddInt64(&s.sequence, 1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s.remoteLocalVersion[device] = maxLocalVersion(fs)
|
||||
s.remoteSequence[device] = maxSequence(fs)
|
||||
}
|
||||
s.db.replace([]byte(s.folder), device[:], fs, &s.localSize, &s.globalSize)
|
||||
if device == protocol.LocalDeviceID {
|
||||
@ -164,7 +164,7 @@ func (s *FileSet) Update(device protocol.DeviceID, fs []protocol.FileInfo) {
|
||||
discards := make([]protocol.FileInfo, 0, len(fs))
|
||||
updates := make([]protocol.FileInfo, 0, len(fs))
|
||||
for i, newFile := range fs {
|
||||
fs[i].LocalVersion = atomic.AddInt64(&s.localVersion, 1)
|
||||
fs[i].Sequence = atomic.AddInt64(&s.sequence, 1)
|
||||
existingFile, ok := s.db.getFile([]byte(s.folder), device[:], []byte(newFile.Name))
|
||||
if !ok || !existingFile.Version.Equal(newFile.Version) {
|
||||
discards = append(discards, existingFile)
|
||||
@ -174,7 +174,7 @@ func (s *FileSet) Update(device protocol.DeviceID, fs []protocol.FileInfo) {
|
||||
s.blockmap.Discard(discards)
|
||||
s.blockmap.Update(updates)
|
||||
} else {
|
||||
s.remoteLocalVersion[device] = maxLocalVersion(fs)
|
||||
s.remoteSequence[device] = maxSequence(fs)
|
||||
}
|
||||
s.db.updateFiles([]byte(s.folder), device[:], fs, &s.localSize, &s.globalSize)
|
||||
}
|
||||
@ -248,14 +248,14 @@ func (s *FileSet) Availability(file string) []protocol.DeviceID {
|
||||
return s.db.availability([]byte(s.folder), []byte(osutil.NormalizedFilename(file)))
|
||||
}
|
||||
|
||||
func (s *FileSet) LocalVersion(device protocol.DeviceID) int64 {
|
||||
func (s *FileSet) Sequence(device protocol.DeviceID) int64 {
|
||||
if device == protocol.LocalDeviceID {
|
||||
return atomic.LoadInt64(&s.localVersion)
|
||||
return atomic.LoadInt64(&s.sequence)
|
||||
}
|
||||
|
||||
s.updateMutex.Lock()
|
||||
defer s.updateMutex.Unlock()
|
||||
return s.remoteLocalVersion[device]
|
||||
return s.remoteSequence[device]
|
||||
}
|
||||
|
||||
func (s *FileSet) LocalSize() (files, deleted int, bytes int64) {
|
||||
@ -283,15 +283,15 @@ func (s *FileSet) SetIndexID(device protocol.DeviceID, id protocol.IndexID) {
|
||||
s.db.setIndexID(device[:], []byte(s.folder), id)
|
||||
}
|
||||
|
||||
// maxLocalVersion returns the highest of the LocalVersion numbers found in
|
||||
// the given slice of FileInfos. This should really be the LocalVersion of
|
||||
// maxSequence returns the highest of the Sequence numbers found in
|
||||
// the given slice of FileInfos. This should really be the Sequence of
|
||||
// the last item, but Syncthing v0.14.0 and other implementations may not
|
||||
// implement update sorting....
|
||||
func maxLocalVersion(fs []protocol.FileInfo) int64 {
|
||||
func maxSequence(fs []protocol.FileInfo) int64 {
|
||||
var max int64
|
||||
for _, f := range fs {
|
||||
if f.LocalVersion > max {
|
||||
max = f.LocalVersion
|
||||
if f.Sequence > max {
|
||||
max = f.Sequence
|
||||
}
|
||||
}
|
||||
return max
|
||||
|
@ -100,11 +100,11 @@ func TestGlobalSet(t *testing.T) {
|
||||
m := db.NewFileSet("test", ldb)
|
||||
|
||||
local0 := fileList{
|
||||
protocol.FileInfo{Name: "a", LocalVersion: 1, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(1)},
|
||||
protocol.FileInfo{Name: "b", LocalVersion: 2, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(2)},
|
||||
protocol.FileInfo{Name: "c", LocalVersion: 3, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(3)},
|
||||
protocol.FileInfo{Name: "d", LocalVersion: 4, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(4)},
|
||||
protocol.FileInfo{Name: "z", LocalVersion: 5, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(8)},
|
||||
protocol.FileInfo{Name: "a", Sequence: 1, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(1)},
|
||||
protocol.FileInfo{Name: "b", Sequence: 2, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(2)},
|
||||
protocol.FileInfo{Name: "c", Sequence: 3, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(3)},
|
||||
protocol.FileInfo{Name: "d", Sequence: 4, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(4)},
|
||||
protocol.FileInfo{Name: "z", Sequence: 5, Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(8)},
|
||||
}
|
||||
local1 := fileList{
|
||||
protocol.FileInfo{Name: "a", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}, Blocks: genBlocks(1)},
|
||||
@ -480,7 +480,7 @@ func TestNeed(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocalVersion(t *testing.T) {
|
||||
func TestSequence(t *testing.T) {
|
||||
ldb := db.OpenMemory()
|
||||
|
||||
m := db.NewFileSet("test", ldb)
|
||||
@ -501,10 +501,10 @@ func TestLocalVersion(t *testing.T) {
|
||||
}
|
||||
|
||||
m.Replace(protocol.LocalDeviceID, local1)
|
||||
c0 := m.LocalVersion(protocol.LocalDeviceID)
|
||||
c0 := m.Sequence(protocol.LocalDeviceID)
|
||||
|
||||
m.Replace(protocol.LocalDeviceID, local2)
|
||||
c1 := m.LocalVersion(protocol.LocalDeviceID)
|
||||
c1 := m.Sequence(protocol.LocalDeviceID)
|
||||
if !(c1 > c0) {
|
||||
t.Fatal("Local version number should have incremented")
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ type FileInfoTruncated struct {
|
||||
Invalid bool `protobuf:"varint,7,opt,name=invalid,proto3" json:"invalid,omitempty"`
|
||||
NoPermissions bool `protobuf:"varint,8,opt,name=no_permissions,json=noPermissions,proto3" json:"no_permissions,omitempty"`
|
||||
Version protocol.Vector `protobuf:"bytes,9,opt,name=version" json:"version"`
|
||||
LocalVersion int64 `protobuf:"varint,10,opt,name=local_version,json=localVersion,proto3" json:"local_version,omitempty"`
|
||||
Sequence int64 `protobuf:"varint,10,opt,name=sequence,proto3" json:"sequence,omitempty"`
|
||||
}
|
||||
|
||||
func (m *FileInfoTruncated) Reset() { *m = FileInfoTruncated{} }
|
||||
@ -214,10 +214,10 @@ func (m *FileInfoTruncated) MarshalTo(data []byte) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
i += n2
|
||||
if m.LocalVersion != 0 {
|
||||
if m.Sequence != 0 {
|
||||
data[i] = 0x50
|
||||
i++
|
||||
i = encodeVarintStructs(data, i, uint64(m.LocalVersion))
|
||||
i = encodeVarintStructs(data, i, uint64(m.Sequence))
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
@ -303,8 +303,8 @@ func (m *FileInfoTruncated) ProtoSize() (n int) {
|
||||
}
|
||||
l = m.Version.ProtoSize()
|
||||
n += 1 + l + sovStructs(uint64(l))
|
||||
if m.LocalVersion != 0 {
|
||||
n += 1 + sovStructs(uint64(m.LocalVersion))
|
||||
if m.Sequence != 0 {
|
||||
n += 1 + sovStructs(uint64(m.Sequence))
|
||||
}
|
||||
return n
|
||||
}
|
||||
@ -740,9 +740,9 @@ func (m *FileInfoTruncated) Unmarshal(data []byte) error {
|
||||
iNdEx = postIndex
|
||||
case 10:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field LocalVersion", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType)
|
||||
}
|
||||
m.LocalVersion = 0
|
||||
m.Sequence = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowStructs
|
||||
@ -752,7 +752,7 @@ func (m *FileInfoTruncated) Unmarshal(data []byte) error {
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
m.LocalVersion |= (int64(b) & 0x7F) << shift
|
||||
m.Sequence |= (int64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
@ -884,31 +884,30 @@ var (
|
||||
)
|
||||
|
||||
var fileDescriptorStructs = []byte{
|
||||
// 401 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x51, 0x4f, 0xcb, 0xd3, 0x30,
|
||||
0x1c, 0x6e, 0xb7, 0xba, 0xf5, 0x4d, 0xdf, 0x4e, 0x0d, 0x32, 0xca, 0x0e, 0xdd, 0x98, 0x08, 0x22,
|
||||
0xd8, 0xe9, 0xc4, 0x8b, 0xc7, 0x1d, 0x06, 0x82, 0x07, 0x29, 0x32, 0x8f, 0xa3, 0x4d, 0xb2, 0x2e,
|
||||
0xd0, 0x26, 0xa5, 0x49, 0x07, 0xf3, 0x93, 0x78, 0xdc, 0xc7, 0xd9, 0xd1, 0x2f, 0xa0, 0xe8, 0xfc,
|
||||
0x22, 0x66, 0x49, 0x3b, 0x7b, 0x7c, 0x0f, 0x81, 0xdf, 0x93, 0xe7, 0xcf, 0xef, 0x21, 0x01, 0xbe,
|
||||
0x90, 0x55, 0x8d, 0xa4, 0x88, 0xca, 0x8a, 0x4b, 0x0e, 0x7b, 0x38, 0x9d, 0xbc, 0xce, 0xa8, 0xdc,
|
||||
0xd7, 0x69, 0x84, 0x78, 0xb1, 0xc8, 0x78, 0xc6, 0x17, 0x9a, 0x4a, 0xeb, 0x9d, 0x46, 0x1a, 0xe8,
|
||||
0xc9, 0x58, 0x26, 0xef, 0x3b, 0x72, 0x71, 0x64, 0x48, 0xee, 0x29, 0xcb, 0x3a, 0x53, 0x4e, 0x53,
|
||||
0x93, 0x80, 0x78, 0xbe, 0x48, 0x49, 0x69, 0x6c, 0xf3, 0xaf, 0xc0, 0x5b, 0xd3, 0x9c, 0x6c, 0x48,
|
||||
0x25, 0x28, 0x67, 0xf0, 0x0d, 0x18, 0x1e, 0xcc, 0x18, 0xd8, 0x33, 0xfb, 0xa5, 0xb7, 0x7c, 0x12,
|
||||
0xb5, 0xa6, 0x68, 0x43, 0x90, 0xe4, 0xd5, 0xca, 0x39, 0xff, 0x9a, 0x5a, 0x71, 0x2b, 0x83, 0x63,
|
||||
0x30, 0xc0, 0xe4, 0x40, 0x11, 0x09, 0x7a, 0xca, 0x70, 0x1f, 0x37, 0x68, 0xbe, 0x06, 0x5e, 0x13,
|
||||
0xfa, 0x89, 0x0a, 0x09, 0xdf, 0x02, 0xb7, 0x71, 0x08, 0x95, 0xdc, 0x57, 0xc9, 0x8f, 0x23, 0x9c,
|
||||
0x46, 0x9d, 0xdd, 0x4d, 0xf0, 0x4d, 0xf6, 0xc1, 0xf9, 0x7e, 0x9a, 0x5a, 0xf3, 0x9f, 0x3d, 0xf0,
|
||||
0xf4, 0xaa, 0xfa, 0xc8, 0x76, 0xfc, 0x4b, 0x55, 0x33, 0x94, 0x48, 0x82, 0x21, 0x04, 0x0e, 0x4b,
|
||||
0x0a, 0xa2, 0x4b, 0xde, 0xc5, 0x7a, 0x86, 0xaf, 0x80, 0x23, 0x8f, 0xa5, 0xe9, 0x31, 0x5a, 0x8e,
|
||||
0xff, 0x17, 0xbf, 0xd9, 0x15, 0x1b, 0x6b, 0xcd, 0xd5, 0x2f, 0xe8, 0x37, 0x12, 0xf4, 0x95, 0xb6,
|
||||
0x1f, 0xeb, 0x19, 0xce, 0x80, 0x57, 0x92, 0xaa, 0xa0, 0xc2, 0xb4, 0x74, 0x14, 0xe5, 0xc7, 0xdd,
|
||||
0x2b, 0x38, 0x01, 0x6e, 0xc1, 0x31, 0xdd, 0x51, 0x82, 0x83, 0x47, 0xda, 0x79, 0xc3, 0x30, 0x00,
|
||||
0x43, 0x4c, 0x72, 0xa2, 0xca, 0x05, 0x03, 0x45, 0xb9, 0x71, 0x0b, 0xaf, 0x0c, 0x65, 0x87, 0x24,
|
||||
0xa7, 0x38, 0x18, 0x1a, 0xa6, 0x81, 0xf0, 0x05, 0x18, 0x31, 0xbe, 0xed, 0x2e, 0x75, 0xb5, 0xc0,
|
||||
0x67, 0xfc, 0x73, 0x67, 0x6d, 0xe7, 0x53, 0xee, 0x1e, 0xf6, 0x29, 0xcf, 0x81, 0x9f, 0x73, 0x94,
|
||||
0xe4, 0xdb, 0xd6, 0x07, 0x74, 0xdb, 0x7b, 0x7d, 0xd9, 0xbc, 0xb7, 0x79, 0xdf, 0xd5, 0xb3, 0xf3,
|
||||
0x9f, 0xd0, 0x3a, 0x5f, 0x42, 0xfb, 0x87, 0x3a, 0xbf, 0x2f, 0xa1, 0x75, 0xfa, 0x1b, 0xda, 0xe9,
|
||||
0x40, 0x2f, 0x78, 0xf7, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xe4, 0xb1, 0x7f, 0x07, 0x98, 0x02, 0x00,
|
||||
0x00,
|
||||
// 400 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x51, 0x4d, 0x6b, 0xe2, 0x40,
|
||||
0x18, 0x4e, 0x34, 0xab, 0x71, 0xb2, 0xba, 0xbb, 0xc3, 0x22, 0xc1, 0x43, 0x14, 0x61, 0x61, 0x59,
|
||||
0xd8, 0xb8, 0xeb, 0xb2, 0x97, 0x1e, 0x3d, 0x08, 0x85, 0x1e, 0x4a, 0x28, 0xf6, 0x58, 0x4c, 0x66,
|
||||
0x8c, 0x03, 0xc9, 0x4c, 0x9a, 0x99, 0x08, 0xf6, 0x97, 0xf4, 0xe8, 0xcf, 0xf1, 0xd8, 0x43, 0xcf,
|
||||
0xa5, 0xb5, 0x7f, 0xa4, 0xe3, 0x4c, 0x62, 0x73, 0xec, 0x21, 0xf0, 0x3e, 0x79, 0x3e, 0xde, 0x87,
|
||||
0x79, 0x41, 0x97, 0x8b, 0xbc, 0x88, 0x04, 0xf7, 0xb3, 0x9c, 0x09, 0x06, 0x1b, 0x28, 0x1c, 0xfc,
|
||||
0x8e, 0x89, 0x58, 0x17, 0xa1, 0x1f, 0xb1, 0x74, 0x12, 0xb3, 0x98, 0x4d, 0x14, 0x15, 0x16, 0x2b,
|
||||
0x85, 0x14, 0x50, 0x93, 0xb6, 0x0c, 0xfe, 0xd7, 0xe4, 0x7c, 0x4b, 0x23, 0xb1, 0x26, 0x34, 0xae,
|
||||
0x4d, 0x09, 0x09, 0x75, 0x42, 0xc4, 0x92, 0x49, 0x88, 0x33, 0x6d, 0x1b, 0x5f, 0x03, 0x67, 0x4e,
|
||||
0x12, 0xbc, 0xc0, 0x39, 0x27, 0x8c, 0xc2, 0x3f, 0xa0, 0xbd, 0xd1, 0xa3, 0x6b, 0x8e, 0xcc, 0x9f,
|
||||
0xce, 0xf4, 0xab, 0x5f, 0x99, 0xfc, 0x05, 0x8e, 0x04, 0xcb, 0x67, 0xd6, 0xfe, 0x69, 0x68, 0x04,
|
||||
0x95, 0x0c, 0xf6, 0x41, 0x0b, 0xe1, 0x0d, 0x89, 0xb0, 0xdb, 0x90, 0x86, 0xcf, 0x41, 0x89, 0xc6,
|
||||
0x73, 0xe0, 0x94, 0xa1, 0x17, 0x84, 0x0b, 0xf8, 0x17, 0xd8, 0xa5, 0x83, 0xcb, 0xe4, 0xa6, 0x4c,
|
||||
0xfe, 0xe2, 0xa3, 0xd0, 0xaf, 0xed, 0x2e, 0x83, 0x4f, 0xb2, 0x33, 0xeb, 0x7e, 0x37, 0x34, 0xc6,
|
||||
0x8f, 0x0d, 0xf0, 0xed, 0xa8, 0x3a, 0xa7, 0x2b, 0x76, 0x95, 0x17, 0x34, 0x5a, 0x0a, 0x8c, 0x20,
|
||||
0x04, 0x16, 0x5d, 0xa6, 0x58, 0x95, 0xec, 0x04, 0x6a, 0x86, 0xbf, 0x80, 0x25, 0xb6, 0x99, 0xee,
|
||||
0xd1, 0x9b, 0xf6, 0xdf, 0x8b, 0x9f, 0xec, 0x92, 0x0d, 0x94, 0xe6, 0xe8, 0xe7, 0xe4, 0x0e, 0xbb,
|
||||
0x4d, 0xa9, 0x6d, 0x06, 0x6a, 0x86, 0x23, 0xe0, 0x64, 0x38, 0x4f, 0x09, 0xd7, 0x2d, 0x2d, 0x49,
|
||||
0x75, 0x83, 0xfa, 0x2f, 0x38, 0x00, 0x76, 0xca, 0x10, 0x59, 0x11, 0x8c, 0xdc, 0x4f, 0xca, 0x79,
|
||||
0xc2, 0xd0, 0x05, 0x6d, 0x84, 0x13, 0x2c, 0xcb, 0xb9, 0x2d, 0x49, 0xd9, 0x41, 0x05, 0x8f, 0x0c,
|
||||
0xa1, 0x9b, 0x65, 0x42, 0x90, 0xdb, 0xd6, 0x4c, 0x09, 0xe1, 0x0f, 0xd0, 0xa3, 0xec, 0xa6, 0xbe,
|
||||
0xd4, 0x56, 0x82, 0x2e, 0x65, 0x97, 0xb5, 0xb5, 0xb5, 0xa3, 0x74, 0x3e, 0x76, 0x14, 0x59, 0x94,
|
||||
0xe3, 0xdb, 0x02, 0x53, 0x79, 0x16, 0xa0, 0x8b, 0x56, 0x58, 0x3f, 0xeb, 0xec, 0xfb, 0xfe, 0xc5,
|
||||
0x33, 0xf6, 0x07, 0xcf, 0x7c, 0x90, 0xdf, 0xf3, 0xc1, 0x33, 0x76, 0xaf, 0x9e, 0x19, 0xb6, 0x54,
|
||||
0xee, 0xbf, 0xb7, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdf, 0xb3, 0x6f, 0x36, 0x8f, 0x02, 0x00, 0x00,
|
||||
}
|
||||
|
@ -31,5 +31,5 @@ message FileInfoTruncated {
|
||||
bool invalid = 7;
|
||||
bool no_permissions = 8;
|
||||
protocol.Vector version = 9 [(gogoproto.nullable) = false];
|
||||
int64 local_version = 10;
|
||||
int64 sequence = 10;
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ func (m *Model) StartFolder(folder string) {
|
||||
}
|
||||
|
||||
fs := m.folderFiles[folder]
|
||||
v, ok := fs.LocalVersion(protocol.LocalDeviceID), true
|
||||
v, ok := fs.Sequence(protocol.LocalDeviceID), true
|
||||
indexHasFiles := ok && v > 0
|
||||
if !indexHasFiles {
|
||||
// It's a blank folder, so this may the first time we're looking at
|
||||
@ -583,7 +583,7 @@ func (m *Model) Index(deviceID protocol.DeviceID, folder string, fs []protocol.F
|
||||
"device": deviceID.String(),
|
||||
"folder": folder,
|
||||
"items": len(fs),
|
||||
"version": files.LocalVersion(deviceID),
|
||||
"version": files.Sequence(deviceID),
|
||||
})
|
||||
}
|
||||
|
||||
@ -619,7 +619,7 @@ func (m *Model) IndexUpdate(deviceID protocol.DeviceID, folder string, fs []prot
|
||||
"device": deviceID.String(),
|
||||
"folder": folder,
|
||||
"items": len(fs),
|
||||
"version": files.LocalVersion(deviceID),
|
||||
"version": files.Sequence(deviceID),
|
||||
})
|
||||
|
||||
runner.IndexUpdated()
|
||||
@ -674,8 +674,8 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
|
||||
|
||||
fs := m.folderFiles[folder.ID]
|
||||
myIndexID := fs.IndexID(protocol.LocalDeviceID)
|
||||
myLocalVersion := fs.LocalVersion(protocol.LocalDeviceID)
|
||||
var startLocalVersion int64
|
||||
mySequence := fs.Sequence(protocol.LocalDeviceID)
|
||||
var startSequence int64
|
||||
|
||||
for _, dev := range folder.Devices {
|
||||
if bytes.Equal(dev.ID, m.id[:]) {
|
||||
@ -687,7 +687,7 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
|
||||
// They say they've seen our index ID before, so we can
|
||||
// send a delta update only.
|
||||
|
||||
if dev.MaxLocalVersion > myLocalVersion {
|
||||
if dev.MaxSequence > mySequence {
|
||||
// Safety check. They claim to have more or newer
|
||||
// index data than we have - either we have lost
|
||||
// index data, or reset the index without resetting
|
||||
@ -695,19 +695,19 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
|
||||
// happened. We send a full index to reset the
|
||||
// situation.
|
||||
l.Infof("Device %v folder %q is delta index compatible, but seems out of sync with reality", deviceID, folder.ID)
|
||||
startLocalVersion = 0
|
||||
startSequence = 0
|
||||
continue
|
||||
}
|
||||
|
||||
l.Infof("Device %v folder %q is delta index compatible (mlv=%d)", deviceID, folder.ID, dev.MaxLocalVersion)
|
||||
startLocalVersion = dev.MaxLocalVersion
|
||||
l.Infof("Device %v folder %q is delta index compatible (mlv=%d)", deviceID, folder.ID, dev.MaxSequence)
|
||||
startSequence = dev.MaxSequence
|
||||
} else if dev.IndexID != 0 {
|
||||
// They say they've seen an index ID from us, but it's
|
||||
// not the right one. Either they are confused or we
|
||||
// must have reset our database since last talking to
|
||||
// them. We'll start with a full index transfer.
|
||||
l.Infof("Device %v folder %q has mismatching index ID for us (%v != %v)", deviceID, folder.ID, dev.IndexID, myIndexID)
|
||||
startLocalVersion = 0
|
||||
startSequence = 0
|
||||
}
|
||||
} else if bytes.Equal(dev.ID, deviceID[:]) && dev.IndexID != 0 {
|
||||
// This is the other side's description of themselves. We
|
||||
@ -743,7 +743,7 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
|
||||
}
|
||||
}
|
||||
|
||||
go sendIndexes(conn, folder.ID, fs, m.folderIgnores[folder.ID], startLocalVersion, dbLocation)
|
||||
go sendIndexes(conn, folder.ID, fs, m.folderIgnores[folder.ID], startSequence, dbLocation)
|
||||
}
|
||||
m.fmut.Unlock()
|
||||
|
||||
@ -1216,15 +1216,15 @@ func (m *Model) receivedFile(folder string, file protocol.FileInfo) {
|
||||
m.folderStatRef(folder).ReceivedFile(file.Name, file.IsDeleted())
|
||||
}
|
||||
|
||||
func sendIndexes(conn protocol.Connection, folder string, fs *db.FileSet, ignores *ignore.Matcher, startLocalVersion int64, dbLocation string) {
|
||||
func sendIndexes(conn protocol.Connection, folder string, fs *db.FileSet, ignores *ignore.Matcher, startSequence int64, dbLocation string) {
|
||||
deviceID := conn.ID()
|
||||
name := conn.Name()
|
||||
var err error
|
||||
|
||||
l.Debugf("sendIndexes for %s-%s/%q starting (slv=%d)", deviceID, name, folder, startLocalVersion)
|
||||
l.Debugf("sendIndexes for %s-%s/%q starting (slv=%d)", deviceID, name, folder, startSequence)
|
||||
defer l.Debugf("sendIndexes for %s-%s/%q exiting: %v", deviceID, name, folder, err)
|
||||
|
||||
minLocalVer, err := sendIndexTo(startLocalVersion, conn, folder, fs, ignores, dbLocation)
|
||||
minSequence, err := sendIndexTo(startSequence, conn, folder, fs, ignores, dbLocation)
|
||||
|
||||
// Subscribe to LocalIndexUpdated (we have new information to send) and
|
||||
// DeviceDisconnected (it might be us who disconnected, so we should
|
||||
@ -1238,16 +1238,16 @@ func sendIndexes(conn protocol.Connection, folder string, fs *db.FileSet, ignore
|
||||
return
|
||||
}
|
||||
|
||||
// While we have sent a localVersion at least equal to the one
|
||||
// While we have sent a sequence at least equal to the one
|
||||
// currently in the database, wait for the local index to update. The
|
||||
// local index may update for other folders than the one we are
|
||||
// sending for.
|
||||
if fs.LocalVersion(protocol.LocalDeviceID) <= minLocalVer {
|
||||
if fs.Sequence(protocol.LocalDeviceID) <= minSequence {
|
||||
sub.Poll(time.Minute)
|
||||
continue
|
||||
}
|
||||
|
||||
minLocalVer, err = sendIndexTo(minLocalVer, conn, folder, fs, ignores, dbLocation)
|
||||
minSequence, err = sendIndexTo(minSequence, conn, folder, fs, ignores, dbLocation)
|
||||
|
||||
// Wait a short amount of time before entering the next loop. If there
|
||||
// are continuous changes happening to the local index, this gives us
|
||||
@ -1256,13 +1256,13 @@ func sendIndexes(conn protocol.Connection, folder string, fs *db.FileSet, ignore
|
||||
}
|
||||
}
|
||||
|
||||
func sendIndexTo(minLocalVer int64, conn protocol.Connection, folder string, fs *db.FileSet, ignores *ignore.Matcher, dbLocation string) (int64, error) {
|
||||
func sendIndexTo(minSequence int64, conn protocol.Connection, folder string, fs *db.FileSet, ignores *ignore.Matcher, dbLocation string) (int64, error) {
|
||||
deviceID := conn.ID()
|
||||
name := conn.Name()
|
||||
batch := make([]protocol.FileInfo, 0, indexBatchSize)
|
||||
currentBatchSize := 0
|
||||
initial := minLocalVer == 0
|
||||
maxLocalVer := minLocalVer
|
||||
initial := minSequence == 0
|
||||
maxSequence := minSequence
|
||||
var err error
|
||||
|
||||
sorter := NewIndexSorter(dbLocation)
|
||||
@ -1270,12 +1270,12 @@ func sendIndexTo(minLocalVer int64, conn protocol.Connection, folder string, fs
|
||||
|
||||
fs.WithHave(protocol.LocalDeviceID, func(fi db.FileIntf) bool {
|
||||
f := fi.(protocol.FileInfo)
|
||||
if f.LocalVersion <= minLocalVer {
|
||||
if f.Sequence <= minSequence {
|
||||
return true
|
||||
}
|
||||
|
||||
if f.LocalVersion > maxLocalVer {
|
||||
maxLocalVer = f.LocalVersion
|
||||
if f.Sequence > maxSequence {
|
||||
maxSequence = f.Sequence
|
||||
}
|
||||
|
||||
if ignores.Match(f.Name).IsIgnored() || symlinkInvalid(folder, f) {
|
||||
@ -1323,7 +1323,7 @@ func sendIndexTo(minLocalVer int64, conn protocol.Connection, folder string, fs
|
||||
}
|
||||
}
|
||||
|
||||
return maxLocalVer, err
|
||||
return maxSequence, err
|
||||
}
|
||||
|
||||
func (m *Model) updateLocalsFromScanning(folder string, fs []protocol.FileInfo) {
|
||||
@ -1360,7 +1360,7 @@ func (m *Model) updateLocals(folder string, fs []protocol.FileInfo) {
|
||||
"folder": folder,
|
||||
"items": len(fs),
|
||||
"filenames": filenames,
|
||||
"version": files.LocalVersion(protocol.LocalDeviceID),
|
||||
"version": files.Sequence(protocol.LocalDeviceID),
|
||||
})
|
||||
}
|
||||
|
||||
@ -1751,24 +1751,24 @@ func (m *Model) generateClusterConfig(device protocol.DeviceID) protocol.Cluster
|
||||
deviceCfg := m.cfg.Devices()[device]
|
||||
|
||||
var indexID protocol.IndexID
|
||||
var maxLocalVersion int64
|
||||
var maxSequence int64
|
||||
if device == m.id {
|
||||
indexID = fs.IndexID(protocol.LocalDeviceID)
|
||||
maxLocalVersion = fs.LocalVersion(protocol.LocalDeviceID)
|
||||
maxSequence = fs.Sequence(protocol.LocalDeviceID)
|
||||
} else {
|
||||
indexID = fs.IndexID(device)
|
||||
maxLocalVersion = fs.LocalVersion(device)
|
||||
maxSequence = fs.Sequence(device)
|
||||
}
|
||||
|
||||
protocolDevice := protocol.Device{
|
||||
ID: device[:],
|
||||
Name: deviceCfg.Name,
|
||||
Addresses: deviceCfg.Addresses,
|
||||
Compression: deviceCfg.Compression,
|
||||
CertName: deviceCfg.CertName,
|
||||
Introducer: deviceCfg.Introducer,
|
||||
IndexID: indexID,
|
||||
MaxLocalVersion: maxLocalVersion,
|
||||
ID: device[:],
|
||||
Name: deviceCfg.Name,
|
||||
Addresses: deviceCfg.Addresses,
|
||||
Compression: deviceCfg.Compression,
|
||||
CertName: deviceCfg.CertName,
|
||||
Introducer: deviceCfg.Introducer,
|
||||
IndexID: indexID,
|
||||
MaxSequence: maxSequence,
|
||||
}
|
||||
|
||||
protocolFolder.Devices = append(protocolFolder.Devices, protocolDevice)
|
||||
@ -1823,7 +1823,7 @@ func (m *Model) Override(folder string) {
|
||||
have.Version = have.Version.Merge(need.Version).Update(m.shortID)
|
||||
need = have
|
||||
}
|
||||
need.LocalVersion = 0
|
||||
need.Sequence = 0
|
||||
batch = append(batch, need)
|
||||
return true
|
||||
})
|
||||
@ -1833,10 +1833,10 @@ func (m *Model) Override(folder string) {
|
||||
runner.setState(FolderIdle)
|
||||
}
|
||||
|
||||
// CurrentLocalVersion returns the change version for the given folder.
|
||||
// CurrentSequence returns the change version for the given folder.
|
||||
// This is guaranteed to increment if the contents of the local folder has
|
||||
// changed.
|
||||
func (m *Model) CurrentLocalVersion(folder string) (int64, bool) {
|
||||
func (m *Model) CurrentSequence(folder string) (int64, bool) {
|
||||
m.fmut.RLock()
|
||||
fs, ok := m.folderFiles[folder]
|
||||
m.fmut.RUnlock()
|
||||
@ -1846,13 +1846,13 @@ func (m *Model) CurrentLocalVersion(folder string) (int64, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return fs.LocalVersion(protocol.LocalDeviceID), true
|
||||
return fs.Sequence(protocol.LocalDeviceID), true
|
||||
}
|
||||
|
||||
// RemoteLocalVersion returns the change version for the given folder, as
|
||||
// RemoteSequence returns the change version for the given folder, as
|
||||
// sent by remote peers. This is guaranteed to increment if the contents of
|
||||
// the remote or global folder has changed.
|
||||
func (m *Model) RemoteLocalVersion(folder string) (int64, bool) {
|
||||
func (m *Model) RemoteSequence(folder string) (int64, bool) {
|
||||
m.fmut.RLock()
|
||||
defer m.fmut.RUnlock()
|
||||
|
||||
@ -1865,7 +1865,7 @@ func (m *Model) RemoteLocalVersion(folder string) (int64, bool) {
|
||||
|
||||
var ver int64
|
||||
for _, n := range m.folderDevices[folder] {
|
||||
ver += fs.LocalVersion(n)
|
||||
ver += fs.Sequence(n)
|
||||
}
|
||||
|
||||
return ver, true
|
||||
|
@ -179,7 +179,7 @@ func (f *rwFolder) Serve() {
|
||||
f.setState(FolderIdle)
|
||||
}()
|
||||
|
||||
var prevVer int64
|
||||
var prevSec int64
|
||||
var prevIgnoreHash string
|
||||
|
||||
for {
|
||||
@ -188,7 +188,7 @@ func (f *rwFolder) Serve() {
|
||||
return
|
||||
|
||||
case <-f.remoteIndex:
|
||||
prevVer = 0
|
||||
prevSec = 0
|
||||
f.pullTimer.Reset(0)
|
||||
l.Debugln(f, "remote index updated, rescheduling pull")
|
||||
|
||||
@ -210,14 +210,14 @@ func (f *rwFolder) Serve() {
|
||||
// The ignore patterns have changed. We need to re-evaluate if
|
||||
// there are files we need now that were ignored before.
|
||||
l.Debugln(f, "ignore patterns have changed, resetting prevVer")
|
||||
prevVer = 0
|
||||
prevSec = 0
|
||||
prevIgnoreHash = newHash
|
||||
}
|
||||
|
||||
// RemoteLocalVersion() is a fast call, doesn't touch the database.
|
||||
curVer, ok := f.model.RemoteLocalVersion(f.folderID)
|
||||
if !ok || curVer == prevVer {
|
||||
l.Debugln(f, "skip (curVer == prevVer)", prevVer, ok)
|
||||
// RemoteSequence() is a fast call, doesn't touch the database.
|
||||
curSeq, ok := f.model.RemoteSequence(f.folderID)
|
||||
if !ok || curSeq == prevSec {
|
||||
l.Debugln(f, "skip (curSeq == prevSeq)", prevSec, ok)
|
||||
f.pullTimer.Reset(f.sleep)
|
||||
continue
|
||||
}
|
||||
@ -228,7 +228,7 @@ func (f *rwFolder) Serve() {
|
||||
continue
|
||||
}
|
||||
|
||||
l.Debugln(f, "pulling", prevVer, curVer)
|
||||
l.Debugln(f, "pulling", prevSec, curSeq)
|
||||
|
||||
f.setState(FolderSyncing)
|
||||
f.clearErrors()
|
||||
@ -245,19 +245,19 @@ func (f *rwFolder) Serve() {
|
||||
// sync. Remember the local version number and
|
||||
// schedule a resync a little bit into the future.
|
||||
|
||||
if lv, ok := f.model.RemoteLocalVersion(f.folderID); ok && lv < curVer {
|
||||
if lv, ok := f.model.RemoteSequence(f.folderID); ok && lv < curSeq {
|
||||
// There's a corner case where the device we needed
|
||||
// files from disconnected during the puller
|
||||
// iteration. The files will have been removed from
|
||||
// the index, so we've concluded that we don't need
|
||||
// them, but at the same time we have the local
|
||||
// version that includes those files in curVer. So we
|
||||
// catch the case that localVersion might have
|
||||
// catch the case that sequence might have
|
||||
// decreased here.
|
||||
l.Debugln(f, "adjusting curVer", lv)
|
||||
curVer = lv
|
||||
curSeq = lv
|
||||
}
|
||||
prevVer = curVer
|
||||
prevSec = curSeq
|
||||
l.Debugln(f, "next pull in", f.sleep)
|
||||
f.pullTimer.Reset(f.sleep)
|
||||
break
|
||||
@ -1422,7 +1422,7 @@ loop:
|
||||
break loop
|
||||
}
|
||||
|
||||
job.file.LocalVersion = 0
|
||||
job.file.Sequence = 0
|
||||
batch = append(batch, job)
|
||||
|
||||
if len(batch) == maxBatchSize {
|
||||
|
@ -21,7 +21,7 @@ const (
|
||||
maxBytesInMemory = 512 << 10
|
||||
)
|
||||
|
||||
// The IndexSorter sorts FileInfos based on their LocalVersion. You use it
|
||||
// The IndexSorter sorts FileInfos based on their Sequence. You use it
|
||||
// by first Append()ing all entries to be sorted, then calling Sorted()
|
||||
// which will iterate over all the items in correctly sorted order.
|
||||
type IndexSorter interface {
|
||||
@ -88,7 +88,7 @@ func (s *inMemoryIndexSorter) Append(f protocol.FileInfo) {
|
||||
}
|
||||
|
||||
func (s *inMemoryIndexSorter) Sorted(fn func(protocol.FileInfo) bool) {
|
||||
sort.Sort(byLocalVersion(s.files))
|
||||
sort.Sort(bySequence(s.files))
|
||||
for _, f := range s.files {
|
||||
if !fn(f) {
|
||||
break
|
||||
@ -109,22 +109,22 @@ func (s *inMemoryIndexSorter) copyTo(dst IndexSorter) {
|
||||
}
|
||||
}
|
||||
|
||||
// byLocalVersion sorts FileInfos by LocalVersion
|
||||
type byLocalVersion []protocol.FileInfo
|
||||
// bySequence sorts FileInfos by Sequence
|
||||
type bySequence []protocol.FileInfo
|
||||
|
||||
func (l byLocalVersion) Len() int {
|
||||
func (l bySequence) Len() int {
|
||||
return len(l)
|
||||
}
|
||||
func (l byLocalVersion) Swap(a, b int) {
|
||||
func (l bySequence) Swap(a, b int) {
|
||||
l[a], l[b] = l[b], l[a]
|
||||
}
|
||||
func (l byLocalVersion) Less(a, b int) bool {
|
||||
return l[a].LocalVersion < l[b].LocalVersion
|
||||
func (l bySequence) Less(a, b int) bool {
|
||||
return l[a].Sequence < l[b].Sequence
|
||||
}
|
||||
|
||||
// An onDiskIndexSorter is backed by a LevelDB database in the temporary
|
||||
// directory. It relies on the fact that iterating over the database is done
|
||||
// in key order and uses the LocalVersion as key. When done with an
|
||||
// in key order and uses the Sequence as key. When done with an
|
||||
// onDiskIndexSorter you must call Close() to remove the temporary database.
|
||||
type onDiskIndexSorter struct {
|
||||
db *leveldb.DB
|
||||
@ -158,7 +158,7 @@ func newOnDiskIndexSorter(location string) *onDiskIndexSorter {
|
||||
|
||||
func (s *onDiskIndexSorter) Append(f protocol.FileInfo) {
|
||||
key := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(key[:], uint64(f.LocalVersion))
|
||||
binary.BigEndian.PutUint64(key[:], uint64(f.Sequence))
|
||||
data, err := f.Marshal()
|
||||
if err != nil {
|
||||
panic("bug: marshalling FileInfo should never fail: " + err.Error())
|
||||
|
@ -95,17 +95,17 @@ func TestIndexSorter(t *testing.T) {
|
||||
verifySorted(t, s, nFiles+1)
|
||||
}
|
||||
|
||||
// addFiles adds files with random LocalVersion to the Sorter.
|
||||
// addFiles adds files with random Sequence to the Sorter.
|
||||
func addFiles(n int, s IndexSorter) {
|
||||
for i := 0; i < n; i++ {
|
||||
rnd := rand.Int63()
|
||||
f := protocol.FileInfo{
|
||||
Name: fmt.Sprintf("file-%d", rnd),
|
||||
Size: rand.Int63(),
|
||||
Permissions: uint32(rand.Intn(0777)),
|
||||
Modified: rand.Int63(),
|
||||
LocalVersion: rnd,
|
||||
Version: protocol.Vector{Counters: []protocol.Counter{{ID: 42, Value: uint64(rand.Int63())}}},
|
||||
Name: fmt.Sprintf("file-%d", rnd),
|
||||
Size: rand.Int63(),
|
||||
Permissions: uint32(rand.Intn(0777)),
|
||||
Modified: rand.Int63(),
|
||||
Sequence: rnd,
|
||||
Version: protocol.Vector{Counters: []protocol.Counter{{ID: 42, Value: uint64(rand.Int63())}}},
|
||||
Blocks: []protocol.BlockInfo{{
|
||||
Size: int32(rand.Intn(128 << 10)),
|
||||
Hash: []byte(rand.String(32)),
|
||||
@ -115,15 +115,15 @@ func addFiles(n int, s IndexSorter) {
|
||||
}
|
||||
}
|
||||
|
||||
// verifySorted checks that the files are returned sorted by LocalVersion.
|
||||
// verifySorted checks that the files are returned sorted by Sequence.
|
||||
func verifySorted(t *testing.T, s IndexSorter, expected int) {
|
||||
prevLocalVer := int64(-1)
|
||||
prevSequence := int64(-1)
|
||||
seen := 0
|
||||
s.Sorted(func(f protocol.FileInfo) bool {
|
||||
if f.LocalVersion <= prevLocalVer {
|
||||
t.Fatalf("Unsorted LocalVer, %d <= %d", f.LocalVersion, prevLocalVer)
|
||||
if f.Sequence <= prevSequence {
|
||||
t.Fatalf("Unsorted Sequence, %d <= %d", f.Sequence, prevSequence)
|
||||
}
|
||||
prevLocalVer = f.LocalVersion
|
||||
prevSequence = f.Sequence
|
||||
seen++
|
||||
return true
|
||||
})
|
||||
@ -134,11 +134,11 @@ func verifySorted(t *testing.T, s IndexSorter, expected int) {
|
||||
|
||||
// verifyBreak checks that the Sorter stops iteration once we return false.
|
||||
func verifyBreak(t *testing.T, s IndexSorter, expected int) {
|
||||
prevLocalVer := int64(-1)
|
||||
prevSequence := int64(-1)
|
||||
seen := 0
|
||||
s.Sorted(func(f protocol.FileInfo) bool {
|
||||
if f.LocalVersion <= prevLocalVer {
|
||||
t.Fatalf("Unsorted LocalVer, %d <= %d", f.LocalVersion, prevLocalVer)
|
||||
if f.Sequence <= prevSequence {
|
||||
t.Fatalf("Unsorted Sequence, %d <= %d", f.Sequence, prevSequence)
|
||||
}
|
||||
if len(f.Blocks) != 1 {
|
||||
t.Fatalf("incorrect number of blocks %d != 1", len(f.Blocks))
|
||||
@ -146,7 +146,7 @@ func verifyBreak(t *testing.T, s IndexSorter, expected int) {
|
||||
if len(f.Version.Counters) != 1 {
|
||||
t.Fatalf("incorrect number of version counters %d != 1", len(f.Version.Counters))
|
||||
}
|
||||
prevLocalVer = f.LocalVersion
|
||||
prevSequence = f.Sequence
|
||||
seen++
|
||||
return seen < expected/2
|
||||
})
|
||||
|
@ -255,14 +255,14 @@ func (*Folder) ProtoMessage() {}
|
||||
func (*Folder) Descriptor() ([]byte, []int) { return fileDescriptorBep, []int{3} }
|
||||
|
||||
type Device struct {
|
||||
ID []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Addresses []string `protobuf:"bytes,3,rep,name=addresses" json:"addresses,omitempty"`
|
||||
Compression Compression `protobuf:"varint,4,opt,name=compression,proto3,enum=protocol.Compression" json:"compression,omitempty"`
|
||||
CertName string `protobuf:"bytes,5,opt,name=cert_name,json=certName,proto3" json:"cert_name,omitempty"`
|
||||
MaxLocalVersion int64 `protobuf:"varint,6,opt,name=max_local_version,json=maxLocalVersion,proto3" json:"max_local_version,omitempty"`
|
||||
Introducer bool `protobuf:"varint,7,opt,name=introducer,proto3" json:"introducer,omitempty"`
|
||||
IndexID IndexID `protobuf:"varint,8,opt,name=index_id,json=indexId,proto3,customtype=IndexID" json:"index_id"`
|
||||
ID []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Addresses []string `protobuf:"bytes,3,rep,name=addresses" json:"addresses,omitempty"`
|
||||
Compression Compression `protobuf:"varint,4,opt,name=compression,proto3,enum=protocol.Compression" json:"compression,omitempty"`
|
||||
CertName string `protobuf:"bytes,5,opt,name=cert_name,json=certName,proto3" json:"cert_name,omitempty"`
|
||||
MaxSequence int64 `protobuf:"varint,6,opt,name=max_sequence,json=maxSequence,proto3" json:"max_sequence,omitempty"`
|
||||
Introducer bool `protobuf:"varint,7,opt,name=introducer,proto3" json:"introducer,omitempty"`
|
||||
IndexID IndexID `protobuf:"varint,8,opt,name=index_id,json=indexId,proto3,customtype=IndexID" json:"index_id"`
|
||||
}
|
||||
|
||||
func (m *Device) Reset() { *m = Device{} }
|
||||
@ -300,7 +300,7 @@ type FileInfo struct {
|
||||
Invalid bool `protobuf:"varint,7,opt,name=invalid,proto3" json:"invalid,omitempty"`
|
||||
NoPermissions bool `protobuf:"varint,8,opt,name=no_permissions,json=noPermissions,proto3" json:"no_permissions,omitempty"`
|
||||
Version Vector `protobuf:"bytes,9,opt,name=version" json:"version"`
|
||||
LocalVersion int64 `protobuf:"varint,10,opt,name=local_version,json=localVersion,proto3" json:"local_version,omitempty"`
|
||||
Sequence int64 `protobuf:"varint,10,opt,name=sequence,proto3" json:"sequence,omitempty"`
|
||||
Blocks []BlockInfo `protobuf:"bytes,16,rep,name=Blocks,json=blocks" json:"Blocks"`
|
||||
}
|
||||
|
||||
@ -658,10 +658,10 @@ func (m *Device) MarshalTo(data []byte) (int, error) {
|
||||
i = encodeVarintBep(data, i, uint64(len(m.CertName)))
|
||||
i += copy(data[i:], m.CertName)
|
||||
}
|
||||
if m.MaxLocalVersion != 0 {
|
||||
if m.MaxSequence != 0 {
|
||||
data[i] = 0x30
|
||||
i++
|
||||
i = encodeVarintBep(data, i, uint64(m.MaxLocalVersion))
|
||||
i = encodeVarintBep(data, i, uint64(m.MaxSequence))
|
||||
}
|
||||
if m.Introducer {
|
||||
data[i] = 0x38
|
||||
@ -832,10 +832,10 @@ func (m *FileInfo) MarshalTo(data []byte) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
i += n1
|
||||
if m.LocalVersion != 0 {
|
||||
if m.Sequence != 0 {
|
||||
data[i] = 0x50
|
||||
i++
|
||||
i = encodeVarintBep(data, i, uint64(m.LocalVersion))
|
||||
i = encodeVarintBep(data, i, uint64(m.Sequence))
|
||||
}
|
||||
if len(m.Blocks) > 0 {
|
||||
for _, msg := range m.Blocks {
|
||||
@ -1288,8 +1288,8 @@ func (m *Device) ProtoSize() (n int) {
|
||||
if l > 0 {
|
||||
n += 1 + l + sovBep(uint64(l))
|
||||
}
|
||||
if m.MaxLocalVersion != 0 {
|
||||
n += 1 + sovBep(uint64(m.MaxLocalVersion))
|
||||
if m.MaxSequence != 0 {
|
||||
n += 1 + sovBep(uint64(m.MaxSequence))
|
||||
}
|
||||
if m.Introducer {
|
||||
n += 2
|
||||
@ -1362,8 +1362,8 @@ func (m *FileInfo) ProtoSize() (n int) {
|
||||
}
|
||||
l = m.Version.ProtoSize()
|
||||
n += 1 + l + sovBep(uint64(l))
|
||||
if m.LocalVersion != 0 {
|
||||
n += 1 + sovBep(uint64(m.LocalVersion))
|
||||
if m.Sequence != 0 {
|
||||
n += 1 + sovBep(uint64(m.Sequence))
|
||||
}
|
||||
if len(m.Blocks) > 0 {
|
||||
for _, e := range m.Blocks {
|
||||
@ -2218,9 +2218,9 @@ func (m *Device) Unmarshal(data []byte) error {
|
||||
iNdEx = postIndex
|
||||
case 6:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field MaxLocalVersion", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field MaxSequence", wireType)
|
||||
}
|
||||
m.MaxLocalVersion = 0
|
||||
m.MaxSequence = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowBep
|
||||
@ -2230,7 +2230,7 @@ func (m *Device) Unmarshal(data []byte) error {
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
m.MaxLocalVersion |= (int64(b) & 0x7F) << shift
|
||||
m.MaxSequence |= (int64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
@ -2741,9 +2741,9 @@ func (m *FileInfo) Unmarshal(data []byte) error {
|
||||
iNdEx = postIndex
|
||||
case 10:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field LocalVersion", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType)
|
||||
}
|
||||
m.LocalVersion = 0
|
||||
m.Sequence = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowBep
|
||||
@ -2753,7 +2753,7 @@ func (m *FileInfo) Unmarshal(data []byte) error {
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
m.LocalVersion |= (int64(b) & 0x7F) << shift
|
||||
m.Sequence |= (int64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
@ -3927,103 +3927,103 @@ var (
|
||||
|
||||
var fileDescriptorBep = []byte{
|
||||
// 1569 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x6f, 0x1b, 0x45,
|
||||
0x14, 0x8f, 0xed, 0xf5, 0xbf, 0x89, 0x93, 0x3a, 0xd3, 0x34, 0x35, 0xdb, 0x90, 0x84, 0x6d, 0x2b,
|
||||
0x82, 0x45, 0x53, 0x68, 0x81, 0x4a, 0x48, 0x20, 0x39, 0xf6, 0x26, 0xb5, 0xea, 0xac, 0xdd, 0xb5,
|
||||
0x9d, 0x52, 0x0e, 0x58, 0x6b, 0xef, 0xd8, 0x59, 0x75, 0xbd, 0x63, 0x76, 0xd7, 0x6d, 0xc3, 0x17,
|
||||
0x40, 0x82, 0x2f, 0xc0, 0x05, 0xa9, 0x57, 0xc4, 0x95, 0x0f, 0xd1, 0x63, 0xd5, 0x23, 0x87, 0x0a,
|
||||
0xc2, 0x85, 0x2f, 0xc0, 0x9d, 0x37, 0x33, 0xbb, 0xde, 0x75, 0xfe, 0xa0, 0x1e, 0x38, 0x58, 0x9e,
|
||||
0x79, 0xef, 0x37, 0x6f, 0x66, 0x7e, 0xef, 0xf7, 0xde, 0x2c, 0xca, 0xf7, 0xc9, 0x64, 0x67, 0xe2,
|
||||
0x52, 0x9f, 0xe2, 0x1c, 0xff, 0x1b, 0x50, 0x5b, 0xbe, 0x35, 0xb2, 0xfc, 0xa3, 0x69, 0x7f, 0x67,
|
||||
0x40, 0xc7, 0xb7, 0x47, 0x74, 0x44, 0x6f, 0x73, 0x4f, 0x7f, 0x3a, 0xe4, 0x33, 0x3e, 0xe1, 0x23,
|
||||
0xb1, 0x50, 0x99, 0xa0, 0xf4, 0x7d, 0x62, 0xdb, 0x14, 0x6f, 0xa2, 0x45, 0x93, 0x3c, 0xb5, 0x06,
|
||||
0xa4, 0xe7, 0x18, 0x63, 0x52, 0x4a, 0x6c, 0x25, 0xb6, 0xf3, 0x3a, 0x12, 0x26, 0x0d, 0x2c, 0x0c,
|
||||
0x30, 0xb0, 0x2d, 0xe2, 0xf8, 0x02, 0x90, 0x14, 0x00, 0x61, 0xe2, 0x80, 0x9b, 0x68, 0x39, 0x00,
|
||||
0x3c, 0x25, 0xae, 0x67, 0x51, 0xa7, 0x94, 0xe2, 0x98, 0x25, 0x61, 0x3d, 0x14, 0x46, 0xc5, 0x43,
|
||||
0x99, 0xfb, 0xc4, 0x30, 0x89, 0x8b, 0x3f, 0x40, 0x92, 0x7f, 0x3c, 0x11, 0x7b, 0x2d, 0xdf, 0xb9,
|
||||
0xb2, 0x13, 0xde, 0x61, 0xe7, 0x80, 0x78, 0x9e, 0x31, 0x22, 0x1d, 0x70, 0xea, 0x1c, 0x82, 0xbf,
|
||||
0x84, 0xcd, 0xe9, 0x78, 0xe2, 0x82, 0x83, 0x05, 0x4e, 0xf2, 0x15, 0xeb, 0x67, 0x56, 0x54, 0x23,
|
||||
0x8c, 0x1e, 0x5f, 0xa0, 0x54, 0xd0, 0x52, 0xd5, 0x9e, 0x7a, 0x3e, 0x71, 0xab, 0xd4, 0x19, 0x5a,
|
||||
0x23, 0xfc, 0x11, 0xca, 0x0e, 0xa9, 0x0d, 0xa7, 0xf0, 0x60, 0xfb, 0xd4, 0xf6, 0xe2, 0x9d, 0x62,
|
||||
0x14, 0x6c, 0x8f, 0x3b, 0x76, 0xa5, 0x97, 0x6f, 0x36, 0x17, 0xf4, 0x10, 0xa6, 0xfc, 0x98, 0x44,
|
||||
0x19, 0xe1, 0xc1, 0x6b, 0x28, 0x69, 0x99, 0x82, 0xa2, 0xdd, 0xcc, 0xc9, 0x9b, 0xcd, 0x64, 0xbd,
|
||||
0xa6, 0x83, 0x05, 0xaf, 0xa2, 0xb4, 0x6d, 0xf4, 0x89, 0x1d, 0x90, 0x23, 0x26, 0xf8, 0x1a, 0xca,
|
||||
0xbb, 0x70, 0xe1, 0x1e, 0x75, 0xec, 0x63, 0x4e, 0x49, 0x4e, 0xcf, 0x31, 0x43, 0x13, 0xe6, 0xf8,
|
||||
0x16, 0xc2, 0xd6, 0xc8, 0xa1, 0x2e, 0xe9, 0x4d, 0x88, 0x3b, 0xb6, 0xf8, 0x69, 0xbd, 0x92, 0xc4,
|
||||
0x51, 0x2b, 0xc2, 0xd3, 0x8a, 0x1c, 0xf8, 0x3a, 0x5a, 0x0a, 0xe0, 0x26, 0xb1, 0x89, 0x4f, 0x4a,
|
||||
0x69, 0x8e, 0x2c, 0x08, 0x63, 0x8d, 0xdb, 0xe0, 0x6e, 0xab, 0xa6, 0xe5, 0x19, 0x7d, 0x9b, 0xf4,
|
||||
0x7c, 0x32, 0x9e, 0xf4, 0x2c, 0xc7, 0x24, 0xcf, 0x89, 0x57, 0xca, 0x70, 0x2c, 0x0e, 0x7c, 0x1d,
|
||||
0x70, 0xd5, 0x85, 0x87, 0xb1, 0x21, 0x32, 0xed, 0x95, 0x8a, 0xa7, 0xd9, 0xa8, 0x71, 0x47, 0xc8,
|
||||
0x46, 0x00, 0x53, 0x7e, 0x05, 0x36, 0x84, 0x27, 0xc6, 0x46, 0x61, 0x8e, 0x0d, 0x8c, 0xa4, 0x98,
|
||||
0x52, 0xf8, 0x18, 0xaf, 0xa3, 0xbc, 0x61, 0x9a, 0x2c, 0x2b, 0xb0, 0x55, 0x0a, 0xb6, 0xca, 0xeb,
|
||||
0x91, 0x01, 0xdf, 0x9b, 0xcf, 0xb2, 0x74, 0x5a, 0x17, 0x17, 0xa5, 0x97, 0x51, 0x3c, 0x20, 0x6e,
|
||||
0xa0, 0xcc, 0x34, 0xdf, 0x2f, 0xc7, 0x0c, 0x5c, 0x97, 0x65, 0xb4, 0x32, 0x36, 0x9e, 0xf7, 0x6c,
|
||||
0x3a, 0x30, 0xec, 0x99, 0x34, 0x19, 0x17, 0x29, 0xfd, 0x12, 0x38, 0x1a, 0xcc, 0x1e, 0x88, 0x13,
|
||||
0x6f, 0x20, 0x64, 0x39, 0xbe, 0x4b, 0xcd, 0x29, 0x2c, 0x2f, 0x65, 0x39, 0x61, 0x31, 0x0b, 0xfe,
|
||||
0x14, 0xe5, 0x38, 0x9b, 0x3d, 0xb8, 0x71, 0x0e, 0xbc, 0xd2, 0xae, 0xcc, 0x78, 0xf9, 0xfd, 0xcd,
|
||||
0x66, 0x96, 0x73, 0x59, 0xaf, 0x9d, 0x44, 0x43, 0x3d, 0xcb, 0xb1, 0x75, 0x53, 0x69, 0xa2, 0x34,
|
||||
0xb7, 0x01, 0x57, 0x19, 0xa1, 0xa7, 0xa0, 0xc0, 0x82, 0x19, 0xde, 0x41, 0xe9, 0xa1, 0x65, 0x03,
|
||||
0x27, 0x49, 0x4e, 0x3f, 0x8e, 0x89, 0x11, 0xcc, 0x75, 0x67, 0x48, 0x83, 0x04, 0x08, 0x98, 0xd2,
|
||||
0x45, 0x8b, 0x3c, 0x60, 0x77, 0x62, 0x1a, 0x3e, 0xf9, 0xdf, 0xc2, 0x7e, 0x9f, 0x42, 0xb9, 0xd0,
|
||||
0x33, 0xcb, 0x5f, 0x22, 0x96, 0xbf, 0x72, 0x50, 0xb2, 0xa2, 0x00, 0xd7, 0xce, 0xc6, 0x8b, 0xd5,
|
||||
0x2c, 0xac, 0xf7, 0xac, 0xef, 0x08, 0x97, 0x7c, 0x4a, 0xe7, 0x63, 0xbc, 0x85, 0x16, 0x4f, 0xeb,
|
||||
0x7c, 0x49, 0x8f, 0x9b, 0xb0, 0x8c, 0x72, 0x63, 0x6a, 0x5a, 0x43, 0x8b, 0x98, 0x3c, 0x93, 0x29,
|
||||
0x7d, 0x36, 0xc7, 0x25, 0x26, 0x53, 0x26, 0x71, 0x33, 0xd0, 0x72, 0x38, 0x65, 0x1e, 0xcb, 0x79,
|
||||
0x6a, 0xd8, 0x90, 0x16, 0x91, 0xb4, 0x70, 0xca, 0xba, 0x92, 0x43, 0xe7, 0x8a, 0x2b, 0xc7, 0x01,
|
||||
0x4b, 0x0e, 0x8d, 0x17, 0x16, 0x54, 0x40, 0x28, 0x8d, 0x3c, 0xf8, 0xe7, 0x2a, 0xe0, 0x90, 0x0c,
|
||||
0x7c, 0x3a, 0xeb, 0x07, 0x01, 0x8c, 0x95, 0xe2, 0xbc, 0xa4, 0x10, 0x3f, 0x6d, 0xc1, 0x8e, 0xeb,
|
||||
0xe9, 0x63, 0x94, 0xd9, 0x05, 0xc3, 0x93, 0xb0, 0xae, 0x2e, 0x47, 0x51, 0xb9, 0x3d, 0x96, 0x82,
|
||||
0x4c, 0x9f, 0x03, 0x3f, 0x97, 0x7e, 0x7a, 0xb1, 0xb9, 0xa0, 0x3c, 0x44, 0xf9, 0x19, 0x80, 0xa5,
|
||||
0x97, 0x0e, 0x87, 0x1e, 0xf1, 0x79, 0x2e, 0x52, 0x7a, 0x30, 0x9b, 0x31, 0xcc, 0xb2, 0x91, 0x0e,
|
||||
0x18, 0x06, 0xdb, 0x91, 0xe1, 0x1d, 0x71, 0xd6, 0x0b, 0x3a, 0x1f, 0x07, 0x21, 0xbf, 0x40, 0x19,
|
||||
0x71, 0x13, 0x7c, 0x17, 0xe5, 0x06, 0x74, 0xea, 0xf8, 0x51, 0xf7, 0x5b, 0x89, 0x17, 0x19, 0xf7,
|
||||
0x04, 0xa7, 0x9a, 0x01, 0x95, 0x3d, 0x94, 0x0d, 0x5c, 0xc0, 0x69, 0x58, 0xf1, 0xd2, 0xee, 0x95,
|
||||
0x50, 0xff, 0xed, 0x23, 0xea, 0xfa, 0x5c, 0xff, 0xb1, 0x76, 0x08, 0x39, 0x98, 0x8a, 0xf3, 0x49,
|
||||
0xba, 0x98, 0x28, 0xbf, 0x25, 0x50, 0x56, 0x27, 0xdf, 0x4e, 0x89, 0xe7, 0xc7, 0x5a, 0x47, 0x7a,
|
||||
0xae, 0x75, 0x44, 0x7a, 0x4e, 0xce, 0xe9, 0x39, 0x94, 0x64, 0x2a, 0x26, 0xc9, 0x88, 0x1c, 0xe9,
|
||||
0x5c, 0x72, 0xd2, 0xe7, 0x90, 0x93, 0x89, 0xc8, 0x61, 0x02, 0x19, 0xba, 0x74, 0xcc, 0x5b, 0x25,
|
||||
0x75, 0x0d, 0xf7, 0x38, 0x50, 0xd0, 0x12, 0xb3, 0x76, 0x42, 0xa3, 0xd2, 0x43, 0x39, 0x9d, 0x78,
|
||||
0x13, 0xd0, 0x0a, 0xb9, 0xf0, 0xd8, 0x10, 0x1e, 0xca, 0xd1, 0xe0, 0x87, 0x86, 0xf0, 0x6c, 0x8c,
|
||||
0xdf, 0x47, 0xd2, 0x80, 0x9a, 0xe2, 0xc8, 0xcb, 0xf1, 0xfc, 0xab, 0xae, 0x4b, 0xe1, 0x35, 0x32,
|
||||
0xa1, 0x5c, 0x18, 0x00, 0x5e, 0xe2, 0x62, 0x8d, 0x3e, 0x73, 0x6c, 0x6a, 0x98, 0x2d, 0x97, 0x8e,
|
||||
0x58, 0x6b, 0xbb, 0xb0, 0xae, 0x6b, 0x28, 0x3b, 0xe5, 0x95, 0x1f, 0x56, 0xf6, 0x8d, 0xf9, 0x4a,
|
||||
0x3c, 0x1d, 0x48, 0xb4, 0x89, 0x50, 0xc1, 0xc1, 0x52, 0xe5, 0x75, 0x02, 0xc9, 0x17, 0xa3, 0x71,
|
||||
0x1d, 0x2d, 0x0a, 0x64, 0x2f, 0xf6, 0x4a, 0x6f, 0xbf, 0xcd, 0x46, 0xbc, 0x09, 0xa0, 0xe9, 0x6c,
|
||||
0x7c, 0xee, 0x53, 0x10, 0xab, 0xb8, 0xd4, 0x5b, 0x57, 0x1c, 0xaf, 0x91, 0xd9, 0x83, 0x26, 0xc1,
|
||||
0xdd, 0xd3, 0x7a, 0xa1, 0x2f, 0x0a, 0x85, 0xdb, 0x94, 0x0c, 0x92, 0x5a, 0x96, 0x33, 0x52, 0x36,
|
||||
0x51, 0xba, 0x6a, 0x53, 0x9e, 0xac, 0x0c, 0xbc, 0xb6, 0x1e, 0x6c, 0x13, 0x70, 0x28, 0x66, 0xe5,
|
||||
0xd7, 0x49, 0xb4, 0x18, 0xfb, 0xd0, 0x80, 0xf3, 0x2c, 0x57, 0x1b, 0xdd, 0x76, 0x47, 0xd5, 0x7b,
|
||||
0xd5, 0xa6, 0xb6, 0x57, 0xdf, 0x2f, 0x2e, 0xc8, 0xeb, 0x3f, 0xfc, 0xbc, 0x55, 0x1a, 0x47, 0xa0,
|
||||
0xf9, 0x6f, 0x08, 0xd8, 0xa2, 0xae, 0xd5, 0xd4, 0xaf, 0x8a, 0x09, 0x79, 0x15, 0x80, 0xc5, 0x18,
|
||||
0x50, 0x74, 0xfb, 0x0f, 0x51, 0x81, 0x03, 0x7a, 0xdd, 0x56, 0xad, 0xd2, 0x51, 0x8b, 0x49, 0x59,
|
||||
0x06, 0xdc, 0xda, 0x69, 0x5c, 0xc0, 0xf7, 0x75, 0xa8, 0x0b, 0xf5, 0x61, 0x57, 0x6d, 0x77, 0x8a,
|
||||
0x29, 0x79, 0x0d, 0x80, 0x38, 0x06, 0x0c, 0x2b, 0xe6, 0x26, 0xc8, 0x50, 0x6d, 0xb7, 0x9a, 0x5a,
|
||||
0x5b, 0x2d, 0x4a, 0xf2, 0x55, 0x40, 0x5d, 0x9e, 0x43, 0x05, 0x0a, 0xfd, 0x0c, 0xad, 0xd4, 0x9a,
|
||||
0x8f, 0xb4, 0x46, 0xb3, 0x52, 0xeb, 0xb5, 0xf4, 0xe6, 0x3e, 0xac, 0x69, 0x17, 0xd3, 0xf2, 0x26,
|
||||
0xe0, 0xaf, 0xc5, 0xf0, 0x67, 0x04, 0xf7, 0x2e, 0xb0, 0x57, 0xd7, 0xf6, 0x8b, 0x19, 0xf9, 0x32,
|
||||
0x40, 0x2f, 0xc5, 0xa0, 0x8c, 0x54, 0x76, 0xe3, 0x6a, 0xa3, 0x09, 0x5b, 0x67, 0xcf, 0xdc, 0x98,
|
||||
0x93, 0x5d, 0xfe, 0x06, 0xe1, 0xb3, 0x9f, 0x62, 0xf8, 0x06, 0x92, 0xb4, 0xa6, 0xa6, 0x02, 0xa1,
|
||||
0xfc, 0xfe, 0x67, 0x11, 0x1a, 0x75, 0x08, 0x56, 0x50, 0xaa, 0xf1, 0xf5, 0x27, 0x40, 0xe6, 0x3b,
|
||||
0x00, 0xba, 0x72, 0x16, 0x04, 0xce, 0x32, 0x45, 0x8b, 0xf1, 0xc0, 0x0a, 0xca, 0x1d, 0xa8, 0x9d,
|
||||
0x0a, 0x90, 0x5b, 0x81, 0xe0, 0xfc, 0x48, 0xa1, 0xfb, 0x80, 0xf8, 0x06, 0x2f, 0xc0, 0x75, 0x94,
|
||||
0xd6, 0xd4, 0x43, 0x55, 0x87, 0xc0, 0x2b, 0x00, 0x58, 0x0a, 0x01, 0x1a, 0x01, 0x5d, 0xc1, 0x83,
|
||||
0x9f, 0xa9, 0x34, 0x1e, 0x55, 0x1e, 0xb7, 0x21, 0x39, 0x18, 0xdc, 0xcb, 0xa1, 0xbb, 0x62, 0x3f,
|
||||
0x33, 0x8e, 0xbd, 0xf2, 0x3f, 0x09, 0x54, 0x88, 0xbf, 0x6d, 0xb0, 0x40, 0xda, 0xab, 0x37, 0xd4,
|
||||
0x70, 0xbb, 0xb8, 0x8f, 0x8d, 0xf1, 0x36, 0xca, 0xd7, 0xea, 0xba, 0x5a, 0xed, 0x34, 0xf5, 0xc7,
|
||||
0xe1, 0x5d, 0xe2, 0xa0, 0x9a, 0xe5, 0x72, 0x71, 0xb3, 0x4f, 0xbf, 0x42, 0xfb, 0xf1, 0x41, 0xa3,
|
||||
0xae, 0x3d, 0xe8, 0xf1, 0x88, 0x49, 0xf9, 0x1a, 0x80, 0xaf, 0xc6, 0xc1, 0xed, 0xe3, 0xb1, 0x6d,
|
||||
0x39, 0x4f, 0x78, 0xe0, 0x7b, 0x68, 0x25, 0x84, 0x47, 0x1b, 0xa4, 0xe4, 0x2d, 0x58, 0xb3, 0x7e,
|
||||
0xce, 0x9a, 0x68, 0x9f, 0xbb, 0xe8, 0x52, 0xb8, 0xb0, 0xab, 0x3d, 0xd0, 0x40, 0x16, 0xa0, 0x9c,
|
||||
0x0d, 0x58, 0x26, 0x9f, 0xb3, 0xac, 0xeb, 0x3c, 0x71, 0x40, 0x14, 0xe5, 0x5f, 0x12, 0x28, 0x3f,
|
||||
0xeb, 0x50, 0x8c, 0x67, 0xad, 0xd9, 0x53, 0x75, 0xbd, 0xa9, 0x87, 0x17, 0x9f, 0x39, 0x35, 0xca,
|
||||
0x87, 0xf8, 0x3d, 0x94, 0xdd, 0x57, 0x35, 0x55, 0xaf, 0x57, 0xc3, 0x7a, 0x98, 0x41, 0xf6, 0x89,
|
||||
0x43, 0x5c, 0x6b, 0x00, 0x1f, 0xfc, 0x05, 0x08, 0xd3, 0xee, 0x56, 0xef, 0x87, 0x37, 0xe6, 0x02,
|
||||
0x8e, 0x85, 0x6a, 0x4f, 0x07, 0x47, 0xfc, 0xb6, 0x65, 0x56, 0x3a, 0x87, 0x95, 0x46, 0xbd, 0x26,
|
||||
0xa0, 0x29, 0xb9, 0x04, 0xd0, 0xd5, 0x19, 0xb4, 0x2e, 0x9e, 0x77, 0x86, 0x2d, 0x9b, 0x68, 0xe3,
|
||||
0xbf, 0x7b, 0x11, 0x7c, 0x76, 0x64, 0x2a, 0xad, 0x96, 0xaa, 0xd5, 0xc2, 0xd3, 0x47, 0xbe, 0xca,
|
||||
0x64, 0x42, 0x1c, 0x93, 0x21, 0xf6, 0x9a, 0xfa, 0xbe, 0xda, 0x09, 0x0f, 0x1f, 0x21, 0xf6, 0xa8,
|
||||
0x3b, 0x22, 0xfe, 0xee, 0xfa, 0xcb, 0x3f, 0x37, 0x16, 0x5e, 0xc1, 0xef, 0xe5, 0xc9, 0x46, 0xe2,
|
||||
0x15, 0xfc, 0xfe, 0x38, 0xd9, 0x58, 0xf8, 0x1b, 0xfe, 0x5f, 0xfc, 0xb5, 0x91, 0xe8, 0x67, 0x78,
|
||||
0xef, 0xba, 0xfb, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x7a, 0x46, 0xf6, 0x94, 0x0d, 0x00,
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x6f, 0xdb, 0x46,
|
||||
0x16, 0xb7, 0x24, 0x8a, 0x92, 0x46, 0xb2, 0x23, 0x4f, 0x1c, 0x47, 0xcb, 0x78, 0x6d, 0x2f, 0x93,
|
||||
0x60, 0xbd, 0xc2, 0xc6, 0xd9, 0x4d, 0xda, 0x06, 0x28, 0xd0, 0x02, 0xb2, 0x44, 0x3b, 0x44, 0x64,
|
||||
0x4a, 0xa1, 0x24, 0xa7, 0xe9, 0xa1, 0x02, 0x25, 0x8e, 0x64, 0x22, 0x14, 0x47, 0x25, 0xa9, 0x24,
|
||||
0xee, 0x47, 0x68, 0xbf, 0x40, 0x2f, 0x05, 0x82, 0xde, 0x7a, 0xef, 0x87, 0xc8, 0x31, 0xc8, 0xb1,
|
||||
0x87, 0xa0, 0x75, 0x2f, 0xfd, 0x02, 0xbd, 0x16, 0x7d, 0x9c, 0x21, 0x45, 0xca, 0x7f, 0x8a, 0x1c,
|
||||
0x7a, 0x10, 0x34, 0xf3, 0xde, 0x6f, 0xde, 0xcc, 0xfc, 0xde, 0xef, 0xbd, 0x21, 0x2a, 0x0c, 0xc8,
|
||||
0x74, 0x77, 0xea, 0x52, 0x9f, 0xe2, 0x3c, 0xfb, 0x1b, 0x52, 0x5b, 0xba, 0x33, 0xb6, 0xfc, 0xe3,
|
||||
0xd9, 0x60, 0x77, 0x48, 0x27, 0x77, 0xc7, 0x74, 0x4c, 0xef, 0x32, 0xcf, 0x60, 0x36, 0x62, 0x33,
|
||||
0x36, 0x61, 0x23, 0xbe, 0x50, 0x9e, 0xa2, 0xec, 0x43, 0x62, 0xdb, 0x14, 0x6f, 0xa1, 0xa2, 0x49,
|
||||
0x9e, 0x5b, 0x43, 0xd2, 0x77, 0x8c, 0x09, 0xa9, 0xa4, 0xb6, 0x53, 0x3b, 0x05, 0x1d, 0x71, 0x93,
|
||||
0x06, 0x96, 0x00, 0x30, 0xb4, 0x2d, 0xe2, 0xf8, 0x1c, 0x90, 0xe6, 0x00, 0x6e, 0x62, 0x80, 0xdb,
|
||||
0x68, 0x25, 0x04, 0x3c, 0x27, 0xae, 0x67, 0x51, 0xa7, 0x92, 0x61, 0x98, 0x65, 0x6e, 0x3d, 0xe2,
|
||||
0x46, 0xd9, 0x43, 0xe2, 0x43, 0x62, 0x98, 0xc4, 0xc5, 0xff, 0x41, 0x82, 0x7f, 0x32, 0xe5, 0x7b,
|
||||
0xad, 0xdc, 0xbb, 0xb6, 0x1b, 0xdd, 0x61, 0xf7, 0x90, 0x78, 0x9e, 0x31, 0x26, 0x5d, 0x70, 0xea,
|
||||
0x0c, 0x82, 0x3f, 0x85, 0xcd, 0xe9, 0x64, 0xea, 0x82, 0x23, 0x08, 0x9c, 0x66, 0x2b, 0x36, 0xce,
|
||||
0xad, 0xa8, 0xc7, 0x18, 0x3d, 0xb9, 0x40, 0xae, 0xa1, 0xe5, 0xba, 0x3d, 0xf3, 0x7c, 0xe2, 0xd6,
|
||||
0xa9, 0x33, 0xb2, 0xc6, 0xf8, 0x7f, 0x28, 0x37, 0xa2, 0x36, 0x9c, 0xc2, 0x83, 0xed, 0x33, 0x3b,
|
||||
0xc5, 0x7b, 0xe5, 0x38, 0xd8, 0x3e, 0x73, 0xec, 0x09, 0xaf, 0xdf, 0x6d, 0x2d, 0xe9, 0x11, 0x4c,
|
||||
0xfe, 0x26, 0x8d, 0x44, 0xee, 0xc1, 0xeb, 0x28, 0x6d, 0x99, 0x9c, 0xa2, 0x3d, 0xf1, 0xf4, 0xdd,
|
||||
0x56, 0x5a, 0x6d, 0xe8, 0x60, 0xc1, 0x6b, 0x28, 0x6b, 0x1b, 0x03, 0x62, 0x87, 0xe4, 0xf0, 0x09,
|
||||
0xbe, 0x81, 0x0a, 0x2e, 0x5c, 0xb8, 0x4f, 0x1d, 0xfb, 0x84, 0x51, 0x92, 0xd7, 0xf3, 0x81, 0xa1,
|
||||
0x05, 0x73, 0x7c, 0x07, 0x61, 0x6b, 0xec, 0x50, 0x97, 0xf4, 0xa7, 0xc4, 0x9d, 0x58, 0xec, 0xb4,
|
||||
0x5e, 0x45, 0x60, 0xa8, 0x55, 0xee, 0x69, 0xc7, 0x0e, 0x7c, 0x13, 0x2d, 0x87, 0x70, 0x93, 0xd8,
|
||||
0xc4, 0x27, 0x95, 0x2c, 0x43, 0x96, 0xb8, 0xb1, 0xc1, 0x6c, 0x70, 0xb7, 0x35, 0xd3, 0xf2, 0x8c,
|
||||
0x81, 0x4d, 0xfa, 0x3e, 0x99, 0x4c, 0xfb, 0x96, 0x63, 0x92, 0x97, 0xc4, 0xab, 0x88, 0x0c, 0x8b,
|
||||
0x43, 0x5f, 0x17, 0x5c, 0x2a, 0xf7, 0x04, 0x6c, 0xf0, 0x4c, 0x7b, 0x95, 0xf2, 0x59, 0x36, 0x1a,
|
||||
0xcc, 0x11, 0xb1, 0x11, 0xc2, 0xe4, 0xef, 0x81, 0x0d, 0xee, 0x49, 0xb0, 0x51, 0x5a, 0x60, 0x03,
|
||||
0x23, 0x21, 0xa1, 0x14, 0x36, 0xc6, 0x1b, 0xa8, 0x60, 0x98, 0x66, 0x90, 0x15, 0xd8, 0x2a, 0x03,
|
||||
0x5b, 0x15, 0xf4, 0xd8, 0x80, 0x1f, 0x2c, 0x66, 0x59, 0x38, 0xab, 0x8b, 0xcb, 0xd2, 0x1b, 0x50,
|
||||
0x3c, 0x24, 0x6e, 0xa8, 0xcc, 0x2c, 0xdb, 0x2f, 0x1f, 0x18, 0x98, 0x2e, 0xff, 0x85, 0x4a, 0x13,
|
||||
0xe3, 0x65, 0xdf, 0x23, 0x5f, 0xce, 0x88, 0x33, 0x24, 0x8c, 0x86, 0x8c, 0x5e, 0x04, 0x5b, 0x27,
|
||||
0x34, 0xe1, 0x4d, 0x84, 0x2c, 0xc7, 0x77, 0xa9, 0x39, 0x83, 0x55, 0x95, 0x1c, 0xe3, 0x29, 0x61,
|
||||
0xc1, 0x1f, 0xa2, 0x3c, 0x23, 0xb1, 0x0f, 0x17, 0xcd, 0x83, 0x57, 0xd8, 0x93, 0x02, 0x3a, 0x7e,
|
||||
0x7a, 0xb7, 0x95, 0x63, 0x14, 0xaa, 0x8d, 0xd3, 0x78, 0xa8, 0xe7, 0x18, 0x56, 0x35, 0xe5, 0x16,
|
||||
0xca, 0x32, 0x1b, 0x50, 0x24, 0x72, 0x19, 0x85, 0x75, 0x15, 0xce, 0xf0, 0x2e, 0xca, 0x8e, 0x2c,
|
||||
0x1b, 0xa8, 0x48, 0x33, 0xd6, 0x71, 0x42, 0x83, 0x60, 0x56, 0x9d, 0x11, 0x0d, 0x79, 0xe7, 0x30,
|
||||
0xb9, 0x87, 0x8a, 0x2c, 0x60, 0x6f, 0x6a, 0x1a, 0x3e, 0xf9, 0xdb, 0xc2, 0xfe, 0x91, 0x46, 0xf9,
|
||||
0xc8, 0x33, 0x4f, 0x5b, 0x2a, 0x91, 0xb6, 0x6a, 0x58, 0xa9, 0xbc, 0xee, 0xd6, 0xcf, 0xc7, 0x4b,
|
||||
0x94, 0x2a, 0xac, 0xf7, 0xac, 0xaf, 0x08, 0x53, 0x7a, 0x46, 0x67, 0x63, 0xbc, 0x8d, 0x8a, 0x67,
|
||||
0xe5, 0xbd, 0xac, 0x27, 0x4d, 0x58, 0x42, 0xf9, 0x09, 0x35, 0xad, 0x91, 0x45, 0x4c, 0x96, 0xc0,
|
||||
0x8c, 0x3e, 0x9f, 0xe3, 0x4a, 0xa0, 0xce, 0x40, 0xd9, 0x66, 0x28, 0xe1, 0x68, 0x1a, 0x78, 0x2c,
|
||||
0xe7, 0xb9, 0x61, 0x43, 0x5a, 0x78, 0xd2, 0xa2, 0x69, 0xd0, 0x8c, 0x1c, 0xba, 0x50, 0x53, 0x79,
|
||||
0x06, 0x58, 0x76, 0x68, 0xb2, 0x9e, 0x40, 0xf8, 0x51, 0xb3, 0x2a, 0x80, 0x7f, 0x41, 0xf8, 0x47,
|
||||
0x64, 0xe8, 0xd3, 0x79, 0x1b, 0x08, 0x61, 0xc1, 0x41, 0xe7, 0x4a, 0x42, 0xfc, 0xa0, 0xd1, 0x1c,
|
||||
0xff, 0x1f, 0x89, 0x7b, 0x36, 0x1d, 0x3e, 0x8b, 0xaa, 0xe8, 0x6a, 0x1c, 0x8c, 0xd9, 0x13, 0xcc,
|
||||
0x8b, 0x03, 0x06, 0xfc, 0x58, 0xf8, 0xf6, 0xd5, 0xd6, 0x92, 0xfc, 0x18, 0x15, 0xe6, 0x80, 0x20,
|
||||
0xab, 0x74, 0x34, 0xf2, 0x88, 0xcf, 0x52, 0x90, 0xd1, 0xc3, 0xd9, 0x9c, 0xd8, 0x20, 0x09, 0xd9,
|
||||
0x90, 0x58, 0xb0, 0x1d, 0x1b, 0xde, 0x31, 0x23, 0xbb, 0xa4, 0xb3, 0x71, 0x18, 0xf2, 0x13, 0x24,
|
||||
0xf2, 0x0b, 0xe0, 0xfb, 0x28, 0x3f, 0xa4, 0x33, 0xc7, 0x8f, 0x7b, 0xdd, 0x6a, 0xb2, 0xa4, 0x98,
|
||||
0x27, 0x3c, 0xd5, 0x1c, 0x28, 0xef, 0xa3, 0x5c, 0xe8, 0x02, 0x2a, 0xa3, 0xfa, 0x16, 0xf6, 0xae,
|
||||
0x45, 0xb2, 0xef, 0x1c, 0x53, 0xd7, 0x67, 0xb2, 0x4f, 0x34, 0x3f, 0xa0, 0x7e, 0xc6, 0xcf, 0x27,
|
||||
0xe8, 0x7c, 0x22, 0xff, 0x98, 0x42, 0x39, 0x3d, 0xe0, 0xc7, 0xf3, 0x13, 0x8d, 0x22, 0xbb, 0xd0,
|
||||
0x28, 0x62, 0x19, 0xa7, 0x17, 0x64, 0x1c, 0x29, 0x31, 0x93, 0x50, 0x62, 0x4c, 0x8e, 0x70, 0x21,
|
||||
0x39, 0xd9, 0x0b, 0xc8, 0x11, 0x63, 0x72, 0x02, 0x5d, 0x8c, 0x5c, 0x3a, 0x61, 0x8d, 0x91, 0xba,
|
||||
0x86, 0x7b, 0x12, 0x0a, 0x67, 0x39, 0xb0, 0x76, 0x23, 0xa3, 0xdc, 0x47, 0x79, 0x9d, 0x78, 0x53,
|
||||
0x90, 0x08, 0xb9, 0xf4, 0xd8, 0x10, 0x1e, 0xaa, 0xd0, 0x60, 0x87, 0x86, 0xf0, 0xc1, 0x18, 0xff,
|
||||
0x1b, 0x09, 0x43, 0x6a, 0xf2, 0x23, 0xaf, 0x24, 0xf3, 0xaf, 0xb8, 0x2e, 0x85, 0xb7, 0xc7, 0x84,
|
||||
0x2a, 0x09, 0x00, 0xf0, 0xee, 0x96, 0x1b, 0xf4, 0x85, 0x63, 0x53, 0xc3, 0x6c, 0xbb, 0x74, 0x1c,
|
||||
0x34, 0xb2, 0x4b, 0xcb, 0xb9, 0x81, 0x72, 0x33, 0x56, 0xf0, 0x51, 0x41, 0xdf, 0x5a, 0x2c, 0xc0,
|
||||
0xb3, 0x81, 0x78, 0x77, 0x88, 0x84, 0x1b, 0x2e, 0x95, 0xdf, 0xa6, 0x90, 0x74, 0x39, 0x1a, 0xab,
|
||||
0xa8, 0xc8, 0x91, 0xfd, 0xc4, 0x9b, 0xbc, 0xf3, 0x3e, 0x1b, 0xb1, 0xda, 0x47, 0xb3, 0xf9, 0xf8,
|
||||
0xc2, 0xc6, 0x9f, 0x28, 0xb4, 0xcc, 0xfb, 0x15, 0x1a, 0x3c, 0x75, 0xac, 0x46, 0xe6, 0xcf, 0x97,
|
||||
0x00, 0x77, 0xcf, 0xea, 0xa5, 0x01, 0x2f, 0x14, 0x66, 0x93, 0x45, 0x24, 0xb4, 0x2d, 0x67, 0x2c,
|
||||
0x6f, 0xa1, 0x6c, 0xdd, 0xa6, 0x2c, 0x59, 0x22, 0xbc, 0xad, 0x1e, 0x6c, 0x13, 0x72, 0xc8, 0x67,
|
||||
0xd5, 0xb7, 0x69, 0x54, 0x4c, 0x7c, 0x56, 0xc0, 0x79, 0x56, 0xea, 0xcd, 0x5e, 0xa7, 0xab, 0xe8,
|
||||
0xfd, 0x7a, 0x4b, 0xdb, 0x57, 0x0f, 0xca, 0x4b, 0xd2, 0xc6, 0xd7, 0xdf, 0x6d, 0x57, 0x26, 0x31,
|
||||
0x68, 0xf1, 0x8b, 0x01, 0xb6, 0x50, 0xb5, 0x86, 0xf2, 0x59, 0x39, 0x25, 0xad, 0x01, 0xb0, 0x9c,
|
||||
0x00, 0xf2, 0x26, 0xff, 0x5f, 0x54, 0x62, 0x80, 0x7e, 0xaf, 0xdd, 0xa8, 0x75, 0x95, 0x72, 0x5a,
|
||||
0x92, 0x00, 0xb7, 0x7e, 0x16, 0x17, 0xf2, 0x7d, 0x13, 0xea, 0x42, 0x79, 0xdc, 0x53, 0x3a, 0xdd,
|
||||
0x72, 0x46, 0x5a, 0x07, 0x20, 0x4e, 0x00, 0xa3, 0x8a, 0xb9, 0x0d, 0x32, 0x54, 0x3a, 0xed, 0x96,
|
||||
0xd6, 0x51, 0xca, 0x82, 0x74, 0x1d, 0x50, 0x57, 0x17, 0x50, 0xa1, 0x42, 0x3f, 0x42, 0xab, 0x8d,
|
||||
0xd6, 0x13, 0xad, 0xd9, 0xaa, 0x35, 0xfa, 0x6d, 0xbd, 0x75, 0x00, 0x6b, 0x3a, 0xe5, 0xac, 0xb4,
|
||||
0x05, 0xf8, 0x1b, 0x09, 0xfc, 0x39, 0xc1, 0xfd, 0x13, 0xd8, 0x53, 0xb5, 0x83, 0xb2, 0x28, 0x5d,
|
||||
0x05, 0xe8, 0x95, 0x04, 0x34, 0x20, 0x35, 0xb8, 0x71, 0xbd, 0xd9, 0x82, 0xad, 0x73, 0xe7, 0x6e,
|
||||
0xcc, 0xc8, 0xae, 0x7e, 0x81, 0xf0, 0xf9, 0x0f, 0x2f, 0x7c, 0x0b, 0x09, 0x5a, 0x4b, 0x53, 0x80,
|
||||
0x50, 0x76, 0xff, 0xf3, 0x08, 0x8d, 0x3a, 0x04, 0xcb, 0x28, 0xd3, 0xfc, 0xfc, 0x03, 0x20, 0xf3,
|
||||
0x1f, 0x00, 0xba, 0x76, 0x1e, 0x04, 0xce, 0x2a, 0x45, 0xc5, 0x64, 0x60, 0x19, 0xe5, 0x0f, 0x95,
|
||||
0x6e, 0x0d, 0xc8, 0xad, 0x41, 0x70, 0x76, 0xa4, 0xc8, 0x7d, 0x48, 0x7c, 0x83, 0x15, 0xe0, 0x06,
|
||||
0xca, 0x6a, 0xca, 0x91, 0xa2, 0x43, 0xe0, 0x55, 0x00, 0x2c, 0x47, 0x00, 0x8d, 0x80, 0xae, 0xe0,
|
||||
0x9d, 0x17, 0x6b, 0xcd, 0x27, 0xb5, 0xa7, 0x1d, 0x48, 0x0e, 0x06, 0xf7, 0x4a, 0xe4, 0xae, 0xd9,
|
||||
0x2f, 0x8c, 0x13, 0xaf, 0xfa, 0x7b, 0x0a, 0x95, 0x92, 0x4f, 0x1a, 0x2c, 0x10, 0xf6, 0xd5, 0xa6,
|
||||
0x12, 0x6d, 0x97, 0xf4, 0x05, 0x63, 0xbc, 0x83, 0x0a, 0x0d, 0x55, 0x57, 0xea, 0xdd, 0x96, 0xfe,
|
||||
0x34, 0xba, 0x4b, 0x12, 0xd4, 0xb0, 0x5c, 0x26, 0xee, 0xe0, 0x43, 0xaf, 0xd4, 0x79, 0x7a, 0xd8,
|
||||
0x54, 0xb5, 0x47, 0x7d, 0x16, 0x31, 0x2d, 0xdd, 0x00, 0xf0, 0xf5, 0x24, 0xb8, 0x73, 0x32, 0xb1,
|
||||
0x2d, 0xe7, 0x19, 0x0b, 0xfc, 0x00, 0xad, 0x46, 0xf0, 0x78, 0x83, 0x8c, 0xb4, 0x0d, 0x6b, 0x36,
|
||||
0x2e, 0x58, 0x13, 0xef, 0x73, 0x1f, 0x5d, 0x89, 0x16, 0xf6, 0xb4, 0x47, 0x1a, 0xc8, 0x02, 0x94,
|
||||
0xb3, 0x09, 0xcb, 0xa4, 0x0b, 0x96, 0xf5, 0x9c, 0x67, 0x0e, 0x88, 0xa2, 0xfa, 0x43, 0x0a, 0x15,
|
||||
0xe6, 0x1d, 0x2a, 0xe0, 0x59, 0x6b, 0xf5, 0x15, 0x5d, 0x6f, 0xe9, 0xd1, 0xc5, 0xe7, 0x4e, 0x8d,
|
||||
0xb2, 0x21, 0x7c, 0x54, 0xe5, 0x0e, 0x14, 0x4d, 0xd1, 0xd5, 0x7a, 0x54, 0x0f, 0x73, 0xc8, 0x01,
|
||||
0x71, 0x88, 0x6b, 0x0d, 0xe1, 0xf3, 0xbe, 0x04, 0x61, 0x3a, 0xbd, 0xfa, 0xc3, 0xe8, 0xc6, 0x4c,
|
||||
0xc0, 0x89, 0x50, 0x9d, 0xd9, 0xf0, 0x98, 0xdd, 0xb6, 0x1a, 0x94, 0xce, 0x51, 0xad, 0xa9, 0x36,
|
||||
0x38, 0x34, 0x23, 0x55, 0x00, 0xba, 0x36, 0x87, 0xaa, 0xfc, 0x55, 0x0f, 0xb0, 0x55, 0x13, 0x6d,
|
||||
0xfe, 0x75, 0x2f, 0x82, 0xaf, 0x0d, 0xb1, 0xd6, 0x6e, 0x2b, 0x5a, 0x23, 0x3a, 0x7d, 0xec, 0xab,
|
||||
0x4d, 0xa7, 0xc4, 0x31, 0x03, 0xc4, 0x7e, 0x4b, 0x3f, 0x50, 0xba, 0xd1, 0xe1, 0x63, 0xc4, 0x3e,
|
||||
0x75, 0xc7, 0xc4, 0xdf, 0xdb, 0x78, 0xfd, 0xcb, 0xe6, 0xd2, 0x1b, 0xf8, 0xbd, 0x3e, 0xdd, 0x4c,
|
||||
0xbd, 0x81, 0xdf, 0xcf, 0xa7, 0x9b, 0x4b, 0xbf, 0xc1, 0xff, 0xab, 0x5f, 0x37, 0x53, 0x03, 0x91,
|
||||
0xf5, 0xae, 0xfb, 0x7f, 0x06, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x49, 0x51, 0xc5, 0x82, 0x0d, 0x00,
|
||||
0x00,
|
||||
}
|
||||
|
@ -63,14 +63,14 @@ message Folder {
|
||||
}
|
||||
|
||||
message Device {
|
||||
bytes id = 1 [(gogoproto.customname) = "ID"];
|
||||
string name = 2;
|
||||
repeated string addresses = 3;
|
||||
Compression compression = 4;
|
||||
string cert_name = 5;
|
||||
int64 max_local_version = 6;
|
||||
bool introducer = 7;
|
||||
uint64 index_id = 8 [(gogoproto.customname) = "IndexID", (gogoproto.customtype) = "IndexID", (gogoproto.nullable) = false];
|
||||
bytes id = 1 [(gogoproto.customname) = "ID"];
|
||||
string name = 2;
|
||||
repeated string addresses = 3;
|
||||
Compression compression = 4;
|
||||
string cert_name = 5;
|
||||
int64 max_sequence = 6;
|
||||
bool introducer = 7;
|
||||
uint64 index_id = 8 [(gogoproto.customname) = "IndexID", (gogoproto.customtype) = "IndexID", (gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
enum Compression {
|
||||
@ -102,7 +102,7 @@ message FileInfo {
|
||||
bool invalid = 7;
|
||||
bool no_permissions = 8;
|
||||
Vector version = 9 [(gogoproto.nullable) = false];
|
||||
int64 local_version = 10;
|
||||
int64 sequence = 10;
|
||||
|
||||
repeated BlockInfo Blocks = 16 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
@ -25,8 +25,8 @@ func (m Hello) Magic() uint32 {
|
||||
}
|
||||
|
||||
func (f FileInfo) String() string {
|
||||
return fmt.Sprintf("File{Name:%q, Type:%v, LocalVersion:%d, Permissions:0%o, Modified:%d, Version:%v, Length:%d, Deleted:%v, Invalid:%v, NoPermissions:%v, Blocks:%v}",
|
||||
f.Name, f.Type, f.LocalVersion, f.Permissions, f.Modified, f.Version, f.Size, f.Deleted, f.Invalid, f.NoPermissions, f.Blocks)
|
||||
return fmt.Sprintf("File{Name:%q, Type:%v, Sequence:%d, Permissions:0%o, Modified:%d, Version:%v, Length:%d, Deleted:%v, Invalid:%v, NoPermissions:%v, Blocks:%v}",
|
||||
f.Name, f.Type, f.Sequence, f.Permissions, f.Modified, f.Version, f.Size, f.Deleted, f.Invalid, f.NoPermissions, f.Blocks)
|
||||
}
|
||||
|
||||
func (f FileInfo) IsDeleted() bool {
|
||||
|
26
lib/rc/rc.go
26
lib/rc/rc.go
@ -46,7 +46,7 @@ type Process struct {
|
||||
startComplete bool
|
||||
startCompleteCond *stdsync.Cond
|
||||
stop bool
|
||||
localVersion map[string]map[string]int64 // Folder ID => Device ID => LocalVersion
|
||||
sequence map[string]map[string]int64 // Folder ID => Device ID => Sequence
|
||||
done map[string]bool // Folder ID => 100%
|
||||
|
||||
cmd *exec.Cmd
|
||||
@ -57,10 +57,10 @@ type Process struct {
|
||||
// Example: NewProcess("127.0.0.1:8082")
|
||||
func NewProcess(addr string) *Process {
|
||||
p := &Process{
|
||||
addr: addr,
|
||||
localVersion: make(map[string]map[string]int64),
|
||||
done: make(map[string]bool),
|
||||
eventMut: sync.NewMutex(),
|
||||
addr: addr,
|
||||
sequence: make(map[string]map[string]int64),
|
||||
done: make(map[string]bool),
|
||||
eventMut: sync.NewMutex(),
|
||||
}
|
||||
p.startCompleteCond = stdsync.NewCond(p.eventMut)
|
||||
return p
|
||||
@ -308,16 +308,16 @@ func InSync(folder string, ps ...*Process) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check LocalVersion for each device. The local version seen by remote
|
||||
// Check Sequence for each device. The local version seen by remote
|
||||
// devices should be the same as what it has locally, or the index
|
||||
// hasn't been sent yet.
|
||||
|
||||
sourceID := ps[i].id.String()
|
||||
sourceVersion := ps[i].localVersion[folder][sourceID]
|
||||
sourceSeq := ps[i].sequence[folder][sourceID]
|
||||
for j := range ps {
|
||||
if i != j {
|
||||
remoteVersion := ps[j].localVersion[folder][sourceID]
|
||||
if remoteVersion != sourceVersion {
|
||||
remoteSeq := ps[j].sequence[folder][sourceID]
|
||||
if remoteSeq != sourceSeq {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -510,12 +510,12 @@ func (p *Process) eventLoop() {
|
||||
folder := data["folder"].(string)
|
||||
version, _ := data["version"].(json.Number).Int64()
|
||||
p.eventMut.Lock()
|
||||
m := p.localVersion[folder]
|
||||
m := p.sequence[folder]
|
||||
if m == nil {
|
||||
m = make(map[string]int64)
|
||||
}
|
||||
m[p.id.String()] = version
|
||||
p.localVersion[folder] = m
|
||||
p.sequence[folder] = m
|
||||
p.done[folder] = false
|
||||
l.Debugf("LocalIndexUpdated %v %v done=false\n\t%+v", p.id, folder, m)
|
||||
p.eventMut.Unlock()
|
||||
@ -526,12 +526,12 @@ func (p *Process) eventLoop() {
|
||||
folder := data["folder"].(string)
|
||||
version, _ := data["version"].(json.Number).Int64()
|
||||
p.eventMut.Lock()
|
||||
m := p.localVersion[folder]
|
||||
m := p.sequence[folder]
|
||||
if m == nil {
|
||||
m = make(map[string]int64)
|
||||
}
|
||||
m[device] = version
|
||||
p.localVersion[folder] = m
|
||||
p.sequence[folder] = m
|
||||
p.done[folder] = false
|
||||
l.Debugf("RemoteIndexUpdated %v %v done=false\n\t%+v", p.id, folder, m)
|
||||
p.eventMut.Unlock()
|
||||
|
Loading…
Reference in New Issue
Block a user