mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Improve nogo action cache-ability.
Presently, the standard library facts are not serialized in a deterministic order. This means that they have the possibility to change on each iteration, requiring a large scale re-analysis of all downstream actions, which includes all packages. Improve cache-ability of nogo actions by improving the determinism of the both facts and findings. Internally, default facts should be serialized as a sorted list for this reason already. PiperOrigin-RevId: 370188259
This commit is contained in:
committed by
gVisor bot
parent
80cd26c2f4
commit
f373f67048
@@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Finding is a single finding.
|
||||
@@ -44,6 +45,33 @@ func WriteFindingsToFile(findings []Finding, filename string) error {
|
||||
|
||||
// WriteFindingsToBytes serializes findings as bytes.
|
||||
func WriteFindingsToBytes(findings []Finding) ([]byte, error) {
|
||||
// N.B. Sort all the findings in order to maximize cacheability.
|
||||
sort.Slice(findings, func(i, j int) bool {
|
||||
switch {
|
||||
case findings[i].Position.Filename < findings[j].Position.Filename:
|
||||
return true
|
||||
case findings[i].Position.Filename > findings[j].Position.Filename:
|
||||
return false
|
||||
case findings[i].Position.Line < findings[j].Position.Line:
|
||||
return true
|
||||
case findings[i].Position.Line > findings[j].Position.Line:
|
||||
return false
|
||||
case findings[i].Position.Column < findings[j].Position.Column:
|
||||
return true
|
||||
case findings[i].Position.Column > findings[j].Position.Column:
|
||||
return false
|
||||
case findings[i].Category < findings[j].Category:
|
||||
return true
|
||||
case findings[i].Category > findings[j].Category:
|
||||
return false
|
||||
case findings[i].Message < findings[j].Message:
|
||||
return true
|
||||
case findings[i].Message > findings[j].Message:
|
||||
return false
|
||||
default:
|
||||
return false
|
||||
}
|
||||
})
|
||||
return json.Marshal(findings)
|
||||
}
|
||||
|
||||
|
||||
+29
-4
@@ -34,6 +34,7 @@ import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/analysis"
|
||||
@@ -75,6 +76,12 @@ type loader func(string) ([]byte, error)
|
||||
// saver is a fact-saver function.
|
||||
type saver func([]byte) error
|
||||
|
||||
// stdlibFact is used for serialiation.
|
||||
type stdlibFact struct {
|
||||
Package string
|
||||
Facts []byte
|
||||
}
|
||||
|
||||
// factLoader returns a function that loads facts.
|
||||
//
|
||||
// This resolves all standard library facts and imported package facts up
|
||||
@@ -90,10 +97,17 @@ func (c *PackageConfig) factLoader() (loader, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error loading stdlib facts from %q: %w", c.StdlibFacts, err)
|
||||
}
|
||||
var stdlibFacts map[string][]byte
|
||||
if err := json.Unmarshal(data, &stdlibFacts); err != nil {
|
||||
var (
|
||||
stdlibFactsSorted []stdlibFact
|
||||
stdlibFacts = make(map[string][]byte)
|
||||
)
|
||||
// See below re: sorted serialization.
|
||||
if err := json.Unmarshal(data, &stdlibFactsSorted); err != nil {
|
||||
return nil, fmt.Errorf("error loading stdlib facts: %w", err)
|
||||
}
|
||||
for _, stdlibFact := range stdlibFactsSorted {
|
||||
stdlibFacts[stdlibFact.Package] = stdlibFact.Facts
|
||||
}
|
||||
for pkg, data := range stdlibFacts {
|
||||
allFacts[pkg] = data
|
||||
}
|
||||
@@ -327,8 +341,19 @@ func CheckStdlib(config *StdlibConfig, analyzers []*analysis.Analyzer) (allFindi
|
||||
return nil, nil, fmt.Errorf("no stdlib facts found: misconfiguration?")
|
||||
}
|
||||
|
||||
// Write out all findings.
|
||||
factData, err := json.Marshal(stdlibFacts)
|
||||
// Write out all findings. Note that the standard library facts
|
||||
// must be serialized in a sorted order to ensure cacheability.
|
||||
stdlibFactsSorted := make([]stdlibFact, 0, len(stdlibFacts))
|
||||
for pkg, facts := range stdlibFacts {
|
||||
stdlibFactsSorted = append(stdlibFactsSorted, stdlibFact{
|
||||
Package: pkg,
|
||||
Facts: facts,
|
||||
})
|
||||
}
|
||||
sort.Slice(stdlibFactsSorted, func(i, j int) bool {
|
||||
return stdlibFactsSorted[i].Package < stdlibFactsSorted[j].Package
|
||||
})
|
||||
factData, err := json.Marshal(stdlibFactsSorted)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error saving stdlib facts: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user