ledger.go 1.77 KB
Newer Older
1
package strategy
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
2 3

import (
4
	"sync"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
5 6
	"time"

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
7 8 9 10
	peer "github.com/jbenet/go-ipfs/peer"
	u "github.com/jbenet/go-ipfs/util"
)

11 12 13 14
// keySet is just a convenient alias for maps of keys, where we only care
// access/lookups.
type keySet map[u.Key]struct{}

15 16
func newLedger(p *peer.Peer, strategy strategyFunc) *ledger {
	return &ledger{
Brian Tiger Chow's avatar
Brian Tiger Chow committed
17
		wantList: keySet{},
18 19 20 21 22
		Strategy: strategy,
		Partner:  p,
	}
}

23 24
// ledger stores the data exchange relationship between two peers.
type ledger struct {
25
	lock sync.RWMutex
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
26

27 28
	// Partner is the remote Peer.
	Partner *peer.Peer
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
29

30 31
	// Accounting tracks bytes sent and recieved.
	Accounting debtRatio
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
32

Brian Tiger Chow's avatar
Brian Tiger Chow committed
33 34
	// firstExchnage is the time of the first data exchange.
	firstExchange time.Time
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
35

Brian Tiger Chow's avatar
Brian Tiger Chow committed
36 37
	// lastExchange is the time of the last data exchange.
	lastExchange time.Time
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
38

Brian Tiger Chow's avatar
Brian Tiger Chow committed
39 40
	// exchangeCount is the number of exchanges with this peer
	exchangeCount uint64
41

Brian Tiger Chow's avatar
Brian Tiger Chow committed
42
	// wantList is a (bounded, small) set of keys that Partner desires.
43
	wantList keySet
Jeromy's avatar
Jeromy committed
44

45
	Strategy strategyFunc
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
46 47
}

48
func (l *ledger) ShouldSend() bool {
49 50 51
	l.lock.Lock()
	defer l.lock.Unlock()

52
	return l.Strategy(l)
53 54
}

55
func (l *ledger) SentBytes(n int) {
56 57 58
	l.lock.Lock()
	defer l.lock.Unlock()

Brian Tiger Chow's avatar
Brian Tiger Chow committed
59 60
	l.exchangeCount++
	l.lastExchange = time.Now()
61
	l.Accounting.BytesSent += uint64(n)
62 63
}

64
func (l *ledger) ReceivedBytes(n int) {
65 66 67
	l.lock.Lock()
	defer l.lock.Unlock()

Brian Tiger Chow's avatar
Brian Tiger Chow committed
68 69
	l.exchangeCount++
	l.lastExchange = time.Now()
70
	l.Accounting.BytesRecv += uint64(n)
71
}
72 73

// TODO: this needs to be different. We need timeouts.
74
func (l *ledger) Wants(k u.Key) {
75 76 77
	l.lock.Lock()
	defer l.lock.Unlock()

Brian Tiger Chow's avatar
Brian Tiger Chow committed
78
	l.wantList[k] = struct{}{}
79 80
}

81
func (l *ledger) WantListContains(k u.Key) bool {
82 83 84
	l.lock.RLock()
	defer l.lock.RUnlock()

Brian Tiger Chow's avatar
Brian Tiger Chow committed
85
	_, ok := l.wantList[k]
86 87
	return ok
}
88

89
func (l *ledger) ExchangeCount() uint64 {
90 91 92 93
	l.lock.RLock()
	defer l.lock.RUnlock()
	return l.exchangeCount
}