client.go | 4 ++-- file.go | 12 ++++++------ peerconn.go | 29 +++++++++++++++-------------- piece.go | 10 +++++----- request-strategy.go | 3 ++- test/transfer_test.go | 3 ++- torrent.go | 22 +++++++++++----------- torrent_test.go | 5 +++-- diff --git a/client.go b/client.go index 9300b24b23c4c94e8b99497023ccb3c4339fb458..98bf0892465a160d17fa06250ac9b78bff1650bc 100644 --- a/client.go +++ b/client.go @@ -18,10 +18,10 @@ "github.com/anacrolix/dht/v2" "github.com/anacrolix/dht/v2/krpc" "github.com/anacrolix/log" - "github.com/anacrolix/missinggo/bitmap" "github.com/anacrolix/missinggo/perf" "github.com/anacrolix/missinggo/pubsub" "github.com/anacrolix/missinggo/slices" + "github.com/anacrolix/missinggo/v2/bitmap" "github.com/anacrolix/missinggo/v2/pproffd" "github.com/anacrolix/sync" "github.com/anacrolix/torrent/internal/limiter" @@ -1007,7 +1007,7 @@ func() { if conn.fastEnabled() { if torrent.haveAllPieces() { conn.write(pp.Message{Type: pp.HaveAll}) - conn.sentHaves.AddRange(0, bitmap.BitIndex(conn.t.NumPieces())) + conn.sentHaves.AddRange(0, bitmap.BitRange(conn.t.NumPieces())) return } else if !torrent.haveAnyPieces() { conn.write(pp.Message{Type: pp.HaveNone}) diff --git a/file.go b/file.go index e2ebcf4d5c6cf5a2a8c90b1e8a109f8caa4f3282..37c185c1aa72b7c7802b863347731f4de2200047 100644 --- a/file.go +++ b/file.go @@ -66,20 +66,20 @@ numPiecesSpanned := fileEndPieceIndex - fileFirstPieceIndex switch numPiecesSpanned { case 0: case 1: - if !torrentCompletedPieces.Get(fileFirstPieceIndex) { + if !torrentCompletedPieces.Get(bitmap.BitIndex(fileFirstPieceIndex)) { left += fileLength } default: - if !torrentCompletedPieces.Get(fileFirstPieceIndex) { + if !torrentCompletedPieces.Get(bitmap.BitIndex(fileFirstPieceIndex)) { left += torrentUsualPieceSize - (fileTorrentOffset % torrentUsualPieceSize) } - if !torrentCompletedPieces.Get(fileEndPieceIndex - 1) { + if !torrentCompletedPieces.Get(bitmap.BitIndex(fileEndPieceIndex - 1)) { left += fileTorrentOffset + fileLength - int64(fileEndPieceIndex-1)*torrentUsualPieceSize } completedMiddlePieces := torrentCompletedPieces.Copy() - completedMiddlePieces.RemoveRange(0, fileFirstPieceIndex+1) - completedMiddlePieces.RemoveRange(fileEndPieceIndex-1, bitmap.ToEnd) - left += int64(numPiecesSpanned-2-completedMiddlePieces.Len()) * torrentUsualPieceSize + completedMiddlePieces.RemoveRange(0, bitmap.BitRange(fileFirstPieceIndex+1)) + completedMiddlePieces.RemoveRange(bitmap.BitRange(fileEndPieceIndex-1), bitmap.ToEnd) + left += int64(numPiecesSpanned-2-pieceIndex(completedMiddlePieces.Len())) * torrentUsualPieceSize } return } diff --git a/peerconn.go b/peerconn.go index f3680e1832472b6e893c2784a4ddcc621bc42dd1..976081ab614a949c773f4c742d6827315dfe5d0c 100644 --- a/peerconn.go +++ b/peerconn.go @@ -232,7 +232,7 @@ } if !cn.t.haveInfo() { return false, false } - return bitmap.Flip(cn._peerPieces, 0, bitmap.BitIndex(cn.t.numPieces())).IsEmpty(), true + return bitmap.Flip(cn._peerPieces, 0, bitmap.BitRange(cn.t.numPieces())).IsEmpty(), true } func (cn *PeerConn) locker() *lockWithDeferreds { @@ -267,7 +267,7 @@ // Correct the PeerPieces slice length. Return false if the existing slice is invalid, such as by // receiving badly sized BITFIELD, or invalid HAVE messages. func (cn *PeerConn) setNumPieces(num pieceIndex) { - cn._peerPieces.RemoveRange(bitmap.BitIndex(num), bitmap.ToEnd) + cn._peerPieces.RemoveRange(bitmap.BitRange(num), bitmap.ToEnd) cn.peerPiecesChanged() } @@ -730,10 +730,10 @@ for _, bm := range bms { if !iter.All( func(_i interface{}) bool { i := _i.(int) - if skip.Contains(i) { + if skip.Contains(bitmap.BitIndex(i)) { return true } - skip.Add(i) + skip.Add(bitmap.BitIndex(i)) return cb(i) }, bm.Iter, @@ -746,7 +746,7 @@ } // check callers updaterequests func (cn *Peer) stopRequestingPiece(piece pieceIndex) bool { - return cn._pieceRequestOrder.Remove(bitmap.BitIndex(piece)) + return cn._pieceRequestOrder.Remove(piece) } // This is distinct from Torrent piece priority, which is the user's @@ -762,7 +762,7 @@ if tpp == PiecePriorityNone { return cn.stopRequestingPiece(piece) } prio := cn.getPieceInclination()[piece] - return cn._pieceRequestOrder.Set(bitmap.BitIndex(piece), prio) + return cn._pieceRequestOrder.Set(piece, prio) } func (cn *Peer) getPieceInclination() []int { @@ -835,15 +835,15 @@ cn.peerSentHaveAll = false for i, have := range bf { if have { cn.raisePeerMinPieces(pieceIndex(i) + 1) - if !pp.Contains(i) { + if !pp.Contains(bitmap.BitIndex(i)) { cn.t.incPieceAvailability(i) } } else { - if pp.Contains(i) { + if pp.Contains(bitmap.BitIndex(i)) { cn.t.decPieceAvailability(i) } } - cn._peerPieces.Set(i, have) + cn._peerPieces.Set(bitmap.BitIndex(i), have) } cn.peerPiecesChanged() return nil @@ -854,7 +854,7 @@ t := cn.t if t.haveInfo() { pp := cn.newPeerPieces() for i := range iter.N(t.numPieces()) { - if !pp.Contains(i) { + if !pp.Contains(bitmap.BitIndex(i)) { t.incPieceAvailability(i) } } @@ -1198,7 +1198,7 @@ c.remoteRejectedRequest(newRequestFromMessage(&msg)) case pp.AllowedFast: torrent.Add("allowed fasts received", 1) log.Fmsg("peer allowed fast: %d", msg.Index).AddValues(c).SetLevel(log.Debug).Log(c.t.logger) - c.peerAllowedFast.Add(int(msg.Index)) + c.peerAllowedFast.Add(bitmap.BitIndex(msg.Index)) c.updateRequests() case pp.Extended: err = c.onReadExtendedMsg(msg.ExtendedID, msg.ExtendedPayload) @@ -1326,7 +1326,7 @@ return errors.New("received unexpected chunk") } c.decExpectedChunkReceive(req) - if c.peerChoking && c.peerAllowedFast.Get(int(req.Index)) { + if c.peerChoking && c.peerAllowedFast.Get(bitmap.BitIndex(req.Index)) { chunksReceived.Add("due to allowed fast", 1) } @@ -1658,11 +1658,12 @@ defer cn.locker().RUnlock() return cn.newPeerPieces() } -// Returns a new Bitmap that includes bits for all pieces we have. +// Returns a new Bitmap that includes bits for all pieces the peer claims to have. func (cn *Peer) newPeerPieces() bitmap.Bitmap { ret := cn._peerPieces.Copy() if cn.peerSentHaveAll { - ret.AddRange(0, cn.t.numPieces()) + + ret.AddRange(0, bitmap.BitRange(cn.t.numPieces())) } return ret } diff --git a/piece.go b/piece.go index 3ee648d37e44248a06c0c97d2bd028871104bfce..45b37c0aa2cd5d7337c90d7b87a1644907d2f733 100644 --- a/piece.go +++ b/piece.go @@ -53,7 +53,7 @@ return p.t.storage.Piece(p.Info()) } func (p *Piece) pendingChunkIndex(chunkIndex int) bool { - return !p._dirtyChunks.Contains(chunkIndex) + return !p._dirtyChunks.Contains(bitmap.BitIndex(chunkIndex)) } func (p *Piece) pendingChunk(cs ChunkSpec, chunkSize pp.Integer) bool { @@ -69,12 +69,12 @@ return pp.Integer(p._dirtyChunks.Len()) } func (p *Piece) unpendChunkIndex(i int) { - p._dirtyChunks.Add(i) + p._dirtyChunks.Add(bitmap.BitIndex(i)) p.t.tickleReaders() } func (p *Piece) pendChunkIndex(i int) { - p._dirtyChunks.Remove(i) + p._dirtyChunks.Remove(bitmap.BitIndex(i)) } func (p *Piece) numChunks() pp.Integer { @@ -199,7 +199,7 @@ func (p *Piece) purePriority() (ret piecePriority) { for _, f := range p.files { ret.Raise(f.prio) } - if p.t.readerNowPieces().Contains(int(p.index)) { + if p.t.readerNowPieces().Contains(bitmap.BitIndex(p.index)) { ret.Raise(PiecePriorityNow) } // if t._readerNowPieces.Contains(piece - 1) { @@ -234,7 +234,7 @@ return } func (p *Piece) allChunksDirty() bool { - return p._dirtyChunks.Len() == int(p.numChunks()) + return p._dirtyChunks.Len() == bitmap.BitRange(p.numChunks()) } func (p *Piece) dirtyChunks() bitmap.Bitmap { diff --git a/request-strategy.go b/request-strategy.go index f0470007ccf91d58567c2b54b62f3862b0a96751..72f7f3d4ae1b6ebf90118d16d197662605147819 100644 --- a/request-strategy.go +++ b/request-strategy.go @@ -4,6 +4,7 @@ import ( "time" "unsafe" + "github.com/anacrolix/missinggo/v2/bitmap" request_strategy "github.com/anacrolix/torrent/request-strategy" "github.com/anacrolix/torrent/types" ) @@ -66,7 +67,7 @@ return ok }, Choking: p.peerChoking, PieceAllowedFast: func(i pieceIndex) bool { - return p.peerAllowedFast.Contains(i) + return p.peerAllowedFast.Contains(bitmap.BitIndex(i)) }, DownloadRate: p.downloadRate(), Age: time.Since(p.completedHandshake), diff --git a/test/transfer_test.go b/test/transfer_test.go index 857cd44ff3a7b3a76c8b65472db67db256cfa211..b3187c0bec30cef658bba492560eda39d17552f1 100644 --- a/test/transfer_test.go +++ b/test/transfer_test.go @@ -12,6 +12,7 @@ "testing" "testing/iotest" "time" + "github.com/anacrolix/missinggo/v2/bitmap" "github.com/anacrolix/missinggo/v2/filecache" "github.com/anacrolix/torrent" "github.com/anacrolix/torrent/internal/testutil" @@ -168,7 +169,7 @@ foundSeeder := false for _, pc := range leecherPeerConns { completed := pc.PeerPieces().Len() t.Logf("peer conn %v has %v completed pieces", pc, completed) - if completed == leecherTorrent.Info().NumPieces() { + if completed == bitmap.BitRange(leecherTorrent.Info().NumPieces()) { foundSeeder = true } } diff --git a/torrent.go b/torrent.go index da71ba93168be13f1b5394edb267f3eea197474c..5190b65ebeb3a9df9cec4877c9caab996df49025 100644 --- a/torrent.go +++ b/torrent.go @@ -759,7 +759,7 @@ return t.bytesLeft() } func (t *Torrent) bytesLeft() (left int64) { - bitmap.Flip(t._completedPieces, 0, bitmap.BitIndex(t.numPieces())).IterTyped(func(piece int) bool { + bitmap.Flip(t._completedPieces, 0, bitmap.BitRange(t.numPieces())).IterTyped(func(piece int) bool { p := &t.pieces[piece] left += int64(p.length() - p.numDirtyBytes()) return true @@ -794,8 +794,8 @@ func (t *Torrent) numPieces() pieceIndex { return pieceIndex(t.info.NumPieces()) } -func (t *Torrent) numPiecesCompleted() (num int) { - return t._completedPieces.Len() +func (t *Torrent) numPiecesCompleted() (num pieceIndex) { + return pieceIndex(t._completedPieces.Len()) } func (t *Torrent) close() (err error) { @@ -895,7 +895,7 @@ func (t *Torrent) haveAllPieces() bool { if !t.haveInfo() { return false } - return t._completedPieces.Len() == bitmap.BitIndex(t.numPieces()) + return t._completedPieces.Len() == bitmap.BitRange(t.numPieces()) } func (t *Torrent) havePiece(index pieceIndex) bool { @@ -960,7 +960,7 @@ } if t.pieceComplete(index) { return false } - if t._pendingPieces.Contains(bitmap.BitIndex(index)) { + if t._pendingPieces.Contains(int(index)) { return true } // t.logger.Printf("piece %d not pending", index) @@ -1019,7 +1019,7 @@ return t.pieceNumChunks(piece) - t.pieces[piece].numDirtyChunks() } func (t *Torrent) pieceAllDirty(piece pieceIndex) bool { - return t.pieces[piece]._dirtyChunks.Len() == int(t.pieceNumChunks(piece)) + return t.pieces[piece]._dirtyChunks.Len() == bitmap.BitRange(t.pieceNumChunks(piece)) } func (t *Torrent) readersChanged() { @@ -1078,11 +1078,11 @@ p := &t.pieces[piece] newPrio := p.uncachedPriority() // t.logger.Printf("torrent %p: piece %d: uncached priority: %v", t, piece, newPrio) if newPrio == PiecePriorityNone { - if !t._pendingPieces.Remove(bitmap.BitIndex(piece)) { + if !t._pendingPieces.Remove(int(piece)) { return } } else { - if !t._pendingPieces.Set(bitmap.BitIndex(piece), newPrio.BitmapPriority()) { + if !t._pendingPieces.Set(int(piece), newPrio.BitmapPriority()) { return } } @@ -1138,7 +1138,7 @@ return true } func (t *Torrent) piecePriority(piece pieceIndex) piecePriority { - prio, ok := t._pendingPieces.GetPriority(bitmap.BitIndex(piece)) + prio, ok := t._pendingPieces.GetPriority(piece) if !ok { return PiecePriorityNone } @@ -1286,7 +1286,7 @@ func (t *Torrent) readerPiecePriorities() (now, readahead bitmap.Bitmap) { t.forReaderOffsetPieces(func(begin, end pieceIndex) bool { if end > begin { now.Add(bitmap.BitIndex(begin)) - readahead.AddRange(bitmap.BitIndex(begin)+1, bitmap.BitIndex(end)) + readahead.AddRange(bitmap.BitRange(begin)+1, bitmap.BitRange(end)) } return true }) @@ -1966,7 +1966,7 @@ if !ok { return false } p := t.piece(pi) - t.piecesQueuedForHash.Remove(pi) + t.piecesQueuedForHash.Remove(bitmap.BitIndex(pi)) p.hashing = true t.publishPieceChange(pi) t.updatePiecePriority(pi) diff --git a/torrent_test.go b/torrent_test.go index d53aa693a4b8f7a53ea9860691560889513a41ae..ceff1feeac7c17b8c38dbf8426b930636d484c4a 100644 --- a/torrent_test.go +++ b/torrent_test.go @@ -9,6 +9,7 @@ "path/filepath" "testing" "github.com/anacrolix/missinggo" + "github.com/anacrolix/missinggo/v2/bitmap" "github.com/bradfitz/iter" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -96,8 +97,8 @@ r.SetReadahead(32 << 20) r.Seek(3500000, io.SeekStart) } assert.Len(b, t.readers, 7) - for i := 0; i < int(t.numPieces()); i += 3 { - t._completedPieces.Set(i, true) + for i := 0; i < t.numPieces(); i += 3 { + t._completedPieces.Set(bitmap.BitIndex(i), true) } t.DownloadPieces(0, t.numPieces()) for range iter.N(b.N) {