Skip to content

Commit 4c935cf

Browse files
committed
parser: optimize memory usage on env processing
Reuse internal buffers used to build up words for variable expansion. Signed-off-by: Tonis Tiigi <[email protected]>
1 parent 0cdb0e3 commit 4c935cf

File tree

1 file changed

+21
-15
lines changed
  • frontend/dockerfile/shell

1 file changed

+21
-15
lines changed

frontend/dockerfile/shell/lex.go

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,12 @@ func (s *Lex) process(word string, env map[string]string) (ProcessWordResult, er
105105

106106
type shellWord struct {
107107
*Lex
108-
scanner scanner.Scanner
109-
envs map[string]string
110-
rawEscapes bool
111-
matches map[string]struct{}
112-
nonmatches map[string]struct{}
108+
wordsBuffer strings.Builder
109+
scanner scanner.Scanner
110+
envs map[string]string
111+
rawEscapes bool
112+
matches map[string]struct{}
113+
nonmatches map[string]struct{}
113114
}
114115

115116
func (sw *shellWord) process(source string) (string, []string, error) {
@@ -121,16 +122,16 @@ func (sw *shellWord) process(source string) (string, []string, error) {
121122
}
122123

123124
type wordsStruct struct {
124-
word string
125+
buf *strings.Builder
125126
words []string
126127
inWord bool
127128
}
128129

129130
func (w *wordsStruct) addChar(ch rune) {
130131
if unicode.IsSpace(ch) && w.inWord {
131-
if len(w.word) != 0 {
132-
w.words = append(w.words, w.word)
133-
w.word = ""
132+
if w.buf.Len() != 0 {
133+
w.words = append(w.words, w.buf.String())
134+
w.buf.Reset()
134135
w.inWord = false
135136
}
136137
} else if !unicode.IsSpace(ch) {
@@ -139,7 +140,7 @@ func (w *wordsStruct) addChar(ch rune) {
139140
}
140141

141142
func (w *wordsStruct) addRawChar(ch rune) {
142-
w.word += string(ch)
143+
w.buf.WriteRune(ch)
143144
w.inWord = true
144145
}
145146

@@ -150,16 +151,16 @@ func (w *wordsStruct) addString(str string) {
150151
}
151152

152153
func (w *wordsStruct) addRawString(str string) {
153-
w.word += str
154+
w.buf.WriteString(str)
154155
w.inWord = true
155156
}
156157

157158
func (w *wordsStruct) getWords() []string {
158-
if len(w.word) > 0 {
159-
w.words = append(w.words, w.word)
159+
if w.buf.Len() > 0 {
160+
w.words = append(w.words, w.buf.String())
160161

161162
// Just in case we're called again by mistake
162-
w.word = ""
163+
w.buf.Reset()
163164
w.inWord = false
164165
}
165166
return w.words
@@ -168,9 +169,14 @@ func (w *wordsStruct) getWords() []string {
168169
// Process the word, starting at 'pos', and stop when we get to the
169170
// end of the word or the 'stopChar' character
170171
func (sw *shellWord) processStopOn(stopChar rune, rawEscapes bool) (string, []string, error) {
171-
var result bytes.Buffer
172+
// result buffer can't be currently shared for shellWord as it is called internally
173+
// by processDollar
174+
var result strings.Builder
175+
sw.wordsBuffer.Reset()
172176
var words wordsStruct
177+
words.buf = &sw.wordsBuffer
173178

179+
// no need to initialize all the time
174180
var charFuncMapping = map[rune]func() (string, error){
175181
'$': sw.processDollar,
176182
}

0 commit comments

Comments
 (0)