OLD | NEW |
1 package data | 1 package data |
2 | 2 |
3 import ( | 3 import ( |
4 "bytes" | 4 "bytes" |
5 "encoding/gob" | 5 "encoding/gob" |
6 "fmt" | 6 "fmt" |
7 "sort" | 7 "sort" |
8 "sync" | 8 "sync" |
9 | 9 |
10 "github.com/skia-dev/glog" | 10 "github.com/skia-dev/glog" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 caches: map[string]*fuzzReportCache{}, | 69 caches: map[string]*fuzzReportCache{}, |
70 } | 70 } |
71 } | 71 } |
72 | 72 |
73 // A fuzzReportCache holds three FuzzReportTrees - one for the raw data, a sorte
d version with | 73 // A fuzzReportCache holds three FuzzReportTrees - one for the raw data, a sorte
d version with |
74 // all of the reports and an empty tree that holds no reports. These are used t
o procure data | 74 // all of the reports and an empty tree that holds no reports. These are used t
o procure data |
75 // for the frontend. | 75 // for the frontend. |
76 type fuzzReportCache struct { | 76 type fuzzReportCache struct { |
77 // All the data goes in here, in no particular order | 77 // All the data goes in here, in no particular order |
78 rawData FuzzReportTree | 78 rawData FuzzReportTree |
79 » // Generated, sorted caches | 79 » // Generated, sorted cache |
80 » FullReport FuzzReportTree | 80 » FullReport FuzzReportTree |
81 » SummaryReport FuzzReportTree | |
82 | 81 |
83 » // If data is in rawData, but not in SummaryReport or FullReport, the tr
ees should be | 82 » // If data is in rawData, but not in FullReport, the trees should be |
84 // rebuilt | 83 // rebuilt |
85 isDirty bool | 84 isDirty bool |
86 } | 85 } |
87 | 86 |
88 // currentData is the object that holds the cache of fuzz results. It is used b
y the frontend. | 87 // currentData is the object that holds the cache of fuzz results. It is used b
y the frontend. |
89 var currentData = newBuilder() | 88 var currentData = newBuilder() |
90 | 89 |
91 // stagingData is the object that processes can write to to queue up new data | 90 // stagingData is the object that processes can write to to queue up new data |
92 // without disturbing the data shown to users. | 91 // without disturbing the data shown to users. |
93 var stagingData = newBuilder() | 92 var stagingData = newBuilder() |
94 | 93 |
95 func FindFuzzSummary(category string) FuzzReportTree { | |
96 cache, found := currentData.caches[category] | |
97 if !found { | |
98 return FuzzReportTree{} | |
99 } | |
100 return cache.SummaryReport | |
101 } | |
102 | |
103 // FindFuzzDetails returns the detailed fuzz reports for a file name, function n
ame, and line number. | 94 // FindFuzzDetails returns the detailed fuzz reports for a file name, function n
ame, and line number. |
104 // If functionName is "" or lineNumber is -1, all reports are shown. | 95 // If functionName is "" or lineNumber is -1, all reports are shown. |
105 func FindFuzzDetails(category, fileName, functionName string, lineNumber int) (F
uzzReportTree, error) { | 96 func FindFuzzDetails(category, fileName, functionName string, lineNumber int) (F
uzzReportTree, error) { |
106 cache, found := currentData.caches[category] | 97 cache, found := currentData.caches[category] |
107 if found { | 98 if found { |
108 if fileName == "" { | 99 if fileName == "" { |
109 return cache.FullReport, nil | 100 return cache.FullReport, nil |
110 } | 101 } |
111 for _, file := range cache.FullReport { | 102 for _, file := range cache.FullReport { |
112 if file.FileName == fileName { | 103 if file.FileName == fileName { |
(...skipping 25 matching lines...) Expand all Loading... |
138 | 129 |
139 // filterByLineNumber removes all FuzzReportLineNumber except that which matches
lineNumber | 130 // filterByLineNumber removes all FuzzReportLineNumber except that which matches
lineNumber |
140 func (function *FunctionFuzzReport) filterByLineNumber(lineNumber int) { | 131 func (function *FunctionFuzzReport) filterByLineNumber(lineNumber int) { |
141 for _, line := range function.LineNumbers { | 132 for _, line := range function.LineNumbers { |
142 if lineNumber == line.LineNumber { | 133 if lineNumber == line.LineNumber { |
143 function.LineNumbers = []LineFuzzReport{line} | 134 function.LineNumbers = []LineFuzzReport{line} |
144 } | 135 } |
145 } | 136 } |
146 } | 137 } |
147 | 138 |
148 func CategoryOverview(category string) FuzzReportTree { | |
149 overview, found := currentData.caches[category] | |
150 if found { | |
151 return overview.SummaryReport | |
152 } | |
153 return FuzzReportTree{} | |
154 } | |
155 | |
156 // FindFuzzDetailForFuzz returns a tree containing the single | 139 // FindFuzzDetailForFuzz returns a tree containing the single |
157 // report with the given name, or an error, it it doesn't exist. | 140 // report with the given name, or an error, it it doesn't exist. |
158 func FindFuzzDetailForFuzz(category, name string) (FuzzReportTree, error) { | 141 func FindFuzzDetailForFuzz(category, name string) (FuzzReportTree, error) { |
159 if cache, found := currentData.caches[category]; found { | 142 if cache, found := currentData.caches[category]; found { |
160 for _, file := range cache.FullReport { | 143 for _, file := range cache.FullReport { |
161 if file.filterByFuzzName(name) { | 144 if file.filterByFuzzName(name) { |
162 return FuzzReportTree{file}, nil | 145 return FuzzReportTree{file}, nil |
163 } | 146 } |
164 } | 147 } |
165 } | 148 } |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 return FuzzReportTree{} | 341 return FuzzReportTree{} |
359 } | 342 } |
360 if cache.isDirty { | 343 if cache.isDirty { |
361 r.mutex.Lock() | 344 r.mutex.Lock() |
362 defer r.mutex.Unlock() | 345 defer r.mutex.Unlock() |
363 cache.rebuildSortedReports() | 346 cache.rebuildSortedReports() |
364 } | 347 } |
365 return cache.FullReport | 348 return cache.FullReport |
366 } | 349 } |
367 | 350 |
368 // getSummarySortedByTotal gets the summary FuzzReport for a fuzz category | |
369 // sorted by total number of fuzzes. | |
370 func (r *treeReportBuilder) getSummarySortedByTotal(category string) FuzzReportT
ree { | |
371 cache, found := r.caches[category] | |
372 if !found { | |
373 glog.Warningf("Could not find report tree for category %s", cate
gory) | |
374 return FuzzReportTree{} | |
375 } | |
376 if cache.isDirty { | |
377 r.mutex.Lock() | |
378 defer r.mutex.Unlock() | |
379 cache.rebuildSortedReports() | |
380 } | |
381 return cache.SummaryReport | |
382 } | |
383 | |
384 // rebuildSortedReports creates the sorted reports for a given cache. | 351 // rebuildSortedReports creates the sorted reports for a given cache. |
385 func (c *fuzzReportCache) rebuildSortedReports() { | 352 func (c *fuzzReportCache) rebuildSortedReports() { |
386 c.FullReport = c.getClonedSortedReport(true) | 353 c.FullReport = c.getClonedSortedReport(true) |
387 c.SummaryReport = c.getClonedSortedReport(false) | |
388 c.isDirty = false | 354 c.isDirty = false |
389 } | 355 } |
390 | 356 |
391 // getClonedSortedReport makes a newly allocated FuzzReport after running the pa
ssed in function | 357 // getClonedSortedReport makes a newly allocated FuzzReport after running the pa
ssed in function |
392 // on all FuzzReportLineNumber objects in the report. | 358 // on all FuzzReportLineNumber objects in the report. |
393 func (c *fuzzReportCache) getClonedSortedReport(keepDetails bool) FuzzReportTree
{ | 359 func (c *fuzzReportCache) getClonedSortedReport(keepDetails bool) FuzzReportTree
{ |
394 report := cloneReport(c.rawData) | 360 report := cloneReport(c.rawData) |
395 sort.Sort(filesTotalSort(report)) | 361 sort.Sort(filesTotalSort(report)) |
396 for i := range report { | 362 for i := range report { |
397 file := &report[i] | 363 file := &report[i] |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 } | 456 } |
491 | 457 |
492 // containsName returns the FuzzReport and true if a fuzz with the given name is
in the list. | 458 // containsName returns the FuzzReport and true if a fuzz with the given name is
in the list. |
493 func (p SortedFuzzReports) containsName(fuzzName string) (FuzzReport, bool) { | 459 func (p SortedFuzzReports) containsName(fuzzName string) (FuzzReport, bool) { |
494 i := sort.Search(len(p), func(i int) bool { return p[i].FuzzName >= fuzz
Name }) | 460 i := sort.Search(len(p), func(i int) bool { return p[i].FuzzName >= fuzz
Name }) |
495 if i < len(p) && p[i].FuzzName == fuzzName { | 461 if i < len(p) && p[i].FuzzName == fuzzName { |
496 return p[i], true | 462 return p[i], true |
497 } | 463 } |
498 return FuzzReport{}, false | 464 return FuzzReport{}, false |
499 } | 465 } |
OLD | NEW |