Skip to content

Commit 344e29f

Browse files
authored
fix: complex symlink performance issue (#411)
Signed-off-by: Keith Zantow <[email protected]>
1 parent 67dfd6c commit 344e29f

File tree

4 files changed

+292
-909
lines changed

4 files changed

+292
-909
lines changed

pkg/filetree/glob_parser.go

Lines changed: 36 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -47,26 +47,27 @@ func (s searchBasis) String() string {
4747

4848
type searchRequest struct {
4949
searchBasis
50-
value string
51-
requirement string
50+
indexLookup string
51+
glob string
5252
}
5353

5454
func (s searchRequest) String() string {
55-
value := s.searchBasis.String() + ": " + s.value
56-
if s.requirement != "" {
57-
value += " (requirement: " + s.requirement + ")"
55+
value := s.searchBasis.String() + ": " + s.indexLookup
56+
if s.glob != "" {
57+
value += " (requirement: " + s.glob + ")"
5858
}
5959
return value
6060
}
6161

6262
func parseGlob(glob string) []searchRequest {
6363
glob = cleanGlob(glob)
6464

65-
if !strings.ContainsAny(glob, "*?[]{}") {
65+
if exactMatch(glob) {
6666
return []searchRequest{
6767
{
6868
searchBasis: searchByFullPath,
69-
value: glob,
69+
indexLookup: glob,
70+
glob: glob,
7071
},
7172
}
7273
}
@@ -80,20 +81,20 @@ func parseGlob(glob string) []searchRequest {
8081
requests := []searchRequest{
8182
{
8283
searchBasis: searchBySubDirectory,
83-
value: nestedBasename,
84-
requirement: beforeBasename,
84+
indexLookup: nestedBasename,
85+
glob: glob,
8586
},
8687
}
8788
return requests
8889
}
8990
}
9091

91-
requests := parseGlobBasename(basename)
92-
for i := range requests {
93-
applyRequirement(&requests[i], beforeBasename, glob)
94-
}
92+
return parseGlobBasename(basename, glob)
93+
}
9594

96-
return requests
95+
// exactMatch indicates the string does not contain an expression that may result in multiple results such as * or {}
96+
func exactMatch(glob string) bool {
97+
return !strings.ContainsAny(glob, "*?[]{}")
9798
}
9899

99100
func splitAtBasename(glob string) (string, string) {
@@ -118,34 +119,9 @@ func splitAtBasename(glob string) (string, string) {
118119
return beforeBasename, basename
119120
}
120121

121-
func applyRequirement(request *searchRequest, beforeBasename, glob string) {
122-
var requirement string
123-
124-
if beforeBasename != "" {
125-
requirement = glob
126-
switch beforeBasename {
127-
case "**", request.requirement:
128-
if request.searchBasis != searchByExtension {
129-
requirement = ""
130-
}
131-
}
132-
} else {
133-
requirement = ""
134-
}
135-
136-
request.requirement = requirement
137-
138-
if request.searchBasis == searchByGlob {
139-
request.value = glob
140-
if glob == request.requirement {
141-
request.requirement = ""
142-
}
143-
}
144-
}
145-
146-
func parseGlobBasename(basenameInput string) []searchRequest {
122+
func parseGlobBasename(basenameInput, glob string) []searchRequest {
147123
if strings.ContainsAny(basenameInput, "[]{}") {
148-
return parseBasenameAltAndClassGlobSections(basenameInput)
124+
return parseBasenameAltAndClassGlobSections(basenameInput, glob)
149125
}
150126

151127
extensionFields := strings.Split(basenameInput, "*.")
@@ -156,7 +132,8 @@ func parseGlobBasename(basenameInput string) []searchRequest {
156132
return []searchRequest{
157133
{
158134
searchBasis: searchByExtension,
159-
value: "." + possibleExtension,
135+
indexLookup: "." + possibleExtension,
136+
glob: glob,
160137
},
161138
}
162139
}
@@ -167,7 +144,8 @@ func parseGlobBasename(basenameInput string) []searchRequest {
167144
return []searchRequest{
168145
{
169146
searchBasis: searchByBasename,
170-
value: basenameInput,
147+
indexLookup: basenameInput,
148+
glob: glob,
171149
},
172150
}
173151
}
@@ -177,20 +155,21 @@ func parseGlobBasename(basenameInput string) []searchRequest {
177155
return []searchRequest{
178156
{
179157
searchBasis: searchByGlob,
180-
// note: we let the parent caller attach the full glob value
158+
glob: glob,
181159
},
182160
}
183161
}
184162

185163
return []searchRequest{
186164
{
187165
searchBasis: searchByBasenameGlob,
188-
value: basenameInput,
166+
indexLookup: basenameInput,
167+
glob: glob,
189168
},
190169
}
191170
}
192171

193-
func parseBasenameAltAndClassGlobSections(basenameInput string) []searchRequest {
172+
func parseBasenameAltAndClassGlobSections(basenameInput, glob string) []searchRequest {
194173
// TODO: process escape sequences
195174

196175
altStartCount := strings.Count(basenameInput, "{")
@@ -203,7 +182,7 @@ func parseBasenameAltAndClassGlobSections(basenameInput string) []searchRequest
203182
return []searchRequest{
204183
{
205184
searchBasis: searchByGlob,
206-
// note: we let the parent caller attach the full glob value
185+
glob: glob,
207186
},
208187
}
209188
}
@@ -213,7 +192,8 @@ func parseBasenameAltAndClassGlobSections(basenameInput string) []searchRequest
213192
return []searchRequest{
214193
{
215194
searchBasis: searchByBasenameGlob,
216-
value: basenameInput,
195+
indexLookup: basenameInput,
196+
glob: glob,
217197
},
218198
}
219199
}
@@ -236,7 +216,8 @@ func parseBasenameAltAndClassGlobSections(basenameInput string) []searchRequest
236216

237217
requests = append(requests, searchRequest{
238218
searchBasis: basis,
239-
value: altSection,
219+
indexLookup: altSection,
220+
glob: glob,
240221
})
241222
}
242223
return requests
@@ -248,7 +229,8 @@ func parseBasenameAltAndClassGlobSections(basenameInput string) []searchRequest
248229
return []searchRequest{
249230
{
250231
searchBasis: searchByBasenameGlob,
251-
value: basenameInput,
232+
indexLookup: basenameInput,
233+
glob: glob,
252234
},
253235
}
254236
}
@@ -265,6 +247,10 @@ func cleanGlob(glob string) string {
265247
// e.g. replace "/bar**/" with "/bar*/"
266248
glob = simplifyMultipleGlobAsterisks(glob)
267249
glob = simplifyGlobRecursion(glob)
250+
// paths are compared against absolute paths. these must begin with slash or doublestar will not match certain cases
251+
if !strings.HasPrefix(glob, "/") && !strings.HasPrefix(glob, "**") {
252+
glob = "/" + glob
253+
}
268254
return glob
269255
}
270256

0 commit comments

Comments
 (0)