github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/exchange/bitswap/decision/ledger.go (about)

     1  package decision
     2  
     3  import (
     4  	"time"
     5  
     6  	key "github.com/ipfs/go-ipfs/blocks/key"
     7  	wl "github.com/ipfs/go-ipfs/exchange/bitswap/wantlist"
     8  	peer "github.com/ipfs/go-ipfs/p2p/peer"
     9  )
    10  
    11  // keySet is just a convenient alias for maps of keys, where we only care
    12  // access/lookups.
    13  type keySet map[key.Key]struct{}
    14  
    15  func newLedger(p peer.ID) *ledger {
    16  	return &ledger{
    17  		wantList:   wl.New(),
    18  		Partner:    p,
    19  		sentToPeer: make(map[key.Key]time.Time),
    20  	}
    21  }
    22  
    23  // ledger stores the data exchange relationship between two peers.
    24  // NOT threadsafe
    25  type ledger struct {
    26  	// Partner is the remote Peer.
    27  	Partner peer.ID
    28  
    29  	// Accounting tracks bytes sent and recieved.
    30  	Accounting debtRatio
    31  
    32  	// firstExchnage is the time of the first data exchange.
    33  	firstExchange time.Time
    34  
    35  	// lastExchange is the time of the last data exchange.
    36  	lastExchange time.Time
    37  
    38  	// exchangeCount is the number of exchanges with this peer
    39  	exchangeCount uint64
    40  
    41  	// wantList is a (bounded, small) set of keys that Partner desires.
    42  	wantList *wl.Wantlist
    43  
    44  	// sentToPeer is a set of keys to ensure we dont send duplicate blocks
    45  	// to a given peer
    46  	sentToPeer map[key.Key]time.Time
    47  }
    48  
    49  type debtRatio struct {
    50  	BytesSent uint64
    51  	BytesRecv uint64
    52  }
    53  
    54  func (dr *debtRatio) Value() float64 {
    55  	return float64(dr.BytesSent) / float64(dr.BytesRecv+1)
    56  }
    57  
    58  func (l *ledger) SentBytes(n int) {
    59  	l.exchangeCount++
    60  	l.lastExchange = time.Now()
    61  	l.Accounting.BytesSent += uint64(n)
    62  }
    63  
    64  func (l *ledger) ReceivedBytes(n int) {
    65  	l.exchangeCount++
    66  	l.lastExchange = time.Now()
    67  	l.Accounting.BytesRecv += uint64(n)
    68  }
    69  
    70  // TODO: this needs to be different. We need timeouts.
    71  func (l *ledger) Wants(k key.Key, priority int) {
    72  	log.Debugf("peer %s wants %s", l.Partner, k)
    73  	l.wantList.Add(k, priority)
    74  }
    75  
    76  func (l *ledger) CancelWant(k key.Key) {
    77  	l.wantList.Remove(k)
    78  }
    79  
    80  func (l *ledger) WantListContains(k key.Key) (wl.Entry, bool) {
    81  	return l.wantList.Contains(k)
    82  }
    83  
    84  func (l *ledger) ExchangeCount() uint64 {
    85  	return l.exchangeCount
    86  }