mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-09 23:00:58 +00:00
Keep LocalSize data in RAM
This commit is contained in:
parent
8c26fe44c3
commit
d4f81e8791
@ -167,6 +167,10 @@ func globalKeyFolder(key []byte) []byte {
|
|||||||
return folder[:izero]
|
return folder[:izero]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isLocalDevice(dev []byte) bool {
|
||||||
|
return bytes.Equal(dev, protocol.LocalDeviceID[:])
|
||||||
|
}
|
||||||
|
|
||||||
type deletionHandler func(db dbReader, batch dbWriter, folder, device, name []byte, dbi iterator.Iterator) int64
|
type deletionHandler func(db dbReader, batch dbWriter, folder, device, name []byte, dbi iterator.Iterator) int64
|
||||||
|
|
||||||
func ldbGenericReplace(db *leveldb.DB, folder, device []byte, fs []protocol.FileInfo, deleteFn deletionHandler) int64 {
|
func ldbGenericReplace(db *leveldb.DB, folder, device []byte, fs []protocol.FileInfo, deleteFn deletionHandler) int64 {
|
||||||
@ -297,7 +301,7 @@ func ldbReplace(db *leveldb.DB, folder, device []byte, fs []protocol.FileInfo) i
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func ldbUpdate(db *leveldb.DB, folder, device []byte, fs []protocol.FileInfo) int64 {
|
func ldbUpdate(db *leveldb.DB, folder, device []byte, fs []protocol.FileInfo, size *sizeTracker) int64 {
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
|
|
||||||
batch := new(leveldb.Batch)
|
batch := new(leveldb.Batch)
|
||||||
@ -314,12 +318,17 @@ func ldbUpdate(db *leveldb.DB, folder, device []byte, fs []protocol.FileInfo) in
|
|||||||
|
|
||||||
var maxLocalVer int64
|
var maxLocalVer int64
|
||||||
var fk []byte
|
var fk []byte
|
||||||
|
localDev := isLocalDevice(device)
|
||||||
for _, f := range fs {
|
for _, f := range fs {
|
||||||
name := []byte(f.Name)
|
name := []byte(f.Name)
|
||||||
fk = deviceKeyInto(fk[:cap(fk)], folder, device, name)
|
fk = deviceKeyInto(fk[:cap(fk)], folder, device, name)
|
||||||
l.Debugf("snap.Get %p %x", snap, fk)
|
l.Debugf("snap.Get %p %x", snap, fk)
|
||||||
bs, err := snap.Get(fk, nil)
|
bs, err := snap.Get(fk, nil)
|
||||||
if err == leveldb.ErrNotFound {
|
if err == leveldb.ErrNotFound {
|
||||||
|
if localDev {
|
||||||
|
size.addFile(f)
|
||||||
|
}
|
||||||
|
|
||||||
if lv := ldbInsert(batch, folder, device, f); lv > maxLocalVer {
|
if lv := ldbInsert(batch, folder, device, f); lv > maxLocalVer {
|
||||||
maxLocalVer = lv
|
maxLocalVer = lv
|
||||||
}
|
}
|
||||||
@ -339,6 +348,11 @@ func ldbUpdate(db *leveldb.DB, folder, device []byte, fs []protocol.FileInfo) in
|
|||||||
// Flags might change without the version being bumped when we set the
|
// Flags might change without the version being bumped when we set the
|
||||||
// invalid flag on an existing file.
|
// invalid flag on an existing file.
|
||||||
if !ef.Version.Equal(f.Version) || ef.Flags != f.Flags {
|
if !ef.Version.Equal(f.Version) || ef.Flags != f.Flags {
|
||||||
|
if localDev {
|
||||||
|
size.removeFile(ef)
|
||||||
|
size.addFile(f)
|
||||||
|
}
|
||||||
|
|
||||||
if lv := ldbInsert(batch, folder, device, f); lv > maxLocalVer {
|
if lv := ldbInsert(batch, folder, device, f); lv > maxLocalVer {
|
||||||
maxLocalVer = lv
|
maxLocalVer = lv
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
stdsync "sync"
|
||||||
|
|
||||||
"github.com/syncthing/syncthing/lib/osutil"
|
"github.com/syncthing/syncthing/lib/osutil"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
@ -25,6 +27,7 @@ type FileSet struct {
|
|||||||
folder string
|
folder string
|
||||||
db *leveldb.DB
|
db *leveldb.DB
|
||||||
blockmap *BlockMap
|
blockmap *BlockMap
|
||||||
|
sizeTracker
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileIntf is the set of methods implemented by both protocol.FileInfo and
|
// FileIntf is the set of methods implemented by both protocol.FileInfo and
|
||||||
@ -43,6 +46,47 @@ type FileIntf interface {
|
|||||||
// continue iteration, false to stop.
|
// continue iteration, false to stop.
|
||||||
type Iterator func(f FileIntf) bool
|
type Iterator func(f FileIntf) bool
|
||||||
|
|
||||||
|
type sizeTracker struct {
|
||||||
|
files int
|
||||||
|
deleted int
|
||||||
|
bytes int64
|
||||||
|
mut stdsync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sizeTracker) addFile(f FileIntf) {
|
||||||
|
if f.IsInvalid() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.mut.Lock()
|
||||||
|
if f.IsDeleted() {
|
||||||
|
s.deleted++
|
||||||
|
} else {
|
||||||
|
s.files++
|
||||||
|
}
|
||||||
|
s.bytes += f.Size()
|
||||||
|
s.mut.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sizeTracker) removeFile(f FileIntf) {
|
||||||
|
if f.IsInvalid() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.mut.Lock()
|
||||||
|
if f.IsDeleted() {
|
||||||
|
s.deleted--
|
||||||
|
} else {
|
||||||
|
s.files--
|
||||||
|
}
|
||||||
|
s.bytes -= f.Size()
|
||||||
|
s.mut.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sizeTracker) Size() (files, deleted int, bytes int64) {
|
||||||
|
s.mut.Lock()
|
||||||
|
defer s.mut.Unlock()
|
||||||
|
return s.files, s.deleted, s.bytes
|
||||||
|
}
|
||||||
|
|
||||||
func NewFileSet(folder string, db *leveldb.DB) *FileSet {
|
func NewFileSet(folder string, db *leveldb.DB) *FileSet {
|
||||||
var s = FileSet{
|
var s = FileSet{
|
||||||
localVersion: make(map[protocol.DeviceID]int64),
|
localVersion: make(map[protocol.DeviceID]int64),
|
||||||
@ -60,6 +104,9 @@ func NewFileSet(folder string, db *leveldb.DB) *FileSet {
|
|||||||
if f.LocalVersion > s.localVersion[deviceID] {
|
if f.LocalVersion > s.localVersion[deviceID] {
|
||||||
s.localVersion[deviceID] = f.LocalVersion
|
s.localVersion[deviceID] = f.LocalVersion
|
||||||
}
|
}
|
||||||
|
if deviceID == protocol.LocalDeviceID {
|
||||||
|
s.addFile(f)
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
l.Debugf("loaded localVersion for %q: %#v", folder, s.localVersion)
|
l.Debugf("loaded localVersion for %q: %#v", folder, s.localVersion)
|
||||||
@ -102,7 +149,7 @@ func (s *FileSet) Update(device protocol.DeviceID, fs []protocol.FileInfo) {
|
|||||||
s.blockmap.Discard(discards)
|
s.blockmap.Discard(discards)
|
||||||
s.blockmap.Update(updates)
|
s.blockmap.Update(updates)
|
||||||
}
|
}
|
||||||
if lv := ldbUpdate(s.db, []byte(s.folder), device[:], fs); lv > s.localVersion[device] {
|
if lv := ldbUpdate(s.db, []byte(s.folder), device[:], fs, &s.sizeTracker); lv > s.localVersion[device] {
|
||||||
s.localVersion[device] = lv
|
s.localVersion[device] = lv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -406,16 +406,7 @@ func (m *Model) LocalSize(folder string) (nfiles, deleted int, bytes int64) {
|
|||||||
m.fmut.RLock()
|
m.fmut.RLock()
|
||||||
defer m.fmut.RUnlock()
|
defer m.fmut.RUnlock()
|
||||||
if rf, ok := m.folderFiles[folder]; ok {
|
if rf, ok := m.folderFiles[folder]; ok {
|
||||||
rf.WithHaveTruncated(protocol.LocalDeviceID, func(f db.FileIntf) bool {
|
nfiles, deleted, bytes = rf.Size()
|
||||||
if f.IsInvalid() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
fs, de, by := sizeOfFile(f)
|
|
||||||
nfiles += fs
|
|
||||||
deleted += de
|
|
||||||
bytes += by
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user