From bb04cb88430d2609c5f0c67f71029d08c98960ec Mon Sep 17 00:00:00 2001
From: Matt Joiner <anacrolix@gmail.com>
Date: Tue, 22 Mar 2016 13:11:36 +1100
Subject: [PATCH] Tidy up bytesLeft calculations
This should fix a bug where completion is shown as negative in WriteStatus
---
misc.go | 8 ++++++++
piece.go | 50 ++++++++++++++++++++++++++++++++++++++++++--------
torrent.go | 24 +-----------------------
3 files changed, 51 insertions(+), 31 deletions(-)
diff --git a/misc.go b/misc.go
index ab6dcf78..8f13a179 100644
--- a/misc.go
+++ b/misc.go
@@ -121,3 +121,11 @@ func validateInfo(info *metainfo.Info) error {
}
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
+}
diff --git a/piece.go b/piece.go
index bcc09546..104602f3 100644
--- a/piece.go
+++ b/piece.go
@@ -69,14 +69,6 @@ func (p *piece) pendChunkIndex(i int) {
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)
}
@@ -112,3 +104,45 @@ func (p *piece) waitNoPendingWrites() {
}
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()
+}
diff --git a/torrent.go b/torrent.go
index 6453c508..598c1718 100644
--- a/torrent.go
+++ b/torrent.go
@@ -29,25 +29,6 @@ func (t *torrent) chunkIndexSpec(chunkIndex, piece int) chunkSpec {
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
@@ -511,11 +492,8 @@ func (t *torrent) MetaInfo() *metainfo.MetaInfo {
}
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
}
--
2.51.0