diff --git a/files/leveldb.go b/files/leveldb.go index 6b465e19c..259556df4 100644 --- a/files/leveldb.go +++ b/files/leveldb.go @@ -103,6 +103,14 @@ func globalKey(repo, file []byte) []byte { func nodeKeyName(key []byte) []byte { return key[1+64+32:] } +func nodeKeyRepo(key []byte) []byte { + repo := key[1 : 1+64] + izero := bytes.IndexByte(repo, 0) + return repo[:izero] +} +func nodeKeyNode(key []byte) []byte { + return key[1+64 : 1+64+32] +} func globalKeyName(key []byte) []byte { return key[1+64:] @@ -405,6 +413,30 @@ func ldbWithHave(db *leveldb.DB, repo, node []byte, fn fileIterator) { } } +func ldbWithAllRepo(db *leveldb.DB, repo []byte, fn func(node []byte, f protocol.FileInfo) bool) { + start := nodeKey(repo, nil, nil) // before all repo/node files + limit := nodeKey(repo, protocol.LocalNodeID[:], []byte{0xff, 0xff, 0xff, 0xff}) // after all repo/node files + snap, err := db.GetSnapshot() + if err != nil { + panic(err) + } + defer snap.Release() + dbi := snap.NewIterator(&util.Range{Start: start, Limit: limit}, nil) + defer dbi.Release() + + for dbi.Next() { + node := nodeKeyNode(dbi.Key()) + var f protocol.FileInfo + err := f.UnmarshalXDR(dbi.Value()) + if err != nil { + panic(err) + } + if cont := fn(node, f); !cont { + return + } + } +} + func ldbGet(db *leveldb.DB, repo, node, file []byte) protocol.FileInfo { nk := nodeKey(repo, node, file) bs, err := db.Get(nk, nil) diff --git a/files/set.go b/files/set.go index 11941dd8d..3d2a708aa 100644 --- a/files/set.go +++ b/files/set.go @@ -34,15 +34,18 @@ func NewSet(repo string, db *leveldb.DB) *Set { db: db, } - var lv uint64 - ldbWithHave(db, []byte(repo), protocol.LocalNodeID[:], func(f protocol.FileInfo) bool { - if f.LocalVersion > lv { - lv = f.LocalVersion + var nodeID protocol.NodeID + ldbWithAllRepo(db, []byte(repo), func(node []byte, f protocol.FileInfo) bool { + copy(nodeID[:], node) + if f.LocalVersion > s.localVersion[nodeID] { + s.localVersion[nodeID] = f.LocalVersion } return true }) - s.localVersion[protocol.LocalNodeID] = lv - clock(lv) + if debug { + l.Debugf("loaded localVersion for %q: %#v", repo, s.localVersion) + } + clock(s.localVersion[protocol.LocalNodeID]) return &s }