6 "github.com/anacrolix/missinggo/bitmap"
8 pp "github.com/anacrolix/torrent/peer_protocol"
11 // Piece priority describes the importance of obtaining a particular piece.
13 type piecePriority byte
15 func (me *piecePriority) Raise(maybe piecePriority) {
22 PiecePriorityNone piecePriority = iota // Not wanted.
23 PiecePriorityNormal // Wanted.
24 PiecePriorityReadahead // May be required soon.
25 PiecePriorityNext // Succeeds a piece where a read occurred.
26 PiecePriorityNow // A read occurred in this piece.
30 // The completed piece SHA1 hash, from the metainfo "pieces" field.
34 // Chunks we've written to since the last check. The chunk offset and
35 // length can be determined by the request chunkSize in use.
36 DirtyChunks bitmap.Bitmap
40 PublicPieceState PieceState
41 priority piecePriority
43 pendingWritesMutex sync.Mutex
45 noPendingWrites sync.Cond
48 func (p *piece) pendingChunkIndex(chunkIndex int) bool {
49 return !p.DirtyChunks.Contains(chunkIndex)
52 func (p *piece) pendingChunk(cs chunkSpec, chunkSize pp.Integer) bool {
53 return p.pendingChunkIndex(chunkIndex(cs, chunkSize))
56 func (p *piece) hasDirtyChunks() bool {
57 return p.DirtyChunks.Len() != 0
60 func (p *piece) numDirtyChunks() (ret int) {
61 return p.DirtyChunks.Len()
64 func (p *piece) unpendChunkIndex(i int) {
68 func (p *piece) pendChunkIndex(i int) {
69 p.DirtyChunks.Remove(i)
72 func chunkIndexSpec(index int, pieceLength, chunkSize pp.Integer) chunkSpec {
73 ret := chunkSpec{pp.Integer(index) * chunkSize, chunkSize}
74 if ret.Begin+ret.Length > pieceLength {
75 ret.Length = pieceLength - ret.Begin
80 func (p *piece) numChunks() int {
81 return p.t.pieceNumChunks(p.index)
84 func (p *piece) undirtiedChunkIndices() (ret bitmap.Bitmap) {
85 ret = p.DirtyChunks.Copy()
86 ret.FlipRange(0, p.numChunks())
90 func (p *piece) incrementPendingWrites() {
91 p.pendingWritesMutex.Lock()
93 p.pendingWritesMutex.Unlock()
96 func (p *piece) decrementPendingWrites() {
97 p.pendingWritesMutex.Lock()
98 if p.pendingWrites == 0 {
102 if p.pendingWrites == 0 {
103 p.noPendingWrites.Broadcast()
105 p.pendingWritesMutex.Unlock()
108 func (p *piece) waitNoPendingWrites() {
109 p.pendingWritesMutex.Lock()
110 for p.pendingWrites != 0 {
111 p.noPendingWrites.Wait()
113 p.pendingWritesMutex.Unlock()