From: Matt Joiner Date: Fri, 12 Jan 2018 01:24:37 +0000 (+1100) Subject: Make Torrent.pendingPieces a priority bitmap in preparation for #220 X-Git-Tag: v1.0.0~278 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=ed7e3f6ec03a84803f983e2851f761da162f8b94;p=btrtrc.git Make Torrent.pendingPieces a priority bitmap in preparation for #220 --- diff --git a/connection.go b/connection.go index f4bef805..794f5986 100644 --- a/connection.go +++ b/connection.go @@ -541,7 +541,19 @@ func (cn *connection) unbiasedPieceRequestOrder() iter.Func { skip.Union(cn.t.completedPieces) // Return an iterator over the different priority classes, minus the skip // pieces. - return iterBitmapsDistinct(skip, now, readahead, cn.t.pendingPieces) + return iter.Chain( + iterBitmapsDistinct(skip, now, readahead), + func(cb iter.Callback) { + cn.t.pendingPieces.IterTyped(func(piece int) bool { + if skip.Contains(piece) { + return true + } + more := cb(piece) + skip.Add(piece) + return more + }) + }, + ) } // The connection should download highest priority pieces first, without any diff --git a/connection_test.go b/connection_test.go index 3f6dfd93..f22d26b9 100644 --- a/connection_test.go +++ b/connection_test.go @@ -97,7 +97,7 @@ func BenchmarkConnectionMainReadLoop(b *testing.B) { } t.setChunkSize(defaultChunkSize) t.makePieces() - t.pendingPieces.Add(0) + t.pendingPieces.Set(0, PiecePriorityNormal.BitmapPriority()) r, w := io.Pipe() cn := &connection{ t: t, diff --git a/piece.go b/piece.go index d5130d7b..71c60417 100644 --- a/piece.go +++ b/piece.go @@ -21,13 +21,20 @@ func (pp *piecePriority) Raise(maybe piecePriority) { } } +// Priority for use in PriorityBitmap +func (me piecePriority) BitmapPriority() int { + return -int(me) +} + const ( PiecePriorityNone piecePriority = iota // Not wanted. PiecePriorityNormal // Wanted. + PiecePriorityHigh // Wanted a lot. PiecePriorityReadahead // May be required soon. - // Succeeds a piece where a read occurred. Currently the same as Now, apparently due to issues with caching. + // Succeeds a piece where a read occurred. Currently the same as Now, + // apparently due to issues with caching. PiecePriorityNext - PiecePriorityNow // A Reader is reading in this piece. + PiecePriorityNow // A Reader is reading in this piece. Highest urgency. ) type Piece struct { diff --git a/torrent.go b/torrent.go index 301e2d6d..32f66b4e 100644 --- a/torrent.go +++ b/torrent.go @@ -16,6 +16,8 @@ import ( "text/tabwriter" "time" + "github.com/anacrolix/missinggo/prioritybitmap" + "github.com/anacrolix/dht" "github.com/anacrolix/missinggo" "github.com/anacrolix/missinggo/bitmap" @@ -113,7 +115,7 @@ type Torrent struct { // The indexes of pieces we want with normal priority, that aren't // currently available. - pendingPieces bitmap.Bitmap + pendingPieces prioritybitmap.PriorityBitmap // A cache of completed piece indices. completedPieces bitmap.Bitmap // Pieces that need to be hashed. @@ -965,13 +967,13 @@ func (t *Torrent) pendPiece(piece int) { if t.havePiece(piece) { return } - t.pendingPieces.Add(piece) + t.pendingPieces.Set(piece, PiecePriorityNormal.BitmapPriority()) t.updatePiecePriority(piece) } func (t *Torrent) unpendPieces(unpend bitmap.Bitmap) { - t.pendingPieces.Sub(unpend) - unpend.IterTyped(func(piece int) (again bool) { + unpend.IterTyped(func(piece int) (more bool) { + t.pendingPieces.Remove(piece) t.updatePiecePriority(piece) return true })