ledger.go 2.04 KB
Newer Older
1
package decision
2 3

import (
Jeromy's avatar
Jeromy committed
4
	"sync"
5 6
	"time"

7
	key "github.com/ipfs/go-ipfs/blocks/key"
8
	wl "github.com/ipfs/go-ipfs/exchange/bitswap/wantlist"
Jeromy's avatar
Jeromy committed
9
	peer "gx/ipfs/QmWtbQU15LaB5B1JC2F7TV9P4K88vD3PpA4AJrwfCjhML8/go-libp2p-peer"
10 11 12 13
)

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

16
func newLedger(p peer.ID) *ledger {
17
	return &ledger{
18
		wantList:   wl.New(),
19
		Partner:    p,
20
		sentToPeer: make(map[key.Key]time.Time),
21 22 23 24
	}
}

// ledger stores the data exchange relationship between two peers.
25
// NOT threadsafe
26 27
type ledger struct {
	// Partner is the remote Peer.
28
	Partner peer.ID
29 30 31 32 33 34 35 36 37 38 39 40 41 42

	// Accounting tracks bytes sent and recieved.
	Accounting debtRatio

	// firstExchnage is the time of the first data exchange.
	firstExchange time.Time

	// lastExchange is the time of the last data exchange.
	lastExchange time.Time

	// exchangeCount is the number of exchanges with this peer
	exchangeCount uint64

	// wantList is a (bounded, small) set of keys that Partner desires.
Jeromy's avatar
Jeromy committed
43
	wantList *wl.Wantlist
44

45 46
	// sentToPeer is a set of keys to ensure we dont send duplicate blocks
	// to a given peer
47
	sentToPeer map[key.Key]time.Time
Jeromy's avatar
Jeromy committed
48 49

	lk sync.Mutex
50 51
}

52 53 54 55 56 57 58 59
type Receipt struct {
	Peer      string
	Value     float64
	Sent      uint64
	Recv      uint64
	Exchanged uint64
}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
60 61 62 63 64 65 66 67 68
type debtRatio struct {
	BytesSent uint64
	BytesRecv uint64
}

func (dr *debtRatio) Value() float64 {
	return float64(dr.BytesSent) / float64(dr.BytesRecv+1)
}

69 70 71 72 73 74 75 76 77 78 79 80
func (l *ledger) SentBytes(n int) {
	l.exchangeCount++
	l.lastExchange = time.Now()
	l.Accounting.BytesSent += uint64(n)
}

func (l *ledger) ReceivedBytes(n int) {
	l.exchangeCount++
	l.lastExchange = time.Now()
	l.Accounting.BytesRecv += uint64(n)
}

81
func (l *ledger) Wants(k key.Key, priority int) {
82
	log.Debugf("peer %s wants %s", l.Partner, k)
83
	l.wantList.Add(k, priority)
Jeromy's avatar
Jeromy committed
84 85
}

86
func (l *ledger) CancelWant(k key.Key) {
Jeromy's avatar
Jeromy committed
87
	l.wantList.Remove(k)
88 89
}

90
func (l *ledger) WantListContains(k key.Key) (wl.Entry, bool) {
Jeromy's avatar
Jeromy committed
91
	return l.wantList.Contains(k)
92 93 94 95 96
}

func (l *ledger) ExchangeCount() uint64 {
	return l.exchangeCount
}