func newScoreLedger(p peer.ID, clock clock.Clock) *scoreledger {
	return &scoreledger{
		partner: p,
		clock:   clock,
	}
}
Returns a new scoreledger.
package decision
import (
	"sync"
	"time"
	"github.com/benbjohnson/clock"
	peer "github.com/libp2p/go-libp2p-core/peer"
)
const (
	shortTermAlpha = 0.5
	longTermAlpha = 0.05
	shortTerm = 10 * time.Second
	longTermRatio = 10
	longTermScore  = 10  
	shortTermScore = 10  
)
type scoreledger struct {
	partner peer.ID
	bytesSent uint64
	bytesRecv uint64
	lastExchange time.Time
	shortScore, longScore float64
	score int
	exchangeCount uint64
	lock sync.RWMutex
	clock clock.Clock
}
type Receipt struct {
	Peer      string
	Value     float64
	Sent      uint64
	Recv      uint64
	Exchanged uint64
}
func (l *scoreledger) AddToSentBytes(n int) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.exchangeCount++
	l.lastExchange = l.clock.Now()
	l.bytesSent += uint64(n)
}
func (l *scoreledger) AddToReceivedBytes(n int) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.exchangeCount++
	l.lastExchange = l.clock.Now()
	l.bytesRecv += uint64(n)
}
func (l *scoreledger) Receipt() *Receipt {
	l.lock.RLock()
	defer l.lock.RUnlock()
	return &Receipt{
		Peer:      l.partner.String(),
		Value:     float64(l.bytesSent) / float64(l.bytesRecv+1),
		Sent:      l.bytesSent,
		Recv:      l.bytesRecv,
		Exchanged: l.exchangeCount,
	}
}
type DefaultScoreLedger struct {
	scorePeer ScorePeerFunc
	closing chan struct{}
	lock sync.RWMutex
	ledgerMap map[peer.ID]*scoreledger
	peerSampleInterval time.Duration
	sampleCh chan struct{}
	clock    clock.Clock
}
func (dsl *DefaultScoreLedger) scoreWorker() {
	ticker := dsl.clock.Ticker(dsl.peerSampleInterval)
	defer ticker.Stop()
	type update struct {
		peer  peer.ID
		score int
	}
	var (
		lastShortUpdate, lastLongUpdate time.Time
		updates                         []update
	)
	for i := 0; ; i = (i + 1) % longTermRatio {
		var now time.Time
		select {
		case now = <-ticker.C:
		case <-dsl.closing:
			return
		}
		updateLong := i == 0
		dsl.lock.Lock()
		for _, l := range dsl.ledgerMap {
			l.lock.Lock()
			if l.lastExchange.After(lastShortUpdate) {
				l.shortScore = ewma(l.shortScore, shortTermScore, shortTermAlpha)
			} else {
				l.shortScore = ewma(l.shortScore, 0, shortTermAlpha)
			}
			if updateLong {
				if l.lastExchange.After(lastLongUpdate) {
					l.longScore = ewma(l.longScore, longTermScore, longTermAlpha)
				} else {
					l.longScore = ewma(l.longScore, 0, longTermAlpha)
				}
			}
			var lscore float64
			if l.bytesRecv == 0 {
				lscore = 0
			} else {
				lscore = float64(l.bytesRecv) / float64(l.bytesRecv+l.bytesSent)
			}
			score := int((l.shortScore + l.longScore) * (lscore*.5 + .75))
			if l.score != score {
				updates = append(updates, update{l.partner, score})
				l.score = score
			}
			l.lock.Unlock()
		}
		dsl.lock.Unlock()
		lastShortUpdate = now
		if updateLong {
			lastLongUpdate = now
		}
		for _, update := range updates {
			dsl.scorePeer(update.peer, update.score)
		}
		updates = updates[:0]
		if dsl.sampleCh != nil {
			dsl.sampleCh <- struct{}{}
		}
	}
}
func (dsl *DefaultScoreLedger) find(p peer.ID) *scoreledger {
	dsl.lock.RLock()
	l, ok := dsl.ledgerMap[p]
	dsl.lock.RUnlock()
	if ok {
		return l
	}
	return nil
}