diff --git a/multiless.go b/multiless.go new file mode 100644 index 00000000..5d6ebb47 --- /dev/null +++ b/multiless.go @@ -0,0 +1,46 @@ +package torrent + +func strictCmp(same, less bool) cmper { + return func() (bool, bool) { return same, less } +} + +type ( + cmper func() (same, less bool) + multiLess struct { + ok bool + less bool + } +) + +func (me *multiLess) Final() bool { + if !me.ok { + panic("undetermined") + } + return me.less +} + +func (me *multiLess) FinalOk() (left, ok bool) { + return me.less, me.ok +} + +func (me *multiLess) Next(f cmper) { + if me.ok { + return + } + same, less := f() + if same { + return + } + me.ok, me.less = true, less +} + +func (me *multiLess) StrictNext(same, less bool) { + if same { + return + } + me.ok, me.less = true, less +} + +func (me *multiLess) NextBool(l, r bool) { + me.StrictNext(l == r, l) +} diff --git a/worst_conns.go b/worst_conns.go index dbbc3c27..51a23f12 100644 --- a/worst_conns.go +++ b/worst_conns.go @@ -3,13 +3,15 @@ package torrent import "container/heap" func worseConn(l, r *connection) bool { - if l.useful() != r.useful() { - return r.useful() - } - if !l.lastHelpful().Equal(r.lastHelpful()) { - return l.lastHelpful().Before(r.lastHelpful()) - } - return l.completedHandshake.Before(r.completedHandshake) + var ml multiLess + ml.NextBool(!l.useful(), !r.useful()) + ml.StrictNext( + l.lastHelpful().Equal(r.lastHelpful()), + l.lastHelpful().Before(r.lastHelpful())) + ml.StrictNext( + l.completedHandshake.Equal(r.completedHandshake), + l.completedHandshake.Before(r.completedHandshake)) + return ml.Final() } type worseConnSlice struct {