9 "github.com/anacrolix/multiless"
10 "github.com/anacrolix/sync"
13 type worseConnInput struct {
17 CompletedHandshake time.Time
18 GetPeerPriority func() (peerPriority, error)
19 getPeerPriorityOnce sync.Once
20 peerPriority peerPriority
25 func (me *worseConnInput) doGetPeerPriority() {
26 me.peerPriority, me.peerPriorityErr = me.GetPeerPriority()
29 func (me *worseConnInput) doGetPeerPriorityOnce() {
30 me.getPeerPriorityOnce.Do(me.doGetPeerPriority)
33 type worseConnLensOpts struct {
34 incomingIsBad, outgoingIsBad bool
37 func worseConnInputFromPeer(p *PeerConn, opts worseConnLensOpts) worseConnInput {
38 ret := worseConnInput{
40 LastHelpful: p.lastHelpful(),
41 CompletedHandshake: p.completedHandshake,
42 Pointer: uintptr(unsafe.Pointer(p)),
43 GetPeerPriority: p.peerPriority,
45 if opts.incomingIsBad && !p.outgoing {
46 ret.BadDirection = true
47 } else if opts.outgoingIsBad && p.outgoing {
48 ret.BadDirection = true
53 func (l *worseConnInput) Less(r *worseConnInput) bool {
54 less, ok := multiless.New().Bool(
55 r.BadDirection, l.BadDirection).Bool(
56 l.Useful, r.Useful).CmpInt64(
57 l.LastHelpful.Sub(r.LastHelpful).Nanoseconds()).CmpInt64(
58 l.CompletedHandshake.Sub(r.CompletedHandshake).Nanoseconds()).LazySameLess(
59 func() (same, less bool) {
60 l.doGetPeerPriorityOnce()
61 if l.peerPriorityErr != nil {
65 r.doGetPeerPriorityOnce()
66 if r.peerPriorityErr != nil {
70 same = l.peerPriority == r.peerPriority
71 less = l.peerPriority < r.peerPriority
77 panic(fmt.Sprintf("cannot differentiate %#v and %#v", l, r))
82 type worseConnSlice struct {
87 func (me *worseConnSlice) initKeys(opts worseConnLensOpts) {
88 me.keys = make([]worseConnInput, len(me.conns))
89 for i, c := range me.conns {
90 me.keys[i] = worseConnInputFromPeer(c, opts)
94 var _ heap.Interface = &worseConnSlice{}
96 func (me worseConnSlice) Len() int {
100 func (me worseConnSlice) Less(i, j int) bool {
101 return me.keys[i].Less(&me.keys[j])
104 func (me *worseConnSlice) Pop() interface{} {
105 i := len(me.conns) - 1
107 me.conns = me.conns[:i]
111 func (me *worseConnSlice) Push(x interface{}) {
112 panic("not implemented")
115 func (me worseConnSlice) Swap(i, j int) {
116 me.conns[i], me.conns[j] = me.conns[j], me.conns[i]
117 me.keys[i], me.keys[j] = me.keys[j], me.keys[i]