}
return nil
}
+
+func chunkIndexSpec(index int, pieceLength, chunkSize pp.Integer) chunkSpec {
+ ret := chunkSpec{pp.Integer(index) * chunkSize, chunkSize}
+ if ret.Begin+ret.Length > pieceLength {
+ ret.Length = pieceLength - ret.Begin
+ }
+ return ret
+}
p.DirtyChunks.Remove(i)
}
-func chunkIndexSpec(index int, pieceLength, chunkSize pp.Integer) chunkSpec {
- ret := chunkSpec{pp.Integer(index) * chunkSize, chunkSize}
- if ret.Begin+ret.Length > pieceLength {
- ret.Length = pieceLength - ret.Begin
- }
- return ret
-}
-
func (p *piece) numChunks() int {
return p.t.pieceNumChunks(p.index)
}
}
p.pendingWritesMutex.Unlock()
}
+
+func (p *piece) chunkIndexDirty(chunk int) bool {
+ return p.DirtyChunks.Contains(chunk)
+}
+
+func (p *piece) chunkIndexSpec(chunk int) chunkSpec {
+ return chunkIndexSpec(chunk, p.length(), p.chunkSize())
+}
+
+func (p *piece) numDirtyBytes() (ret pp.Integer) {
+ defer func() {
+ if ret > p.length() {
+ panic("too many dirty bytes")
+ }
+ }()
+ numRegularDirtyChunks := p.numDirtyChunks()
+ if p.chunkIndexDirty(p.numChunks() - 1) {
+ numRegularDirtyChunks--
+ ret += p.chunkIndexSpec(p.lastChunkIndex()).Length
+ }
+ ret += pp.Integer(numRegularDirtyChunks) * p.chunkSize()
+ return
+}
+
+func (p *piece) length() pp.Integer {
+ return p.t.pieceLength(p.index)
+}
+
+func (p *piece) chunkSize() pp.Integer {
+ return p.t.chunkSize
+}
+
+func (p *piece) lastChunkIndex() int {
+ return p.numChunks() - 1
+}
+
+func (p *piece) bytesLeft() (ret pp.Integer) {
+ if p.t.pieceComplete(p.index) {
+ return 0
+ }
+ return p.length() - p.numDirtyBytes()
+}
return chunkIndexSpec(chunkIndex, t.pieceLength(piece), t.chunkSize)
}
-func (t *torrent) pieceNumPendingBytes(index int) (count pp.Integer) {
- if t.pieceComplete(index) {
- return
- }
- piece := &t.Pieces[index]
- count = t.pieceLength(index)
- if !piece.EverHashed {
- return
- }
- regularDirty := piece.numDirtyChunks()
- lastChunkIndex := t.pieceNumChunks(index) - 1
- if piece.pendingChunkIndex(lastChunkIndex) {
- regularDirty--
- count -= t.chunkIndexSpec(lastChunkIndex, index).Length
- }
- count -= pp.Integer(regularDirty) * t.chunkSize
- return
-}
-
type peersKey struct {
IPBytes string
Port int
}
func (t *torrent) bytesLeft() (left int64) {
- if !t.haveInfo() {
- return -1
- }
for i := 0; i < t.numPieces(); i++ {
- left += int64(t.pieceNumPendingBytes(i))
+ left += int64(t.Pieces[i].bytesLeft())
}
return
}