Skip to content

Commit a35d685

Browse files
authored
chore: Optimize memory for UFM helper functions (#475)
2 parents 3c7287a + fbb034f commit a35d685

File tree

4 files changed

+741
-53
lines changed

4 files changed

+741
-53
lines changed

pkg/apiclients/testapi/problems_helper.go

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,90 @@
11
package testapi
22

3-
import "encoding/json"
4-
5-
// problemCommonFields represents the common fields shared by most Problem union variants.
6-
// Used for efficient access without full type unmarshaling.
7-
type problemCommonFields struct {
8-
ID string `json:"id"`
9-
}
3+
import "bytes"
104

115
// GetID extracts the ID field from a Problem without full unmarshaling.
126
// Returns empty string if the Problem variant doesn't have an ID field (e.g., "other" type).
13-
// This is more efficient than calling discriminator + type-specific As* methods.
7+
// This uses fast byte scanning instead of json.Unmarshal for better performance.
148
func (p Problem) GetID() string {
15-
var common problemCommonFields
16-
if err := json.Unmarshal(p.union, &common); err != nil {
9+
// Fast path: scan for "id":"value" pattern in JSON bytes
10+
// This is 5-10x faster than json.Unmarshal for this simple case
11+
return extractJSONStringField(p.union, "id")
12+
}
13+
14+
// extractJSONStringField efficiently extracts a string field from JSON bytes.
15+
// Returns empty string if field not found or parsing fails.
16+
func extractJSONStringField(data []byte, fieldName string) string {
17+
searchPattern := []byte(`"` + fieldName + `"`)
18+
idx := bytes.Index(data, searchPattern)
19+
if idx == -1 {
20+
return ""
21+
}
22+
23+
pos := skipToValueStart(data, idx+len(searchPattern))
24+
if pos == -1 {
1725
return ""
1826
}
19-
return common.ID
27+
28+
end := findClosingQuote(data, pos)
29+
if end == -1 {
30+
return ""
31+
}
32+
33+
return string(data[pos:end])
34+
}
35+
36+
// skipToValueStart skips past colon and whitespace to find the opening quote.
37+
func skipToValueStart(data []byte, pos int) int {
38+
// Skip whitespace before colon
39+
pos = skipWhitespace(data, pos)
40+
if pos >= len(data) || data[pos] != ':' {
41+
return -1
42+
}
43+
pos++ // Skip colon
44+
45+
// Skip whitespace after colon
46+
pos = skipWhitespace(data, pos)
47+
if pos >= len(data) || data[pos] != '"' {
48+
return -1
49+
}
50+
return pos + 1 // Skip opening quote
51+
}
52+
53+
// skipWhitespace skips JSON whitespace characters.
54+
func skipWhitespace(data []byte, pos int) int {
55+
for pos < len(data) && isWhitespace(data[pos]) {
56+
pos++
57+
}
58+
return pos
59+
}
60+
61+
// isWhitespace checks if a byte is JSON whitespace.
62+
func isWhitespace(b byte) bool {
63+
return b == ' ' || b == '\t' || b == '\n' || b == '\r'
64+
}
65+
66+
// findClosingQuote finds the closing quote, handling escaped quotes.
67+
func findClosingQuote(data []byte, start int) int {
68+
for i := start; i < len(data); i++ {
69+
if data[i] == '"' && !isEscapedQuote(data, start, i) {
70+
return i
71+
}
72+
}
73+
return -1
74+
}
75+
76+
// isEscapedQuote checks if a quote is escaped by counting preceding backslashes.
77+
func isEscapedQuote(data []byte, start, pos int) bool {
78+
if pos == start || data[pos-1] != '\\' {
79+
return false
80+
}
81+
// Count consecutive backslashes
82+
backslashes := 0
83+
for i := pos - 1; i >= start && data[i] == '\\'; i-- {
84+
backslashes++
85+
}
86+
// Odd number means the quote is escaped
87+
return backslashes%2 == 1
2088
}
2189

2290
// HasID returns true if this Problem variant has an ID field.

pkg/utils/sarif/sarif.go

Lines changed: 129 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -303,65 +303,157 @@ func appendComponentSection(sb *strings.Builder, issue testapi.Issue, findingTyp
303303

304304
// appendDependencyPathsSection adds dependency path information to the markdown
305305
func appendDependencyPathsSection(sb *strings.Builder, issue testapi.Issue, componentName string) {
306-
var dependencyPaths [][]string
307-
if val, ok := issue.GetData(testapi.DataKeyDependencyPaths); ok {
308-
// Handle new format: [][]Package (structured data)
309-
if paths, ok := val.([][]testapi.Package); ok {
310-
for _, path := range paths {
311-
formattedPath := make([]string, len(path))
312-
for i, pkg := range path {
313-
formattedPath[i] = fmt.Sprintf("%s@%s", pkg.Name, pkg.Version)
314-
}
315-
dependencyPaths = append(dependencyPaths, formattedPath)
316-
}
317-
} else if paths, ok := val.([][]string); ok {
318-
// Backward compatibility: [][]string format
319-
dependencyPaths = paths
320-
} else if strs, ok := val.([]string); ok {
321-
// Backward compatibility: convert old format (pre-joined strings) to new format
322-
for _, pathStr := range strs {
323-
parts := strings.Split(pathStr, " › ")
324-
dependencyPaths = append(dependencyPaths, parts)
325-
}
306+
val, ok := issue.GetData(testapi.DataKeyDependencyPaths)
307+
if !ok {
308+
if componentName != "" {
309+
appendFallbackIntroduction(sb, issue, componentName)
310+
}
311+
return
312+
}
313+
314+
// Handle new format: [][]Package (structured data)
315+
if paths, ok := val.([][]testapi.Package); ok {
316+
if len(paths) > 0 {
317+
appendDependencyPathsSummaryFromPackages(sb, paths)
318+
appendDetailedPathsFromPackages(sb, paths)
319+
}
320+
return
321+
}
322+
323+
// Backward compatibility: [][]string format
324+
if paths, ok := val.([][]string); ok {
325+
if len(paths) > 0 {
326+
appendDependencyPathsSummary(sb, paths)
327+
appendDetailedPaths(sb, paths)
328+
}
329+
return
330+
}
331+
332+
// Backward compatibility: []string format (old pre-joined strings)
333+
if strs, ok := val.([]string); ok {
334+
if len(strs) > 0 {
335+
appendDependencyPathsFromStrings(sb, strs)
326336
}
337+
return
327338
}
328339

329-
if len(dependencyPaths) > 0 {
330-
appendDependencyPathsSummary(sb, dependencyPaths)
331-
appendDetailedPaths(sb, dependencyPaths)
332-
} else if componentName != "" {
340+
// No valid paths found
341+
if componentName != "" {
333342
appendFallbackIntroduction(sb, issue, componentName)
334343
}
335344
}
336345

337-
// appendDependencyPathsSummary adds a summary of dependency paths
338-
func appendDependencyPathsSummary(sb *strings.Builder, dependencyPaths [][]string) {
339-
if len(dependencyPaths) == 0 {
346+
// appendDependencyPathsSummaryFromPackages writes summary directly without intermediate allocations
347+
func appendDependencyPathsSummaryFromPackages(sb *strings.Builder, paths [][]testapi.Package) {
348+
if len(paths) == 0 || len(paths[0]) == 0 {
340349
return
341350
}
342351

343-
firstPath := dependencyPaths[0]
344-
introduction := "* Introduced through: %s\n"
352+
firstPath := paths[0]
353+
sb.WriteString("* Introduced through: ")
354+
355+
// Format first package
356+
sb.WriteString(firstPath[0].Name)
357+
sb.WriteByte('@')
358+
sb.WriteString(firstPath[0].Version)
359+
360+
if len(firstPath) > 2 {
361+
sb.WriteString(", ")
362+
sb.WriteString(firstPath[1].Name)
363+
sb.WriteByte('@')
364+
sb.WriteString(firstPath[1].Version)
365+
sb.WriteString(" and others")
366+
} else if len(firstPath) == 2 {
367+
sb.WriteString(" and ")
368+
sb.WriteString(firstPath[1].Name)
369+
sb.WriteByte('@')
370+
sb.WriteString(firstPath[1].Version)
371+
}
345372

346-
if len(firstPath) == 0 {
373+
sb.WriteByte('\n')
374+
}
375+
376+
// appendDetailedPathsFromPackages writes paths directly without intermediate strings
377+
func appendDetailedPathsFromPackages(sb *strings.Builder, paths [][]testapi.Package) {
378+
sb.WriteString("### Detailed paths\n")
379+
for _, path := range paths {
380+
sb.WriteString("* _Introduced through_: ")
381+
for i, pkg := range path {
382+
if i > 0 {
383+
sb.WriteString(" › ")
384+
}
385+
sb.WriteString(pkg.Name)
386+
sb.WriteByte('@')
387+
sb.WriteString(pkg.Version)
388+
}
389+
sb.WriteByte('\n')
390+
}
391+
}
392+
393+
// appendDependencyPathsSummary adds a summary of dependency paths ([][]string format)
394+
func appendDependencyPathsSummary(sb *strings.Builder, dependencyPaths [][]string) {
395+
if len(dependencyPaths) == 0 || len(dependencyPaths[0]) == 0 {
347396
return
348397
}
349398

350-
dependencyPath := firstPath[0]
399+
firstPath := dependencyPaths[0]
400+
sb.WriteString("* Introduced through: ")
401+
sb.WriteString(firstPath[0])
402+
351403
if len(firstPath) > 2 {
352-
dependencyPath = fmt.Sprintf("%s, %s and others", firstPath[0], firstPath[1])
404+
sb.WriteString(", ")
405+
sb.WriteString(firstPath[1])
406+
sb.WriteString(" and others")
353407
} else if len(firstPath) == 2 {
354-
dependencyPath = fmt.Sprintf("%s and %s", firstPath[0], firstPath[1])
408+
sb.WriteString(" and ")
409+
sb.WriteString(firstPath[1])
355410
}
356-
fmt.Fprintf(sb, introduction, dependencyPath)
411+
412+
sb.WriteByte('\n')
357413
}
358414

359-
// appendDetailedPaths adds detailed dependency path information
415+
// appendDetailedPaths adds detailed dependency path information ([][]string format)
360416
func appendDetailedPaths(sb *strings.Builder, dependencyPaths [][]string) {
361417
sb.WriteString("### Detailed paths\n")
362418
for _, pathParts := range dependencyPaths {
363-
formattedPath := strings.Join(pathParts, " › ")
364-
sb.WriteString(fmt.Sprintf("* _Introduced through_: %s\n", formattedPath))
419+
sb.WriteString("* _Introduced through_: ")
420+
for i, part := range pathParts {
421+
if i > 0 {
422+
sb.WriteString(" › ")
423+
}
424+
sb.WriteString(part)
425+
}
426+
sb.WriteByte('\n')
427+
}
428+
}
429+
430+
// appendDependencyPathsFromStrings handles old format (pre-joined strings)
431+
func appendDependencyPathsFromStrings(sb *strings.Builder, paths []string) {
432+
if len(paths) == 0 {
433+
return
434+
}
435+
436+
// Summary from first path
437+
firstPath := paths[0]
438+
parts := strings.SplitN(firstPath, " › ", 3) // Only split what we need
439+
sb.WriteString("* Introduced through: ")
440+
sb.WriteString(parts[0])
441+
if len(parts) > 2 {
442+
sb.WriteString(", ")
443+
sb.WriteString(parts[1])
444+
sb.WriteString(" and others")
445+
} else if len(parts) == 2 {
446+
sb.WriteString(" and ")
447+
sb.WriteString(parts[1])
448+
}
449+
sb.WriteByte('\n')
450+
451+
// Detailed paths
452+
sb.WriteString("### Detailed paths\n")
453+
for _, pathStr := range paths {
454+
sb.WriteString("* _Introduced through_: ")
455+
sb.WriteString(pathStr)
456+
sb.WriteByte('\n')
365457
}
366458
}
367459

0 commit comments

Comments
 (0)