From 190d8e2f510c251cf93b582de1c0cbd842fa4d09 Mon Sep 17 00:00:00 2001
From: greatroar <@>
Date: Tue, 26 May 2020 13:35:07 +0200
Subject: [PATCH] Flatten backend.LimitedReadCloser structure
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This inlines the io.LimitedReader into the LimitedReadCloser body to
achieve fewer allocations. Results on linux/amd64:

name                                      old time/op    new time/op    delta
Backend/BenchmarkLoadPartialFile-8           412µs ± 4%     413µs ± 4%    ~     (p=0.634 n=17+17)
Backend/BenchmarkLoadPartialFileOffset-8     455µs ±13%     441µs ±10%    ~     (p=0.072 n=20+18)

name                                      old speed      new speed      delta
Backend/BenchmarkLoadPartialFile-8        10.2GB/s ± 3%  10.2GB/s ± 4%    ~     (p=0.817 n=16+17)
Backend/BenchmarkLoadPartialFileOffset-8  9.25GB/s ±12%  9.54GB/s ± 9%    ~     (p=0.072 n=20+18)

name                                      old alloc/op   new alloc/op   delta
Backend/BenchmarkLoadPartialFile-8            888B ± 0%      872B ± 0%  -1.80%  (p=0.000 n=15+15)
Backend/BenchmarkLoadPartialFileOffset-8      888B ± 0%      872B ± 0%  -1.80%  (p=0.000 n=15+15)

name                                      old allocs/op  new allocs/op  delta
Backend/BenchmarkLoadPartialFile-8            18.0 ± 0%      17.0 ± 0%  -5.56%  (p=0.000 n=15+15)
Backend/BenchmarkLoadPartialFileOffset-8      18.0 ± 0%      17.0 ± 0%  -5.56%  (p=0.000 n=15+15)
---
 internal/backend/utils.go | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/internal/backend/utils.go b/internal/backend/utils.go
index 1665aedc6..e6dc7a549 100644
--- a/internal/backend/utils.go
+++ b/internal/backend/utils.go
@@ -32,19 +32,14 @@ func LoadAll(ctx context.Context, buf []byte, be restic.Backend, h restic.Handle
 
 // LimitedReadCloser wraps io.LimitedReader and exposes the Close() method.
 type LimitedReadCloser struct {
-	io.ReadCloser
-	io.Reader
+	io.Closer
+	io.LimitedReader
 }
 
-// Read reads data from the limited reader.
-func (l *LimitedReadCloser) Read(p []byte) (int, error) {
-	return l.Reader.Read(p)
-}
-
-// LimitReadCloser returns a new reader wraps r in an io.LimitReader, but also
+// LimitReadCloser returns a new reader wraps r in an io.LimitedReader, but also
 // exposes the Close() method.
 func LimitReadCloser(r io.ReadCloser, n int64) *LimitedReadCloser {
-	return &LimitedReadCloser{ReadCloser: r, Reader: io.LimitReader(r, n)}
+	return &LimitedReadCloser{Closer: r, LimitedReader: io.LimitedReader{R: r, N: n}}
 }
 
 // DefaultLoad implements Backend.Load using lower-level openReader func