set.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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/protocol"
  9. "github.com/syndtr/goleveldb/leveldb"
  10. )
  11. type fileRecord struct {
  12. File protocol.FileInfo
  13. Usage int
  14. Global bool
  15. }
  16. type bitset uint64
  17. type Set struct {
  18. localVersion map[protocol.NodeID]uint64
  19. mutex sync.Mutex
  20. repo string
  21. db *leveldb.DB
  22. }
  23. func NewSet(repo string, db *leveldb.DB) *Set {
  24. var s = Set{
  25. localVersion: make(map[protocol.NodeID]uint64),
  26. repo: repo,
  27. db: db,
  28. }
  29. var lv uint64
  30. ldbWithHave(db, []byte(repo), protocol.LocalNodeID[:], func(f protocol.FileInfo) bool {
  31. if f.LocalVersion > lv {
  32. lv = f.LocalVersion
  33. }
  34. return true
  35. })
  36. s.localVersion[protocol.LocalNodeID] = lv
  37. clock(lv)
  38. return &s
  39. }
  40. func (s *Set) Replace(node protocol.NodeID, fs []protocol.FileInfo) {
  41. if debug {
  42. l.Debugf("%s Replace(%v, [%d])", s.repo, node, len(fs))
  43. }
  44. s.mutex.Lock()
  45. defer s.mutex.Unlock()
  46. if lv := ldbReplace(s.db, []byte(s.repo), node[:], fs); lv > s.localVersion[node] {
  47. s.localVersion[node] = lv
  48. }
  49. }
  50. func (s *Set) ReplaceWithDelete(node protocol.NodeID, fs []protocol.FileInfo) {
  51. if debug {
  52. l.Debugf("%s ReplaceWithDelete(%v, [%d])", s.repo, node, len(fs))
  53. }
  54. s.mutex.Lock()
  55. defer s.mutex.Unlock()
  56. if lv := ldbReplaceWithDelete(s.db, []byte(s.repo), node[:], fs); lv > s.localVersion[node] {
  57. s.localVersion[node] = lv
  58. }
  59. }
  60. func (s *Set) Update(node protocol.NodeID, fs []protocol.FileInfo) {
  61. if debug {
  62. l.Debugf("%s Update(%v, [%d])", s.repo, node, len(fs))
  63. }
  64. s.mutex.Lock()
  65. defer s.mutex.Unlock()
  66. if lv := ldbUpdate(s.db, []byte(s.repo), node[:], fs); lv > s.localVersion[node] {
  67. s.localVersion[node] = lv
  68. }
  69. }
  70. func (s *Set) WithNeed(node protocol.NodeID, fn fileIterator) {
  71. if debug {
  72. l.Debugf("%s Need(%v)", s.repo, node)
  73. }
  74. ldbWithNeed(s.db, []byte(s.repo), node[:], fn)
  75. }
  76. func (s *Set) WithHave(node protocol.NodeID, fn fileIterator) {
  77. if debug {
  78. l.Debugf("%s WithHave(%v)", s.repo, node)
  79. }
  80. ldbWithHave(s.db, []byte(s.repo), node[:], fn)
  81. }
  82. func (s *Set) WithGlobal(fn fileIterator) {
  83. if debug {
  84. l.Debugf("%s WithGlobal()", s.repo)
  85. }
  86. ldbWithGlobal(s.db, []byte(s.repo), fn)
  87. }
  88. func (s *Set) Get(node protocol.NodeID, file string) protocol.FileInfo {
  89. return ldbGet(s.db, []byte(s.repo), node[:], []byte(file))
  90. }
  91. func (s *Set) GetGlobal(file string) protocol.FileInfo {
  92. return ldbGetGlobal(s.db, []byte(s.repo), []byte(file))
  93. }
  94. func (s *Set) Availability(file string) []protocol.NodeID {
  95. return ldbAvailability(s.db, []byte(s.repo), []byte(file))
  96. }
  97. func (s *Set) LocalVersion(node protocol.NodeID) uint64 {
  98. s.mutex.Lock()
  99. defer s.mutex.Unlock()
  100. return s.localVersion[node]
  101. }