Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 package analysis | 1 package analysis |
| 2 | 2 |
| 3 import ( | 3 import ( |
| 4 "sync" | 4 "sync" |
| 5 "time" | 5 "time" |
| 6 | 6 |
| 7 "github.com/golang/glog" | 7 "github.com/golang/glog" |
| 8 "github.com/rcrowley/go-metrics" | 8 "github.com/rcrowley/go-metrics" |
| 9 | 9 |
| 10 "skia.googlesource.com/buildbot.git/go/util" | 10 "skia.googlesource.com/buildbot.git/go/util" |
| 11 "skia.googlesource.com/buildbot.git/golden/go/diff" | 11 "skia.googlesource.com/buildbot.git/golden/go/diff" |
| 12 "skia.googlesource.com/buildbot.git/golden/go/expstorage" | 12 "skia.googlesource.com/buildbot.git/golden/go/expstorage" |
| 13 "skia.googlesource.com/buildbot.git/golden/go/types" | 13 "skia.googlesource.com/buildbot.git/golden/go/types" |
| 14 ptypes "skia.googlesource.com/buildbot.git/perf/go/types" | 14 ptypes "skia.googlesource.com/buildbot.git/perf/go/types" |
| 15 ) | 15 ) |
| 16 | 16 |
| 17 // Stores a Trace with labels and digests in memory. CommitIds, Digests and | 17 // Stores a Trace with labels and digests in memory. CommitIds, Digests and |
|
jcgregorio
2014/10/18 00:09:03
Comments for things begin with its name:
// Label
stephana
2014/10/20 12:56:07
Done.
| |
| 18 // Labels are of the same length, identical indices refer to the same digest. | 18 // Labels are of the same length, identical indices refer to the same digest. |
| 19 type LabeledTrace struct { | 19 type LabeledTrace struct { |
| 20 » Params map[string]string `json:"params"` | 20 » Params map[string]string |
| 21 » CommitIds []int `json:"commitIds"` | 21 » CommitIds []int |
| 22 » Digests []string `json:"digests"` | 22 » Digests []string |
| 23 » Labels []types.Label `json:"labels` | 23 » Labels []types.Label |
| 24 } | 24 } |
| 25 | 25 |
| 26 func NewLabeledTrace(params map[string]string, capacity int) *LabeledTrace { | 26 func NewLabeledTrace(params map[string]string, capacity int) *LabeledTrace { |
| 27 return &LabeledTrace{ | 27 return &LabeledTrace{ |
| 28 Params: params, | 28 Params: params, |
| 29 CommitIds: make([]int, 0, capacity), | 29 CommitIds: make([]int, 0, capacity), |
| 30 Digests: make([]string, 0, capacity), | 30 Digests: make([]string, 0, capacity), |
| 31 Labels: make([]types.Label, 0, capacity), | 31 Labels: make([]types.Label, 0, capacity), |
| 32 } | 32 } |
| 33 } | 33 } |
| 34 | 34 |
| 35 // Add the given tripples of commitIds, digests and labels to this LabeledTrace. | 35 // Add the given tripples of commitIds, digests and labels to this LabeledTrace. |
| 36 func (lt *LabeledTrace) addLabeledDigests(commitIds []int, digests []string, lab els []types.Label) { | 36 func (lt *LabeledTrace) addLabeledDigests(commitIds []int, digests []string, lab els []types.Label) { |
| 37 lt.CommitIds = append(lt.CommitIds, commitIds...) | 37 lt.CommitIds = append(lt.CommitIds, commitIds...) |
| 38 lt.Digests = append(lt.Digests, digests...) | 38 lt.Digests = append(lt.Digests, digests...) |
| 39 lt.Labels = append(lt.Labels, labels...) | 39 lt.Labels = append(lt.Labels, labels...) |
| 40 } | 40 } |
| 41 | 41 |
| 42 // Aggregates the Traces in tile and provides the commits that the | 42 // Aggregates the Traces in tile and provides the commits that the |
| 43 // CommitIds in LabeledTrace refer to. | 43 // CommitIds in LabeledTrace refer to. |
| 44 // LabeledTile and LabeledTrace are used to store the cannonical information | |
| 45 // extracted from the tiles. The (redundant) output data is derived from these. | |
| 44 type LabeledTile struct { | 46 type LabeledTile struct { |
| 45 » Commits []*ptypes.Commit `json:"commits"` | 47 » Commits []*ptypes.Commit |
| 46 | 48 |
| 47 // Traces are indexed by the primary key (test name). This is somewhat | 49 // Traces are indexed by the primary key (test name). This is somewhat |
| 48 // redundant, but this also output format. | 50 // redundant, but this also output format. |
| 49 » Traces map[string][]*LabeledTrace `json:"traces"` | 51 » Traces map[string][]*LabeledTrace |
| 50 } | 52 } |
| 51 | 53 |
| 52 func NewLabeledTile() *LabeledTile { | 54 func NewLabeledTile() *LabeledTile { |
| 53 return &LabeledTile{ | 55 return &LabeledTile{ |
| 54 Commits: []*ptypes.Commit{}, | 56 Commits: []*ptypes.Commit{}, |
| 55 Traces: map[string][]*LabeledTrace{}, | 57 Traces: map[string][]*LabeledTrace{}, |
| 56 } | 58 } |
| 57 } | 59 } |
| 58 | 60 |
| 59 // Utility function that returns the testName and a labeled trace for the given | 61 // Utility function that returns the testName and a labeled trace for the given |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 74 } | 76 } |
| 75 } | 77 } |
| 76 | 78 |
| 77 // If we cannot find the trace in our set of tests we are adding a new | 79 // If we cannot find the trace in our set of tests we are adding a new |
| 78 // labeled trace. | 80 // labeled trace. |
| 79 newLT := NewLabeledTrace(params, trace.Len()) | 81 newLT := NewLabeledTrace(params, trace.Len()) |
| 80 t.Traces[pKey] = append(t.Traces[pKey], newLT) | 82 t.Traces[pKey] = append(t.Traces[pKey], newLT) |
| 81 return pKey, newLT | 83 return pKey, newLT |
| 82 } | 84 } |
| 83 | 85 |
| 86 // Classification counts. | |
| 87 type LabelCounts struct { | |
| 88 Unt int `json:"unt"` // Untriaged | |
| 89 Pos int `json:"pos"` // Positive | |
| 90 Neg int `json:"neg"` // Negative | |
| 91 } | |
| 92 | |
| 93 // GUITileCounts is an output type for the aggregated label counts. | |
| 94 // The tupples in Counts store: untriaged, positive, negatives | |
| 95 type GUITileCounts struct { | |
| 96 Commits []*ptypes.Commit `json:"commits"` | |
| 97 Counts map[string][]LabelCounts `json:"counts"` | |
| 98 } | |
| 99 | |
| 100 // GUITestCounts is an output type for a single test that contains the | |
| 101 // aggregated counts over all traces and invidual trace labels. | |
| 102 type GUITestCounts struct { | |
| 103 Commits []*ptypes.Commit `json:"commits"` | |
| 104 Aggregated []LabelCounts `json:"aggregated"` | |
| 105 Traces []*GUILabeledTrace `json:"traces"` | |
| 106 Labels []IdLabel `json:"labels"` | |
| 107 } | |
| 108 | |
| 109 // GUILabeledTrace is an output type for the labels of a trace. | |
| 110 type GUILabeledTrace struct { | |
| 111 Params map[string]string `json:"params"` | |
| 112 | |
| 113 // List of commitId and Label pairs. | |
| 114 Labels []IdLabel `json:"labels"` | |
| 115 } | |
| 116 | |
| 117 // CommitId and label pair. | |
| 118 type IdLabel struct { | |
| 119 C int `json:"c"` | |
|
jcgregorio
2014/10/18 00:09:03
I'm all for brevity, but this might be too much. I
stephana
2014/10/20 12:56:07
Done.
| |
| 120 L int `json:"l"` | |
| 121 } | |
| 122 | |
| 84 // Analyzer continuously manages the tasks, like pollint for new traces | 123 // Analyzer continuously manages the tasks, like pollint for new traces |
| 85 // on disk, etc. | 124 // on disk, etc. |
| 86 type Analyzer struct { | 125 type Analyzer struct { |
| 87 expStore expstorage.ExpectationsStore | 126 expStore expstorage.ExpectationsStore |
| 88 diffStore diff.DiffStore | 127 diffStore diff.DiffStore |
| 89 tileStore ptypes.TileStore | 128 tileStore ptypes.TileStore |
| 90 | 129 |
| 130 // Canonical data structure to hold our information about commits, diges ts | |
| 131 // and labels. | |
| 91 currentTile *LabeledTile | 132 currentTile *LabeledTile |
| 92 | 133 |
| 93 » // Lock to protect the expectations and the current labeled tile. | 134 » // Output data structures that are derived from currentTile. |
| 135 » currentTileCounts *GUITileCounts | |
| 136 » currentTestCounts map[string]*GUITestCounts | |
| 137 | |
| 138 » // Lock to protect the expectations and current* variables. | |
| 94 mutex sync.Mutex | 139 mutex sync.Mutex |
| 95 } | 140 } |
| 96 | 141 |
| 97 func NewAnalyzer(expStore expstorage.ExpectationsStore, tileStore ptypes.TileSto re, diffStore diff.DiffStore, timeBetweenPolls time.Duration) *Analyzer { | 142 func NewAnalyzer(expStore expstorage.ExpectationsStore, tileStore ptypes.TileSto re, diffStore diff.DiffStore, timeBetweenPolls time.Duration) *Analyzer { |
| 98 result := &Analyzer{ | 143 result := &Analyzer{ |
| 99 expStore: expStore, | 144 expStore: expStore, |
| 100 diffStore: diffStore, | 145 diffStore: diffStore, |
| 101 tileStore: tileStore, | 146 tileStore: tileStore, |
| 102 | 147 |
| 103 currentTile: NewLabeledTile(), | 148 currentTile: NewLabeledTile(), |
| 104 } | 149 } |
| 105 | 150 |
| 106 go result.loop(timeBetweenPolls) | 151 go result.loop(timeBetweenPolls) |
| 107 return result | 152 return result |
| 108 } | 153 } |
| 109 | 154 |
| 110 // Returns an entire Tile which is a collection of 'traces' over a series of | 155 // Returns an entire Tile which is a collection of 'traces' over a series of |
| 111 // of commits. Each trace contains the digests and their labels based on | 156 // of commits. Each trace contains the digests and their labels based on |
| 112 // out knowledge base about digests (expectations). | 157 // out knowledge base about digests (expectations). |
| 113 func (a *Analyzer) GetLabeledTile() *LabeledTile { | 158 func (a *Analyzer) GetTileCounts() (*GUITileCounts, error) { |
| 114 a.mutex.Lock() | 159 a.mutex.Lock() |
| 115 defer a.mutex.Unlock() | 160 defer a.mutex.Unlock() |
| 116 | 161 |
| 117 » return a.currentTile | 162 » return a.currentTileCounts, nil |
| 118 } | 163 } |
| 119 | 164 |
| 120 func (a *Analyzer) GetLabeledTraces(testName string) []*LabeledTrace { | 165 func (a *Analyzer) GetTestCounts(testName string) (*GUITestCounts, error) { |
| 121 a.mutex.Lock() | 166 a.mutex.Lock() |
| 122 defer a.mutex.Unlock() | 167 defer a.mutex.Unlock() |
| 123 | 168 |
| 124 » return a.currentTile.Traces[testName] | 169 » return a.currentTestCounts[testName], nil |
| 125 } | 170 } |
| 126 | 171 |
| 127 func (a *Analyzer) SetDigestLabels(labeledTestDigests map[string]types.TestClass ification, userId string) (map[string][]*LabeledTrace, error) { | 172 func (a *Analyzer) SetDigestLabels(labeledTestDigests map[string]types.TestClass ification, userId string) (map[string][]*LabeledTrace, error) { |
| 128 a.mutex.Lock() | 173 a.mutex.Lock() |
| 129 defer a.mutex.Unlock() | 174 defer a.mutex.Unlock() |
| 130 | 175 |
| 131 expectations, err := a.expStore.Get(true) | 176 expectations, err := a.expStore.Get(true) |
| 132 if err != nil { | 177 if err != nil { |
| 133 return nil, err | 178 return nil, err |
| 134 } | 179 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 153 for { | 198 for { |
| 154 glog.Info("Reading tiles ... ") | 199 glog.Info("Reading tiles ... ") |
| 155 | 200 |
| 156 // Load the tile and process it. | 201 // Load the tile and process it. |
| 157 tile, err := a.tileStore.Get(0, -1) | 202 tile, err := a.tileStore.Get(0, -1) |
| 158 if err != nil { | 203 if err != nil { |
| 159 glog.Errorf("Error reading tile store: %s\n", err.Error( )) | 204 glog.Errorf("Error reading tile store: %s\n", err.Error( )) |
| 160 errorTileLoadingCounter.Inc(1) | 205 errorTileLoadingCounter.Inc(1) |
| 161 } else { | 206 } else { |
| 162 newLabeledTile := a.processTile(tile) | 207 newLabeledTile := a.processTile(tile) |
| 208 newTileCounts, newTestCounts := a.getOutputCounts(newLab eledTile) | |
| 209 | |
| 163 a.mutex.Lock() | 210 a.mutex.Lock() |
| 164 a.currentTile = newLabeledTile | 211 a.currentTile = newLabeledTile |
| 212 a.currentTileCounts = newTileCounts | |
| 213 a.currentTestCounts = newTestCounts | |
| 165 a.mutex.Unlock() | 214 a.mutex.Unlock() |
| 166 } | 215 } |
| 216 glog.Info("Done processing tiles.") | |
| 167 runsCounter.Inc(1) | 217 runsCounter.Inc(1) |
| 168 | 218 |
| 169 // Sleep for a while until the next poll. | 219 // Sleep for a while until the next poll. |
| 170 time.Sleep(timeBetweenPolls) | 220 time.Sleep(timeBetweenPolls) |
| 171 } | 221 } |
| 172 } | 222 } |
| 173 | 223 |
| 174 // Process a tile segment and add it to the currentTile. | 224 // Process a tile segment and add it to the currentTile. |
| 175 func (a *Analyzer) processTile(tile *ptypes.Tile) *LabeledTile { | 225 func (a *Analyzer) processTile(tile *ptypes.Tile) *LabeledTile { |
| 176 result := NewLabeledTile() | 226 result := NewLabeledTile() |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 for idx, digest := range digests { | 291 for idx, digest := range digests { |
| 242 if test, ok := expectations.Tests[testName]; ok { | 292 if test, ok := expectations.Tests[testName]; ok { |
| 243 if foundLabel, ok := test[digest]; ok { | 293 if foundLabel, ok := test[digest]; ok { |
| 244 targetLabels[idx] = foundLabel | 294 targetLabels[idx] = foundLabel |
| 245 } | 295 } |
| 246 } | 296 } |
| 247 } | 297 } |
| 248 | 298 |
| 249 return nil | 299 return nil |
| 250 } | 300 } |
| 301 | |
| 302 // Derive the output counts from the given labeled tile. | |
| 303 func (a *Analyzer) getOutputCounts(labeledTile *LabeledTile) (*GUITileCounts, ma p[string]*GUITestCounts) { | |
| 304 // Stores the aggregated counts of a tile for each test. | |
| 305 tileCountsMap := make(map[string][]LabelCounts, len(labeledTile.Traces)) | |
| 306 | |
| 307 // Stores the aggregated counts for each test and individual trace infor mation. | |
| 308 testCountsMap := make(map[string]*GUITestCounts, len(labeledTile.Traces) ) | |
| 309 | |
| 310 for testName, testTraces := range labeledTile.Traces { | |
| 311 acc := make([]LabelCounts, len(labeledTile.Commits)) | |
| 312 tempTraces := make([]*GUILabeledTrace, 0, len(testTraces)) | |
| 313 | |
| 314 for _, oneTrace := range testTraces { | |
| 315 tempTrace := &GUILabeledTrace{ | |
| 316 Params: oneTrace.Params, | |
| 317 Labels: make([]IdLabel, len(oneTrace.CommitIds)) , | |
| 318 } | |
| 319 | |
| 320 for i, ci := range oneTrace.CommitIds { | |
| 321 switch oneTrace.Labels[i] { | |
| 322 case types.UNTRIAGED: | |
| 323 acc[ci].Unt++ | |
| 324 case types.POSITIVE: | |
| 325 acc[ci].Pos++ | |
| 326 case types.NEGATIVE: | |
| 327 acc[ci].Neg++ | |
| 328 } | |
| 329 tempTrace.Labels[i].C = ci | |
| 330 tempTrace.Labels[i].L = int(oneTrace.Labels[i]) | |
| 331 } | |
| 332 | |
| 333 tempTraces = append(tempTraces, tempTrace) | |
| 334 } | |
| 335 | |
| 336 tileCountsMap[testName] = acc | |
| 337 testCountsMap[testName] = &GUITestCounts{ | |
| 338 Commits: labeledTile.Commits, | |
| 339 Aggregated: acc, | |
| 340 Traces: tempTraces, | |
| 341 } | |
| 342 } | |
| 343 | |
| 344 tileCounts := &GUITileCounts{ | |
| 345 Commits: labeledTile.Commits, | |
| 346 Counts: tileCountsMap, | |
| 347 } | |
| 348 | |
| 349 return tileCounts, testCountsMap | |
| 350 } | |
| OLD | NEW |