set.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
  2. // All rights reserved. Use of this source code is governed by an MIT-style
  3. // license that can be found in the LICENSE file.
  4. // Package files provides a set type to track local/remote files with newness checks.
  5. package files
  6. import (
  7. "sync"
  8. "github.com/calmh/syncthing/lamport"
  9. "github.com/calmh/syncthing/protocol"
  10. "github.com/syndtr/goleveldb/leveldb"
  11. )
  12. type fileRecord struct {
  13. File protocol.FileInfo
  14. Usage int
  15. Global bool
  16. }
  17. type bitset uint64
  18. type Set struct {
  19. localVersion map[protocol.NodeID]uint64
  20. mutex sync.Mutex
  21. repo string
  22. db *leveldb.DB
  23. }
  24. func NewSet(repo string, db *leveldb.DB) *Set {
  25. var s = Set{
  26. localVersion: make(map[protocol.NodeID]uint64),
  27. repo: repo,
  28. db: db,
  29. }
  30. var nodeID protocol.NodeID
  31. ldbWithAllRepo(db, []byte(repo), func(node []byte, f protocol.FileInfo) bool {
  32. copy(nodeID[:], node)
  33. if f.LocalVersion > s.localVersion[nodeID] {
  34. s.localVersion[nodeID] = f.LocalVersion
  35. }
  36. lamport.Default.Tick(f.Version)
  37. return true
  38. })
  39. if debug {
  40. l.Debugf("loaded localVersion for %q: %#v", repo, s.localVersion)
  41. }
  42. clock(s.localVersion[protocol.LocalNodeID])
  43. return &s
  44. }
  45. func (s *Set) Replace(node protocol.NodeID, fs []protocol.FileInfo) {
  46. if debug {
  47. l.Debugf("%s Replace(%v, [%d])", s.repo, node, len(fs))
  48. }
  49. s.mutex.Lock()
  50. defer s.mutex.Unlock()
  51. if lv := ldbReplace(s.db, []byte(s.repo), node[:], fs); lv > s.localVersion[node] {
  52. s.localVersion[node] = lv
  53. }
  54. }
  55. func (s *Set) ReplaceWithDelete(node protocol.NodeID, fs []protocol.FileInfo) {
  56. if debug {
  57. l.Debugf("%s ReplaceWithDelete(%v, [%d])", s.repo, node, len(fs))
  58. }
  59. s.mutex.Lock()
  60. defer s.mutex.Unlock()
  61. if lv := ldbReplaceWithDelete(s.db, []byte(s.repo), node[:], fs); lv > s.localVersion[node] {
  62. s.localVersion[node] = lv
  63. }
  64. }
  65. func (s *Set) Update(node protocol.NodeID, fs []protocol.FileInfo) {
  66. if debug {
  67. l.Debugf("%s Update(%v, [%d])", s.repo, node, len(fs))
  68. }
  69. s.mutex.Lock()
  70. defer s.mutex.Unlock()
  71. if lv := ldbUpdate(s.db, []byte(s.repo), node[:], fs); lv > s.localVersion[node] {
  72. s.localVersion[node] = lv
  73. }
  74. }
  75. func (s *Set) WithNeed(node protocol.NodeID, fn fileIterator) {
  76. if debug {
  77. l.Debugf("%s Need(%v)", s.repo, node)
  78. }
  79. ldbWithNeed(s.db, []byte(s.repo), node[:], fn)
  80. }
  81. func (s *Set) WithHave(node protocol.NodeID, fn fileIterator) {
  82. if debug {
  83. l.Debugf("%s WithHave(%v)", s.repo, node)
  84. }
  85. ldbWithHave(s.db, []byte(s.repo), node[:], fn)
  86. }
  87. func (s *Set) WithGlobal(fn fileIterator) {
  88. if debug {
  89. l.Debugf("%s WithGlobal()", s.repo)
  90. }
  91. ldbWithGlobal(s.db, []byte(s.repo), fn)
  92. }
  93. func (s *Set) Get(node protocol.NodeID, file string) protocol.FileInfo {
  94. return ldbGet(s.db, []byte(s.repo), node[:], []byte(file))
  95. }
  96. func (s *Set) GetGlobal(file string) protocol.FileInfo {
  97. return ldbGetGlobal(s.db, []byte(s.repo), []byte(file))
  98. }
  99. func (s *Set) Availability(file string) []protocol.NodeID {
  100. return ldbAvailability(s.db, []byte(s.repo), []byte(file))
  101. }
  102. func (s *Set) LocalVersion(node protocol.NodeID) uint64 {
  103. s.mutex.Lock()
  104. defer s.mutex.Unlock()
  105. return s.localVersion[node]
  106. }