"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"
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})
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
}
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 {
// 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()
}
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,
// 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
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 {
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
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)
}
}
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)
}
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)
}
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
}
}
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 {
}
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 {
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) {
}
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 {
"time"
"unsafe"
+ "github.com/anacrolix/missinggo/v2/bitmap"
request_strategy "github.com/anacrolix/torrent/request-strategy"
"github.com/anacrolix/torrent/types"
)
},
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),
"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"
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
}
}
}
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
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) {
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 {
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)
}
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() {
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
}
}
}
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
}
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
})
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)
"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"
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) {