"strings"
"time"
+ "github.com/RoaringBitmap/roaring"
"github.com/anacrolix/log"
"github.com/anacrolix/missinggo/iter"
"github.com/anacrolix/missinggo/v2/bitmap"
PeerPrefersEncryption bool // as indicated by 'e' field in extension handshake
PeerListenPort int
// The pieces the peer has claimed to have.
- _peerPieces bitmap.Bitmap
+ _peerPieces roaring.Bitmap
// The peer has everything. This can occur due to a special message, when
// we may not even know the number of pieces in the torrent yet.
peerSentHaveAll bool
if !cn.t.haveInfo() {
return false, false
}
- return bitmap.Flip(cn._peerPieces, 0, bitmap.BitRange(cn.t.numPieces())).IsEmpty(), true
+ return roaring.Flip(&cn._peerPieces, 0, bitmap.BitRange(cn.t.numPieces())).IsEmpty(), true
}
func (cn *PeerConn) locker() *lockWithDeferreds {
}
func (cn *Peer) completedString() string {
- have := pieceIndex(cn._peerPieces.Len())
+ have := pieceIndex(cn._peerPieces.GetCardinality())
if cn.peerSentHaveAll {
have = cn.bestPeerNumPieces()
}
if !cn.peerHasPiece(piece) {
cn.t.incPieceAvailability(piece)
}
- cn._peerPieces.Set(bitmap.BitIndex(piece), true)
+ cn._peerPieces.Add(uint32(piece))
cn.t.maybeDropMutuallyCompletePeer(&cn.Peer)
if cn.updatePiecePriority(piece) {
cn.updateRequests()
cn.t.decPieceAvailability(i)
}
}
- cn._peerPieces.Set(bitmap.BitIndex(i), have)
+ if have {
+ cn._peerPieces.Add(uint32(i))
+ } else {
+ cn._peerPieces.Remove(uint32(i))
+ }
}
cn.peerPiecesChanged()
return nil
// Returns the pieces the peer could have based on their claims. If we don't know how many pieces
// are in the torrent, it could be a very large range the peer has sent HaveAll.
-func (cn *PeerConn) PeerPieces() bitmap.Bitmap {
+func (cn *PeerConn) PeerPieces() *roaring.Bitmap {
cn.locker().RLock()
defer cn.locker().RUnlock()
return cn.newPeerPieces()
}
// Returns a new Bitmap that includes bits for all pieces the peer could have based on their claims.
-func (cn *Peer) newPeerPieces() bitmap.Bitmap {
- ret := cn._peerPieces.Copy()
+func (cn *Peer) newPeerPieces() *roaring.Bitmap {
+ // TODO: Can we use copy on write?
+ ret := cn._peerPieces.Clone()
if cn.peerSentHaveAll {
if cn.t.haveInfo() {
ret.AddRange(0, bitmap.BitRange(cn.t.numPieces()))