From 10d5e6234e667d0d632c1820a44e1a764b98ba10 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Thu, 9 Sep 2021 22:19:29 +1000 Subject: [PATCH] Don't readahead until a read occurs --- reader.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/reader.go b/reader.go index 78a2ff00..0d39522f 100644 --- a/reader.go +++ b/reader.go @@ -40,8 +40,11 @@ type reader struct { opMu sync.Mutex // Required when modifying pos and readahead, or reading them without opMu. - mu sync.Locker - pos int64 + mu sync.Locker + pos int64 + // Reads have been initiated since the last seek. This is used to prevent readahead occuring + // after a seek or with a new reader at the starting position. + reading bool readahead int64 // Function to dynamically calculate readahead. If nil, readahead is static. readaheadFunc func() int64 @@ -113,6 +116,9 @@ func (r *reader) piecesUncached() (ret pieceRange) { // anything. ra = 1 } + if !r.reading { + ra = 0 + } if ra > r.length-r.pos { ra = r.length - r.pos } @@ -129,6 +135,14 @@ func (r *reader) ReadContext(ctx context.Context, b []byte) (n int, err error) { // seems reasonable, but unusual. r.opMu.Lock() defer r.opMu.Unlock() + if len(b) > 0 { + r.reading = true + // TODO: Rework reader piece priorities so we don't have to push updates in to the Client + // and take the lock here. + r.mu.Lock() + r.posChanged() + r.mu.Unlock() + } n, err = r.readOnceAt(ctx, b, r.pos) if n == 0 { if err == nil && len(b) > 0 { @@ -280,6 +294,7 @@ func (r *reader) Seek(off int64, whence int) (newPos int64, err error) { if newPos == r.pos { return } + r.reading = false r.pos = newPos r.contiguousReadStartPos = newPos