set.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Copyright (C) 2014 Jakob Borg and other contributors. All rights reserved.
  2. // Use of this source code is governed by an MIT-style license that can be
  3. // 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/calmh/syncthing/scanner"
  10. "github.com/syndtr/goleveldb/leveldb"
  11. )
  12. type fileRecord struct {
  13. File scanner.File
  14. Usage int
  15. Global bool
  16. }
  17. type bitset uint64
  18. type Set struct {
  19. changes 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. changes: make(map[protocol.NodeID]uint64),
  27. repo: repo,
  28. db: db,
  29. }
  30. return &s
  31. }
  32. func (s *Set) Replace(node protocol.NodeID, fs []scanner.File) {
  33. if debug {
  34. l.Debugf("%s Replace(%v, [%d])", s.repo, node, len(fs))
  35. }
  36. s.mutex.Lock()
  37. defer s.mutex.Unlock()
  38. if ldbReplace(s.db, []byte(s.repo), node[:], fs) {
  39. s.changes[node]++
  40. }
  41. }
  42. func (s *Set) ReplaceWithDelete(node protocol.NodeID, fs []scanner.File) {
  43. if debug {
  44. l.Debugf("%s ReplaceWithDelete(%v, [%d])", s.repo, node, len(fs))
  45. }
  46. s.mutex.Lock()
  47. defer s.mutex.Unlock()
  48. if ldbReplaceWithDelete(s.db, []byte(s.repo), node[:], fs) {
  49. s.changes[node]++
  50. }
  51. }
  52. func (s *Set) Update(node protocol.NodeID, fs []scanner.File) {
  53. if debug {
  54. l.Debugf("%s Update(%v, [%d])", s.repo, node, len(fs))
  55. }
  56. s.mutex.Lock()
  57. defer s.mutex.Unlock()
  58. if ldbUpdate(s.db, []byte(s.repo), node[:], fs) {
  59. s.changes[node]++
  60. }
  61. }
  62. func (s *Set) WithNeed(node protocol.NodeID, fn fileIterator) {
  63. if debug {
  64. l.Debugf("%s Need(%v)", s.repo, node)
  65. }
  66. ldbWithNeed(s.db, []byte(s.repo), node[:], fn)
  67. }
  68. func (s *Set) WithHave(node protocol.NodeID, fn fileIterator) {
  69. if debug {
  70. l.Debugf("%s WithHave(%v)", s.repo, node)
  71. }
  72. ldbWithHave(s.db, []byte(s.repo), node[:], fn)
  73. }
  74. func (s *Set) WithGlobal(fn fileIterator) {
  75. if debug {
  76. l.Debugf("%s WithGlobal()", s.repo)
  77. }
  78. ldbWithGlobal(s.db, []byte(s.repo), fn)
  79. }
  80. func (s *Set) Get(node protocol.NodeID, file string) scanner.File {
  81. return ldbGet(s.db, []byte(s.repo), node[:], []byte(file))
  82. }
  83. func (s *Set) GetGlobal(file string) scanner.File {
  84. return ldbGetGlobal(s.db, []byte(s.repo), []byte(file))
  85. }
  86. func (s *Set) Availability(file string) []protocol.NodeID {
  87. return ldbAvailability(s.db, []byte(s.repo), []byte(file))
  88. }
  89. func (s *Set) Changes(node protocol.NodeID) uint64 {
  90. s.mutex.Lock()
  91. defer s.mutex.Unlock()
  92. return s.changes[node]
  93. }