set.go 2.49 KB
Newer Older
Jakob Borg's avatar
Jakob Borg committed
1 2 3 4
// Copyright (C) 2014 Jakob Borg and other contributors. All rights reserved.
// Use of this source code is governed by an MIT-style license that can be
// found in the LICENSE file.

5 6 7 8 9 10 11 12
// Package files provides a set type to track local/remote files with newness checks.
package files

import (
	"sync"

	"github.com/calmh/syncthing/protocol"
	"github.com/calmh/syncthing/scanner"
Jakob Borg's avatar
Jakob Borg committed
13
	"github.com/syndtr/goleveldb/leveldb"
14 15 16
)

type fileRecord struct {
17 18 19
	File   scanner.File
	Usage  int
	Global bool
20 21 22 23 24
}

type bitset uint64

type Set struct {
Jakob Borg's avatar
Jakob Borg committed
25
	changes map[protocol.NodeID]uint64
26
	mutex   sync.Mutex
Jakob Borg's avatar
Jakob Borg committed
27 28
	repo    string
	db      *leveldb.DB
29 30
}

Jakob Borg's avatar
Jakob Borg committed
31 32 33 34 35
func NewSet(repo string, db *leveldb.DB) *Set {
	var s = Set{
		changes: make(map[protocol.NodeID]uint64),
		repo:    repo,
		db:      db,
36
	}
Jakob Borg's avatar
Jakob Borg committed
37
	return &s
38 39
}

Jakob Borg's avatar
Jakob Borg committed
40
func (s *Set) Replace(node protocol.NodeID, fs []scanner.File) {
41
	if debug {
Jakob Borg's avatar
Jakob Borg committed
42
		l.Debugf("%s Replace(%v, [%d])", s.repo, node, len(fs))
43
	}
Jakob Borg's avatar
Jakob Borg committed
44 45 46 47
	s.mutex.Lock()
	defer s.mutex.Unlock()
	if ldbReplace(s.db, []byte(s.repo), node[:], fs) {
		s.changes[node]++
48 49 50
	}
}

Jakob Borg's avatar
Jakob Borg committed
51
func (s *Set) ReplaceWithDelete(node protocol.NodeID, fs []scanner.File) {
52
	if debug {
Jakob Borg's avatar
Jakob Borg committed
53
		l.Debugf("%s ReplaceWithDelete(%v, [%d])", s.repo, node, len(fs))
54
	}
Jakob Borg's avatar
Jakob Borg committed
55 56 57 58
	s.mutex.Lock()
	defer s.mutex.Unlock()
	if ldbReplaceWithDelete(s.db, []byte(s.repo), node[:], fs) {
		s.changes[node]++
59 60 61
	}
}

Jakob Borg's avatar
Jakob Borg committed
62
func (s *Set) Update(node protocol.NodeID, fs []scanner.File) {
63
	if debug {
Jakob Borg's avatar
Jakob Borg committed
64
		l.Debugf("%s Update(%v, [%d])", s.repo, node, len(fs))
65
	}
Jakob Borg's avatar
Jakob Borg committed
66 67 68 69
	s.mutex.Lock()
	defer s.mutex.Unlock()
	if ldbUpdate(s.db, []byte(s.repo), node[:], fs) {
		s.changes[node]++
70 71 72
	}
}

Jakob Borg's avatar
Jakob Borg committed
73
func (s *Set) WithNeed(node protocol.NodeID, fn fileIterator) {
74
	if debug {
Jakob Borg's avatar
Jakob Borg committed
75
		l.Debugf("%s Need(%v)", s.repo, node)
76
	}
Jakob Borg's avatar
Jakob Borg committed
77
	ldbWithNeed(s.db, []byte(s.repo), node[:], fn)
78 79
}

Jakob Borg's avatar
Jakob Borg committed
80
func (s *Set) WithHave(node protocol.NodeID, fn fileIterator) {
81
	if debug {
Jakob Borg's avatar
Jakob Borg committed
82
		l.Debugf("%s WithHave(%v)", s.repo, node)
83
	}
Jakob Borg's avatar
Jakob Borg committed
84
	ldbWithHave(s.db, []byte(s.repo), node[:], fn)
85 86
}

Jakob Borg's avatar
Jakob Borg committed
87
func (s *Set) WithGlobal(fn fileIterator) {
88
	if debug {
Jakob Borg's avatar
Jakob Borg committed
89
		l.Debugf("%s WithGlobal()", s.repo)
90
	}
Jakob Borg's avatar
Jakob Borg committed
91
	ldbWithGlobal(s.db, []byte(s.repo), fn)
92 93
}

Jakob Borg's avatar
Jakob Borg committed
94 95
func (s *Set) Get(node protocol.NodeID, file string) scanner.File {
	return ldbGet(s.db, []byte(s.repo), node[:], []byte(file))
96 97
}

Jakob Borg's avatar
Jakob Borg committed
98 99
func (s *Set) GetGlobal(file string) scanner.File {
	return ldbGetGlobal(s.db, []byte(s.repo), []byte(file))
100 101
}

Jakob Borg's avatar
Jakob Borg committed
102 103
func (s *Set) Availability(file string) []protocol.NodeID {
	return ldbAvailability(s.db, []byte(s.repo), []byte(file))
104 105
}

Jakob Borg's avatar
Jakob Borg committed
106
func (s *Set) Changes(node protocol.NodeID) uint64 {
107 108
	s.mutex.Lock()
	defer s.mutex.Unlock()
Jakob Borg's avatar
Jakob Borg committed
109
	return s.changes[node]
110
}