7 "github.com/bradfitz/iter"
9 pp "github.com/anacrolix/torrent/peer_protocol"
12 // Piece priority describes the importance of obtaining a particular piece.
14 type piecePriority byte
17 PiecePriorityNone piecePriority = iota // Not wanted.
18 PiecePriorityNormal // Wanted.
19 PiecePriorityReadahead // May be required soon.
20 PiecePriorityNext // Succeeds a piece where a read occurred.
21 PiecePriorityNow // A read occurred in this piece.
25 // The completed piece SHA1 hash, from the metainfo "pieces" field.
27 // Chunks we've written to since the last check. The chunk offset and
28 // length can be determined by the request chunkSize in use.
33 Priority piecePriority
34 PublicPieceState PieceState
36 pendingWritesMutex sync.Mutex
38 noPendingWrites sync.Cond
41 func (p *piece) pendingChunk(cs chunkSpec, chunkSize pp.Integer) bool {
42 ci := chunkIndex(cs, chunkSize)
43 if ci >= len(p.DirtyChunks) {
46 return !p.DirtyChunks[ci]
49 func (p *piece) numDirtyChunks() (ret int) {
50 for _, dirty := range p.DirtyChunks {
58 func (p *piece) unpendChunkIndex(i int) {
59 for i >= len(p.DirtyChunks) {
60 p.DirtyChunks = append(p.DirtyChunks, false)
62 p.DirtyChunks[i] = true
65 func chunkIndexSpec(index int, pieceLength, chunkSize pp.Integer) chunkSpec {
66 ret := chunkSpec{pp.Integer(index) * chunkSize, chunkSize}
67 if ret.Begin+ret.Length > pieceLength {
68 ret.Length = pieceLength - ret.Begin
73 func (p *piece) shuffledPendingChunkSpecs(t *torrent, piece int) (css []chunkSpec) {
75 // log.Println(piece, css)
77 numPending := t.pieceNumPendingChunks(piece)
81 css = make([]chunkSpec, 0, numPending)
82 for ci := range iter.N(t.pieceNumChunks(piece)) {
83 if ci >= len(p.DirtyChunks) || !p.DirtyChunks[ci] {
84 css = append(css, t.chunkIndexSpec(ci, piece))
92 css[i], css[j] = css[j], css[i]