]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Clear piece touch flag from connection after a piece is hashed
authorMatt Joiner <anacrolix@gmail.com>
Tue, 4 Aug 2015 16:43:53 +0000 (02:43 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Tue, 4 Aug 2015 16:43:53 +0000 (02:43 +1000)
client.go

index 17a3d87262009b58703f7d36e25033933551e3d8..0eb199f12932924208171729625a6d5109b1c5b8 100644 (file)
--- a/client.go
+++ b/client.go
@@ -2605,33 +2605,43 @@ func (me *Client) downloadedChunk(t *torrent, c *connection, msg *pp.Message) er
        return nil
 }
 
+// Return the connections that touched a piece, and clear the entry while
+// doing it.
+func (me *Client) reapPieceTouches(t *torrent, piece int) (ret []*connection) {
+       for _, c := range t.Conns {
+               if _, ok := c.peerTouchedPieces[piece]; ok {
+                       ret = append(ret, c)
+                       delete(c.peerTouchedPieces, piece)
+               }
+       }
+       return
+}
+
 func (me *Client) pieceHashed(t *torrent, piece pp.Integer, correct bool) {
        p := t.Pieces[piece]
        if p.EverHashed {
+               // Don't score the first time a piece is hashed, it could be an
+               // initial check.
                if correct {
                        pieceHashedCorrect.Add(1)
                } else {
                        log.Printf("%s: piece %d failed hash", t, piece)
                        pieceHashedNotCorrect.Add(1)
-                       var touched []*connection
-                       for _, c := range t.Conns {
-                               if _, ok := c.peerTouchedPieces[int(piece)]; ok {
-                                       touched = append(touched, c)
-                               }
-                       }
-                       log.Printf("dropping %d conns that touched piece", len(touched))
-                       for _, c := range touched {
-                               me.dropConnection(t, c)
-                       }
                }
        }
        p.EverHashed = true
+       touchers := me.reapPieceTouches(t, int(piece))
        if correct {
                err := t.data.PieceCompleted(int(piece))
                if err != nil {
                        log.Printf("error completing piece: %s", err)
                        correct = false
                }
+       } else if len(touchers) != 0 {
+               log.Printf("dropping %d conns that touched piece", len(touchers))
+               for _, c := range touchers {
+                       me.dropConnection(t, c)
+               }
        }
        me.pieceChanged(t, int(piece))
 }