client-peerconn_test.go | 3 +-- client.go | 3 +-- file.go | 9 ++++----- go.mod | 3 +-- go.sum | 7 ++----- peer.go | 7 +++---- peerconn.go | 29 +++++++++++++++-------------- piece.go | 5 ++--- requesting.go | 2 +- test/leecher-storage.go | 3 +-- torrent-piece-request-order.go | 6 +++--- torrent.go | 46 ++++++++++++++++++++++------------------------ torrent_test.go | 3 +-- diff --git a/client-peerconn_test.go b/client-peerconn_test.go index 372b4af4dfbd60aa51e8252cd90046932bae573c..30110b8d589175f43100f72b5596443884b9e6c6 100644 --- a/client-peerconn_test.go +++ b/client-peerconn_test.go @@ -9,7 +9,6 @@ "testing/iotest" "github.com/anacrolix/chansync" "github.com/anacrolix/missinggo/v2" - "github.com/anacrolix/missinggo/v2/bitmap" "github.com/go-quicktest/qt" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -164,7 +163,7 @@ foundSeeder := false for _, pc := range leecherPeerConns { completed := pc.PeerPieces().GetCardinality() t.Logf("peer conn %v has %v completed pieces", pc, completed) - if completed == bitmap.BitRange(leecherTorrent.Info().NumPieces()) { + if completed == uint64(leecherTorrent.Info().NumPieces()) { foundSeeder = true } } diff --git a/client.go b/client.go index fbc8c8264458504f389649e72298caaa36360c07..66a826d3477218f53adcea4b8c19b5b285552cab 100644 --- a/client.go +++ b/client.go @@ -30,7 +30,6 @@ g "github.com/anacrolix/generics" "github.com/anacrolix/generics/heap" "github.com/anacrolix/log" "github.com/anacrolix/missinggo/v2" - "github.com/anacrolix/missinggo/v2/bitmap" "github.com/anacrolix/missinggo/v2/panicif" "github.com/anacrolix/missinggo/v2/pproffd" "github.com/anacrolix/sync" @@ -1282,7 +1281,7 @@ func() { if pc.fastEnabled() { if t.haveAllPieces() { pc.write(pp.Message{Type: pp.HaveAll}) - pc.sentHaves.AddRange(0, bitmap.BitRange(pc.t.NumPieces())) + pc.sentHaves.AddRange(0, uint64(pc.t.NumPieces())) return } else if !t.haveAnyPieces() { pc.write(pp.Message{Type: pp.HaveNone}) diff --git a/file.go b/file.go index abf4070441023a046d1523037636f700e623ec02..f535a6a73c427d7660ddb96fc5eef0b51c7509de 100644 --- a/file.go +++ b/file.go @@ -5,7 +5,6 @@ "iter" "github.com/RoaringBitmap/roaring/v2" g "github.com/anacrolix/generics" - "github.com/anacrolix/missinggo/v2/bitmap" "github.com/anacrolix/torrent/metainfo" infohash_v2 "github.com/anacrolix/torrent/types/infohash-v2" @@ -78,7 +77,7 @@ return } noCompletedMiddlePieces := roaring.New() - noCompletedMiddlePieces.AddRange(bitmap.BitRange(fileFirstPieceIndex), bitmap.BitRange(fileEndPieceIndex)) + noCompletedMiddlePieces.AddRange(uint64(fileFirstPieceIndex), uint64(fileEndPieceIndex)) noCompletedMiddlePieces.AndNot(torrentCompletedPieces) noCompletedMiddlePieces.Iterate(func(pieceIndex uint32) bool { i := int(pieceIndex) @@ -114,8 +113,8 @@ } // //numPiecesSpanned := f.EndPieceIndex() - f.BeginPieceIndex() //completedMiddlePieces := f.t._completedPieces.Clone() - //completedMiddlePieces.RemoveRange(0, bitmap.BitRange(f.BeginPieceIndex()+1)) - //completedMiddlePieces.RemoveRange(bitmap.BitRange(f.EndPieceIndex()-1), bitmap.ToEnd) + //completedMiddlePieces.RemoveRange(0, uint64(f.BeginPieceIndex()+1)) + //completedMiddlePieces.RemoveRange(uint64(f.EndPieceIndex()-1), roaring.MaxRange) //left += int64(numPiecesSpanned-2-pieceIndex(completedMiddlePieces.GetCardinality())) * torrentUsualPieceSize return } @@ -127,7 +126,7 @@ f.BeginPieceIndex(), f.EndPieceIndex(), f.offset, f.length, - &f.t._completedPieces, + &f.t._completedPieces.Bitmap, func(pieceIndex int) int64 { return int64(f.t.piece(pieceIndex).numDirtyBytes()) }, diff --git a/go.mod b/go.mod index 3d087e2fef441d15c0a71155750e91b295f18f57..2e35e5525c06793028311752d94f0f33b2e11bd8 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,7 @@ go 1.24.0 require ( - github.com/RoaringBitmap/roaring v1.2.3 - github.com/RoaringBitmap/roaring/v2 v2.15.0 + github.com/RoaringBitmap/roaring/v2 v2.16.0 github.com/alexflint/go-arg v1.4.3 github.com/anacrolix/bargle v1.0.0 github.com/anacrolix/bargle/v2 v2.0.0 diff --git a/go.sum b/go.sum index 5ea651437b9feb9040c5e43894a5d100b3b8d59e..fb1d2b13f720836ef5ec479c48229e83c68160b4 100644 --- a/go.sum +++ b/go.sum @@ -42,10 +42,8 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w= github.com/RoaringBitmap/roaring v0.4.17/go.mod h1:D3qVegWTmfCaX4Bl5CrBE9hfrSrrXIr8KVNvRsDi1NI= github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo= -github.com/RoaringBitmap/roaring v1.2.3 h1:yqreLINqIrX22ErkKI0vY47/ivtJr6n+kMhVOVmhWBY= -github.com/RoaringBitmap/roaring v1.2.3/go.mod h1:plvDsJQpxOC5bw8LRteu/MLWHsHez/3y6cubLI4/1yE= -github.com/RoaringBitmap/roaring/v2 v2.15.0 h1:gCbixa3UiG7g6WUZNVOfEEg2HTc1vR4OVdMkX8t1ZFc= -github.com/RoaringBitmap/roaring/v2 v2.15.0/go.mod h1:eq4wdNXxtJIS/oikeCzdX1rBzek7ANzbth041hrU8Q4= +github.com/RoaringBitmap/roaring/v2 v2.16.0 h1:Kys1UNf49d5W8Tq3bpuAhIr/Z8/yPB+59CO8A6c/BbE= +github.com/RoaringBitmap/roaring/v2 v2.16.0/go.mod h1:eq4wdNXxtJIS/oikeCzdX1rBzek7ANzbth041hrU8Q4= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0 h1:byYvvbfSo3+9efR4IeReh77gVs4PnNDR3AMOE9NJ7a0= @@ -144,7 +142,6 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.24.2 h1:M7/NzVbsytmtfHbumG+K2bremQPMJuqv1JD3vOaFxp0= github.com/bits-and-blooms/bitset v1.24.2/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bradfitz/iter v0.0.0-20140124041915-454541ec3da2/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo= diff --git a/peer.go b/peer.go index 9a5ae4fd3bd11030e644a586daf49107aa6bc2ab..b1c9bd9f4b3f80038fd265514785103afe5e369a 100644 --- a/peer.go +++ b/peer.go @@ -15,7 +15,6 @@ "github.com/RoaringBitmap/roaring/v2" "github.com/anacrolix/chansync" g "github.com/anacrolix/generics" "github.com/anacrolix/log" - "github.com/anacrolix/missinggo/v2/bitmap" "github.com/anacrolix/missinggo/v2/panicif" "github.com/anacrolix/multiless" @@ -474,7 +473,7 @@ } if !c.t.haveInfo() { return !c.peerPieces().IsEmpty() } - return c.peerPieces().Intersects(&c.t._pendingPieces) + return c.peerPieces().Intersects(&c.t._pendingPieces.Bitmap) } func (c *Peer) peerPriority() (peerPriority, error) { @@ -510,9 +509,9 @@ // TODO: Can we use copy on write? ret := cn.peerPieces().Clone() if all, _ := cn.peerHasAllPieces(); all { if cn.t.haveInfo() { - ret.AddRange(0, bitmap.BitRange(cn.t.numPieces())) + ret.AddRange(0, uint64(cn.t.numPieces())) } else { - ret.AddRange(0, bitmap.ToEnd) + ret.AddRange(0, roaring.MaxRange) } } return ret diff --git a/peerconn.go b/peerconn.go index d7418edbdf152981b550f6d6625c0336dcb0abd6..127a2d6c5519cc02255b2c307a4e6b124c008c7f 100644 --- a/peerconn.go +++ b/peerconn.go @@ -20,11 +20,12 @@ "github.com/RoaringBitmap/roaring/v2" "github.com/anacrolix/chansync" g "github.com/anacrolix/generics" "github.com/anacrolix/log" - "github.com/anacrolix/missinggo/v2/bitmap" "github.com/anacrolix/missinggo/v2/panicif" "github.com/anacrolix/multiless" "golang.org/x/time/rate" + + typedRoaring "github.com/anacrolix/torrent/typed-roaring" "github.com/anacrolix/torrent/bencode" requestStrategy "github.com/anacrolix/torrent/internal/request-strategy" @@ -48,7 +49,7 @@ Peer // Indexed by metadata piece, set to true if posted and pending a response. metadataRequests []bool - sentHaves bitmap.Bitmap + sentHaves typedRoaring.Bitmap[pieceIndex] // Chunks that we might reasonably expect to receive from the peer. Due to latency, buffering, // and implementation differences, we may receive chunks that are no longer in the set of // requests actually want. This could use a roaring.BSI if the memory use becomes noticeable. @@ -93,7 +94,7 @@ uploadTimer *time.Timer pex pexConnState // The pieces the peer has claimed to have. - _peerPieces roaring.Bitmap + _peerPieces typedRoaring.Bitmap[pieceIndex] // 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 @@ -216,12 +217,12 @@ // 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.BitRange(num), bitmap.ToEnd) + cn._peerPieces.RemoveRange(uint64(num), roaring.MaxRange) cn.peerPiecesChanged() } func (cn *PeerConn) peerPieces() *roaring.Bitmap { - return &cn._peerPieces + return &cn._peerPieces.Bitmap } func (cn *PeerConn) connectionFlags() string { @@ -421,18 +422,18 @@ cn.upload(cn.write) } func (cn *PeerConn) have(piece pieceIndex) { - if cn.sentHaves.Get(bitmap.BitIndex(piece)) { + if cn.sentHaves.Contains(piece) { return } cn.write(pp.Message{ Type: pp.Have, Index: pp.Integer(piece), }) - cn.sentHaves.Add(bitmap.BitIndex(piece)) + cn.sentHaves.Add(piece) } func (cn *PeerConn) postBitfield() { - if cn.sentHaves.Len() != 0 { + if !cn.sentHaves.IsEmpty() { panic("bitfield must be first have-related message sent") } if !cn.t.haveAnyPieces() { @@ -442,7 +443,7 @@ cn.write(pp.Message{ Type: pp.Bitfield, Bitfield: cn.t.bitfield(), }) - cn.sentHaves = bitmap.Bitmap{cn.t._completedPieces.Clone()} + cn.sentHaves = cn.t._completedPieces.Clone() } func (cn *PeerConn) handleOnNeedUpdateRequests() { @@ -467,7 +468,7 @@ cn.raisePeerMinPieces(piece + 1) if !cn.peerHasPiece(piece) { cn.t.incPieceAvailability(piece) } - cn._peerPieces.Add(uint32(piece)) + cn._peerPieces.Add(piece) if cn.t.wantPieceIndex(piece) { cn.onNeedUpdateRequests("have") } @@ -503,13 +504,13 @@ if !cn._peerPieces.IsEmpty() { panic("if peer has all, we expect no individual peer pieces to be set") } } else { - bm.Xor(&cn._peerPieces) + bm.Xor(&cn._peerPieces.Bitmap) } cn.peerSentHaveAll = false // bm is now 'on' for pieces that are changing bm.Iterate(func(x uint32) bool { pi := pieceIndex(x) - if cn._peerPieces.Contains(x) { + if cn._peerPieces.Contains(pi) { // Then we must be losing this piece cn.t.decPieceAvailability(pi) } else { @@ -535,8 +536,8 @@ func (cn *PeerConn) onPeerHasAllPiecesNoTriggers() { t := cn.t if t.haveInfo() { - cn._peerPieces.Iterate(func(x uint32) bool { - t.decPieceAvailability(pieceIndex(x)) + cn._peerPieces.Iterate(func(x pieceIndex) bool { + t.decPieceAvailability(x) return true }) } diff --git a/piece.go b/piece.go index 1252e205ecf3ba6b92a6f32c34f482362af1cc2a..588831d39916cc4311fa488b18a3372d793fec3d 100644 --- a/piece.go +++ b/piece.go @@ -10,7 +10,6 @@ "github.com/RoaringBitmap/roaring/v2" "github.com/anacrolix/chansync" g "github.com/anacrolix/generics" - "github.com/anacrolix/missinggo/v2/bitmap" "github.com/anacrolix/missinggo/v2/panicif" "github.com/anacrolix/torrent/merkle" @@ -277,13 +276,13 @@ func (p *Piece) purePriority() (ret PiecePriority) { for _, f := range p.files() { ret.Raise(f.prio) } - if p.t.readerNowPieces().Contains(bitmap.BitIndex(p.index)) { + if p.t.readerNowPieces().Contains(p.index) { ret.Raise(PiecePriorityNow) } // if t._readerNowPieces.Contains(piece - 1) { // return PiecePriorityNext // } - if p.t.readerReadaheadPieces().Contains(bitmap.BitIndex(p.index)) { + if p.t.readerReadaheadPieces().Contains(p.index) { ret.Raise(PiecePriorityReadahead) } ret.Raise(p.priority) diff --git a/requesting.go b/requesting.go index b903739dbead5d8296945a8e01dad57f8f036b1b..85b72d24042f4afbce96fc389c5470696fc5ea6e 100644 --- a/requesting.go +++ b/requesting.go @@ -318,7 +318,7 @@ if all || !known { return false } // Allow losing interest if we have all the pieces the peer has. - return roaring.AndNot(p.peerPieces(), &p.t._completedPieces).IsEmpty() + return roaring.AndNot(p.peerPieces(), &p.t._completedPieces.Bitmap).IsEmpty() } // Transmit/action the request state to the peer. This includes work-stealing from other peers and diff --git a/test/leecher-storage.go b/test/leecher-storage.go index b71df0c8ceb79582dad5a63a7cab119836686230..773c3f837617f4ac1ca566b154f2d14969150003 100644 --- a/test/leecher-storage.go +++ b/test/leecher-storage.go @@ -9,7 +9,6 @@ "runtime" "testing" "testing/iotest" - "github.com/anacrolix/missinggo/v2/bitmap" qt "github.com/go-quicktest/qt" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -227,7 +226,7 @@ foundSeeder := false for _, pc := range leecherPeerConns { completed := pc.PeerPieces().GetCardinality() t.Logf("peer conn %v has %v completed pieces", pc, completed) - if completed == bitmap.BitRange(leecherTorrent.Info().NumPieces()) { + if completed == uint64(leecherTorrent.Info().NumPieces()) { foundSeeder = true } } diff --git a/torrent-piece-request-order.go b/torrent-piece-request-order.go index f3b8da98fe59ce9cae669aba9676927f2f755de3..cb249591818e6cbba3330496bc96ef02e3cd6715 100644 --- a/torrent-piece-request-order.go +++ b/torrent-piece-request-order.go @@ -110,10 +110,10 @@ continue } proBitmap.Add(uint32(item.Key.Index)) } - if !proBitmap.Equals(&t._pendingPieces) { - intersection := roaring.And(&proBitmap, &t._pendingPieces) + if !proBitmap.Equals(&t._pendingPieces.Bitmap) { + intersection := roaring.And(&proBitmap, &t._pendingPieces.Bitmap) exclPro := roaring.AndNot(&proBitmap, intersection) - exclPending := roaring.AndNot(&t._pendingPieces, intersection) + exclPending := roaring.AndNot(&t._pendingPieces.Bitmap, intersection) panic(fmt.Sprintf("piece request order has %v and pending pieces has %v", exclPro.String(), exclPending.String())) } } diff --git a/torrent.go b/torrent.go index 73ef35eafbf1f426b22add23e847260c19e26d21..2e39ec1275ad7b7a5c52e2a3b4ad5739b2421b55 100644 --- a/torrent.go +++ b/torrent.go @@ -32,7 +32,6 @@ "github.com/anacrolix/dht/v2" g "github.com/anacrolix/generics" "github.com/anacrolix/log" "github.com/anacrolix/missinggo/v2" - "github.com/anacrolix/missinggo/v2/bitmap" "github.com/anacrolix/missinggo/v2/panicif" "github.com/anacrolix/missinggo/v2/pubsub" "github.com/anacrolix/multiless" @@ -171,15 +170,15 @@ // IsSet from nameMu. Switching will probably only increase memory use. gotMetainfoC chan struct{} readers map[*reader]struct{} - _readerNowPieces bitmap.Bitmap - _readerReadaheadPieces bitmap.Bitmap + _readerNowPieces typedRoaring.Bitmap[pieceIndex] + _readerReadaheadPieces typedRoaring.Bitmap[pieceIndex] // A cache of pieces we need to get. Calculated from various piece and file priorities and // completion states elsewhere. Includes piece data and piece v2 hashes. Used for efficient set // logic with peer pieces. - _pendingPieces roaring.Bitmap + _pendingPieces typedRoaring.Bitmap[pieceIndex] // A cache of completed piece indices. - _completedPieces roaring.Bitmap + _completedPieces typedRoaring.Bitmap[pieceIndex] // Pieces that need to be hashed. piecesQueuedForHash typedRoaring.Bitmap[pieceIndex] activePieceHashes int @@ -275,12 +274,12 @@ t.updatePieceRequestOrderPiece(i) } } -func (t *Torrent) readerNowPieces() bitmap.Bitmap { - return t._readerNowPieces +func (t *Torrent) readerNowPieces() *typedRoaring.Bitmap[pieceIndex] { + return &t._readerNowPieces } -func (t *Torrent) readerReadaheadPieces() bitmap.Bitmap { - return t._readerReadaheadPieces +func (t *Torrent) readerReadaheadPieces() *typedRoaring.Bitmap[pieceIndex] { + return &t._readerReadaheadPieces } func (t *Torrent) ignorePieceForRequests(i pieceIndex) bool { @@ -339,7 +338,7 @@ } } func (t *Torrent) pieceComplete(piece pieceIndex) bool { - return t._completedPieces.Contains(bitmap.BitIndex(piece)) + return t._completedPieces.Contains(piece) } func (t *Torrent) pieceCompleteUncached(piece pieceIndex) (ret storage.Completion) { @@ -1061,7 +1060,7 @@ roaring.Flip(b, 0, end).Iterate(cb) } func (t *Torrent) bytesLeft() (left int64) { - iterFlipped(&t._completedPieces, uint64(t.numPieces()), func(x uint32) bool { + iterFlipped(&t._completedPieces.Bitmap, uint64(t.numPieces()), func(x uint32) bool { p := t.piece(pieceIndex(x)) left += int64(p.length() - p.numDirtyBytes()) return true @@ -1186,7 +1185,7 @@ } func (t *Torrent) bitfield() (bf []bool) { bf = make([]bool, t.numPieces()) - t._completedPieces.Iterate(func(piece uint32) (again bool) { + t._completedPieces.Iterate(func(piece pieceIndex) (again bool) { bf[piece] = true return true }) @@ -1363,7 +1362,7 @@ func (t *Torrent) haveAllPieces() bool { if !t.haveInfo() { return false } - return t._completedPieces.GetCardinality() == bitmap.BitRange(t.numPieces()) + return t._completedPieces.GetCardinality() == uint64(t.numPieces()) } func (t *Torrent) havePiece(index pieceIndex) bool { @@ -1411,7 +1410,7 @@ return chunkIndexType(cs.Begin / chunkSize) } func (t *Torrent) wantPieceIndex(index pieceIndex) bool { - return !t._pendingPieces.IsEmpty() && t._pendingPieces.Contains(uint32(index)) + return !t._pendingPieces.IsEmpty() && t._pendingPieces.Contains(index) } // A pool of []*PeerConn, to reduce allocations in functions that need to index or sort Torrent @@ -1530,7 +1529,7 @@ t.openNewConns() } func (t *Torrent) updatePeerRequestsForPiece(piece pieceIndex, reason updateRequestReason) { - if !t._pendingPieces.Contains(uint32(piece)) { + if !t._pendingPieces.Contains(piece) { // Non-pending pieces are usually cancelled more synchronously. return } @@ -1564,9 +1563,9 @@ func (t *Torrent) updatePendingPieces(piece pieceIndex) bool { p := t.piece(piece) newPrio := p.effectivePriority() if newPrio == PiecePriorityNone && p.haveHash() { - return t._pendingPieces.CheckedRemove(uint32(piece)) + return t._pendingPieces.CheckedRemove(piece) } else { - return t._pendingPieces.CheckedAdd(uint32(piece)) + return t._pendingPieces.CheckedAdd(piece) } } @@ -1797,9 +1796,8 @@ p.storageCompletionOk = uncached.Ok if !p.storageCompletionHasBeenOk { p.storageCompletionHasBeenOk = p.storageCompletionOk } - x := uint32(piece) if uncached.Ok && uncached.Value { - if t._completedPieces.CheckedAdd(x) { + if t._completedPieces.CheckedAdd(piece) { // This is missing conditions... do we care? if t.haveAllPieces() { // We may be able to send Completed event. @@ -1807,7 +1805,7 @@ t.deferUpdateRegularTrackerAnnouncing() } } } else { - t._completedPieces.Remove(x) + t._completedPieces.Remove(piece) } return changed @@ -1867,11 +1865,11 @@ } return nil } -func (t *Torrent) readerPiecePriorities() (now, readahead bitmap.Bitmap) { +func (t *Torrent) readerPiecePriorities() (now, readahead typedRoaring.Bitmap[pieceIndex]) { t.forReaderOffsetPieces(func(begin, end pieceIndex) bool { if end > begin { - now.Add(bitmap.BitIndex(begin)) - readahead.AddRange(bitmap.BitRange(begin)+1, bitmap.BitRange(end)) + now.Add(begin) + readahead.AddRange(uint64(begin)+1, uint64(end)) } return true }) @@ -3780,7 +3778,7 @@ } // Check for mixed completion. var r roaring.Bitmap r.AddRange(uint64(beginPieceIndex), uint64(endPieceIndex)) - switch t._completedPieces.AndCardinality(&r) { + switch t._completedPieces.Bitmap.AndCardinality(&r) { case 0, uint64(endPieceIndex - beginPieceIndex): // We have either no pieces or all pieces and no dirty chunks. return false diff --git a/torrent_test.go b/torrent_test.go index 32a9fdab75e9514b0b2d8fe5f51e8ee8a2b99286..61e61bfe830683c1840eac2c6d2978283d3815dd 100644 --- a/torrent_test.go +++ b/torrent_test.go @@ -11,7 +11,6 @@ "testing" g "github.com/anacrolix/generics" "github.com/anacrolix/missinggo/v2" - "github.com/anacrolix/missinggo/v2/bitmap" "github.com/go-quicktest/qt" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -101,7 +100,7 @@ r.Seek(3500000, io.SeekStart) } assert.Len(b, t.readers, 7) for i := 0; i < t.numPieces(); i += 3 { - t._completedPieces.Add(bitmap.BitIndex(i)) + t._completedPieces.Add(i) } t.DownloadPieces(0, t.numPieces()) for b.Loop() {