]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Add Torrent.Stats.ConnectedSeeders
authorMatt Joiner <anacrolix@gmail.com>
Mon, 29 Jan 2018 07:18:08 +0000 (18:18 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Mon, 29 Jan 2018 07:22:21 +0000 (18:22 +1100)
Fixes #231

connection.go
torrent.go
torrent_stats.go

index 753bc64fddbf9bf64db25a368621269830c13029..40d02abab34d7ca8f57417bc66a23a664c0690f8 100644 (file)
@@ -82,7 +82,7 @@ type connection struct {
        peerPieces bitmap.Bitmap
        // The peer has everything. This can occur due to a special message, when
        // we may not even know the number of pieces in the torrent yet.
-       peerHasAll bool
+       peerSentHaveAll bool
        // The highest possible number of pieces the torrent could have based on
        // communication with the peer. Generally only useful until we have the
        // torrent info.
@@ -102,6 +102,16 @@ type connection struct {
        writerCond   sync.Cond
 }
 
+func (cn *connection) peerHasAllPieces() (all bool, known bool) {
+       if cn.peerSentHaveAll {
+               return true, true
+       }
+       if !cn.t.haveInfo() {
+               return false, false
+       }
+       return bitmap.Flip(cn.peerPieces, 0, cn.t.numPieces()).IsEmpty(), true
+}
+
 func (cn *connection) mu() sync.Locker {
        return &cn.t.cl.mu
 }
@@ -234,7 +244,7 @@ func (cn *connection) Close() {
 }
 
 func (cn *connection) PeerHasPiece(piece int) bool {
-       return cn.peerHasAll || cn.peerPieces.Contains(piece)
+       return cn.peerSentHaveAll || cn.peerPieces.Contains(piece)
 }
 
 func (cn *connection) Post(msg pp.Message) {
@@ -695,7 +705,7 @@ func (cn *connection) peerSentHave(piece int) error {
 }
 
 func (cn *connection) peerSentBitfield(bf []bool) error {
-       cn.peerHasAll = false
+       cn.peerSentHaveAll = false
        if len(bf)%8 != 0 {
                panic("expected bitfield length divisible by 8")
        }
@@ -716,8 +726,8 @@ func (cn *connection) peerSentBitfield(bf []bool) error {
        return nil
 }
 
-func (cn *connection) peerSentHaveAll() error {
-       cn.peerHasAll = true
+func (cn *connection) onPeerSentHaveAll() error {
+       cn.peerSentHaveAll = true
        cn.peerPieces.Clear()
        cn.peerPiecesChanged()
        return nil
@@ -725,7 +735,7 @@ func (cn *connection) peerSentHaveAll() error {
 
 func (cn *connection) peerSentHaveNone() error {
        cn.peerPieces.Clear()
-       cn.peerHasAll = false
+       cn.peerSentHaveAll = false
        cn.peerPiecesChanged()
        return nil
 }
@@ -883,7 +893,7 @@ func (c *connection) mainReadLoop() error {
                case pp.Bitfield:
                        err = c.peerSentBitfield(msg.Bitfield)
                case pp.HaveAll:
-                       err = c.peerSentHaveAll()
+                       err = c.onPeerSentHaveAll()
                case pp.HaveNone:
                        err = c.peerSentHaveNone()
                case pp.Piece:
index a215859d568c7cc61277007bc28d17115ec8d013..f5d3b2a646cebe2934762a3de1518293564d6300 100644 (file)
@@ -1354,6 +1354,12 @@ func (t *Torrent) statsLocked() TorrentStats {
        t.stats.HalfOpenPeers = len(t.halfOpen)
        t.stats.PendingPeers = len(t.peers)
        t.stats.TotalPeers = t.numTotalPeers()
+       t.stats.ConnectedSeeders = 0
+       for c := range t.conns {
+               if all, ok := c.peerHasAllPieces(); all && ok {
+                       t.stats.ConnectedSeeders++
+               }
+       }
        return t.stats
 }
 
index 3dd2716a916db24aa5be75eac817922c68d89290..f155a0d83ea369e2fa6539b9fe157ace55b18039 100644 (file)
@@ -3,8 +3,10 @@ package torrent
 type TorrentStats struct {
        ConnStats // Aggregates stats over all connections past and present.
 
-       ActivePeers   int
-       HalfOpenPeers int
-       PendingPeers  int
-       TotalPeers    int
+       // Ordered by expected descending quantities (if all is well).
+       TotalPeers       int
+       PendingPeers     int
+       ActivePeers      int
+       ConnectedSeeders int
+       HalfOpenPeers    int
 }