]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Add File.Cancel
authorMatt Joiner <anacrolix@gmail.com>
Thu, 4 Feb 2016 14:18:54 +0000 (01:18 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Thu, 4 Feb 2016 14:18:54 +0000 (01:18 +1100)
file.go
file_test.go [new file with mode: 0644]
piece.go
t.go
torrent.go

diff --git a/file.go b/file.go
index 8e28781b9405cf434875df7c1ec73acee33482ec..94d71a1f7f14b7abfa68ba9acfa813b1abc36493 100644 (file)
--- a/file.go
+++ b/file.go
@@ -78,3 +78,17 @@ func (f *File) State() (ret []FilePieceState) {
 func (f *File) Download() {
        f.t.DownloadPieces(f.t.torrent.byteRegionPieces(f.offset, f.length))
 }
+
+func byteRegionExclusivePieces(off, size, pieceSize int64) (begin, end int) {
+       begin = int((off + pieceSize - 1) / pieceSize)
+       end = int((off + size) / pieceSize)
+       return
+}
+
+func (f *File) exclusivePieces() (begin, end int) {
+       return byteRegionExclusivePieces(f.offset, f.length, int64(f.t.torrent.usualPieceSize()))
+}
+
+func (f *File) Cancel() {
+       f.t.CancelPieces(f.exclusivePieces())
+}
diff --git a/file_test.go b/file_test.go
new file mode 100644 (file)
index 0000000..b66d198
--- /dev/null
@@ -0,0 +1,22 @@
+package torrent
+
+import (
+       "testing"
+
+       "github.com/stretchr/testify/assert"
+)
+
+func TestFileExclusivePieces(t *testing.T) {
+       for _, _case := range []struct {
+               off, size, pieceSize int64
+               begin, end           int
+       }{
+               {0, 2, 2, 0, 1},
+               {1, 2, 2, 1, 1},
+               {1, 4, 2, 1, 2},
+       } {
+               begin, end := byteRegionExclusivePieces(_case.off, _case.size, _case.pieceSize)
+               assert.EqualValues(t, _case.begin, begin)
+               assert.EqualValues(t, _case.end, end)
+       }
+}
index 16f20653fd2b5f7df918e6554dfd7784fdf63870..a56225c1ec7ca947ce97002676abc9460abc4377 100644 (file)
--- a/piece.go
+++ b/piece.go
@@ -52,6 +52,15 @@ func (p *piece) pendingChunk(cs chunkSpec, chunkSize pp.Integer) bool {
        return !p.DirtyChunks[ci]
 }
 
+func (p *piece) hasDirtyChunks() bool {
+       for _, dirty := range p.DirtyChunks {
+               if dirty {
+                       return true
+               }
+       }
+       return false
+}
+
 func (p *piece) numDirtyChunks() (ret int) {
        for _, dirty := range p.DirtyChunks {
                if dirty {
diff --git a/t.go b/t.go
index ffb64dd3ac221289a31d512cdffd4e680089a85c..6bb1071109c2326df8c36d3ce23110ed76ff76c6 100644 (file)
--- a/t.go
+++ b/t.go
@@ -140,7 +140,11 @@ func (t Torrent) deleteReader(r *Reader) {
 func (t Torrent) DownloadPieces(begin, end int) {
        t.cl.mu.Lock()
        defer t.cl.mu.Unlock()
-       for i := begin; i < end; i++ {
-               t.torrent.pendPiece(i, t.cl)
-       }
+       t.torrent.pendPieceRange(begin, end)
+}
+
+func (t Torrent) CancelPieces(begin, end int) {
+       t.cl.mu.Lock()
+       defer t.cl.mu.Unlock()
+       t.torrent.unpendPieceRange(begin, end)
 }
index fd462e1f11d7f47681c3a3639b982f09334b51ef..1d465957d1c844841461f590316a61cc1397d4fd 100644 (file)
@@ -508,9 +508,14 @@ func (t *torrent) bytesLeft() (left int64) {
        return
 }
 
-func (t *torrent) piecePartiallyDownloaded(index int) bool {
-       pendingBytes := t.pieceNumPendingBytes(index)
-       return pendingBytes != 0 && pendingBytes != t.pieceLength(index)
+func (t *torrent) piecePartiallyDownloaded(piece int) bool {
+       if t.pieceComplete(piece) {
+               return false
+       }
+       if t.pieceAllDirty(piece) {
+               return true
+       }
+       return t.Pieces[piece].hasDirtyChunks()
 }
 
 func numChunksForPiece(chunkSize int, pieceSize int) int {
@@ -976,6 +981,37 @@ func (t *torrent) pendPiece(piece int, cl *Client) {
        t.piecePriorityChanged(piece)
 }
 
+func (t *torrent) getCompletedPieces() (ret bitmap.Bitmap) {
+       for i := range iter.N(t.numPieces()) {
+               if t.pieceComplete(i) {
+                       ret.Add(i)
+               }
+       }
+       return
+}
+
+func (t *torrent) pendPieces(pend *bitmap.Bitmap) {
+       t.pendingPieces.Union(pend)
+       t.updatePiecePriorities()
+}
+
+func (t *torrent) unpendPieces(unpend *bitmap.Bitmap) {
+       t.pendingPieces.Sub(unpend)
+       t.updatePiecePriorities()
+}
+
+func (t *torrent) pendPieceRange(begin, end int) {
+       var bm bitmap.Bitmap
+       bm.AddRange(begin, end)
+       t.pendPieces(&bm)
+}
+
+func (t *torrent) unpendPieceRange(begin, end int) {
+       var bm bitmap.Bitmap
+       bm.AddRange(begin, end)
+       t.unpendPieces(&bm)
+}
+
 func (t *torrent) connRequestPiecePendingChunks(c *connection, piece int) (more bool) {
        if !c.PeerHasPiece(piece) {
                return true