Browse code

pkg/tarsum: add dynamic buffer sizing

This commit makes tarsum buffer allocation dynamic. This change
is required to avoid allocating memory excessively after the archive
buffering changes.

Docker-DCO-1.1-Signed-off-by: Cristian Staretu <cristian.staretu@gmail.com> (github: unclejack)

unclejack authored on 2014/09/06 21:29:19
Showing 1 changed files
... ...
@@ -16,6 +16,12 @@ import (
16 16
 	"github.com/docker/docker/pkg/log"
17 17
 )
18 18
 
19
+const (
20
+	buf8K  = 8 * 1024
21
+	buf16K = 16 * 1024
22
+	buf32K = 32 * 1024
23
+)
24
+
19 25
 type TarSum struct {
20 26
 	io.Reader
21 27
 	tarR               *tar.Reader
... ...
@@ -23,7 +29,7 @@ type TarSum struct {
23 23
 	gz                 writeCloseFlusher
24 24
 	bufTar             *bytes.Buffer
25 25
 	bufGz              *bytes.Buffer
26
-	bufData            [8192]byte
26
+	bufData            []byte
27 27
 	h                  hash.Hash
28 28
 	sums               map[string]string
29 29
 	currentFile        string
... ...
@@ -93,12 +99,19 @@ func (ts *TarSum) Read(buf []byte) (int, error) {
93 93
 	if ts.finished {
94 94
 		return ts.bufGz.Read(buf)
95 95
 	}
96
-	var buf2 []byte
97
-	if len(buf) > 8192 {
98
-		buf2 = make([]byte, len(buf), cap(buf))
99
-	} else {
100
-		buf2 = ts.bufData[:len(buf)-1]
96
+	if ts.bufData == nil {
97
+		switch {
98
+		case len(buf) <= buf8K:
99
+			ts.bufData = make([]byte, buf8K)
100
+		case len(buf) <= buf16K:
101
+			ts.bufData = make([]byte, buf16K)
102
+		case len(buf) <= buf32K:
103
+			ts.bufData = make([]byte, buf32K)
104
+		default:
105
+			ts.bufData = make([]byte, len(buf))
106
+		}
101 107
 	}
108
+	buf2 := ts.bufData[:len(buf)-1]
102 109
 
103 110
 	n, err := ts.tarR.Read(buf2)
104 111
 	if err != nil {