| OLD | NEW |
| 1 // tilebuilder is an application that periodically loads new data from BigQuery | 1 // tilebuilder is an application that periodically loads new data from BigQuery |
| 2 // for quick and easy consumption by the skiaperf UI. | 2 // for quick and easy consumption by the skiaperf UI. |
| 3 // | 3 // |
| 4 // The algorithm | 4 // The algorithm |
| 5 // ------------- | 5 // ------------- |
| 6 // | 6 // |
| 7 // Start at level 0. | 7 // Start at level 0. |
| 8 // Find the index of the last tile (0000.gob, 0001.gob, etc) | 8 // Find the index of the last tile (0000.gob, 0001.gob, etc) |
| 9 // nextTile = (last tile)+1 or 0 if no tiles were found. | 9 // nextTile = (last tile)+1 or 0 if no tiles were found. |
| 10 // Find the last commit time from the last tile file, or use BEGINNING_OF_TIME
if there were no tile files. | 10 // Find the last commit time from the last tile file, or use BEGINNING_OF_TIME
if there were no tile files. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 // }} | 31 // }} |
| 32 // | 32 // |
| 33 package main | 33 package main |
| 34 | 34 |
| 35 import ( | 35 import ( |
| 36 "bytes" | 36 "bytes" |
| 37 "flag" | 37 "flag" |
| 38 "fmt" | 38 "fmt" |
| 39 "net" | 39 "net" |
| 40 "net/http" | 40 "net/http" |
| 41 "sort" |
| 41 "text/template" | 42 "text/template" |
| 42 "time" | 43 "time" |
| 43 ) | 44 ) |
| 44 | 45 |
| 45 import ( | 46 import ( |
| 46 "code.google.com/p/goauth2/compute/serviceaccount" | 47 "code.google.com/p/goauth2/compute/serviceaccount" |
| 47 "code.google.com/p/google-api-go-client/bigquery/v2" | 48 "code.google.com/p/google-api-go-client/bigquery/v2" |
| 48 "github.com/golang/glog" | 49 "github.com/golang/glog" |
| 49 "github.com/rcrowley/go-metrics" | 50 "github.com/rcrowley/go-metrics" |
| 50 ) | 51 ) |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 if tile != nil { | 148 if tile != nil { |
| 148 // We are always overwriting the last tile until it is full and
we start on the next tile. | 149 // We are always overwriting the last tile until it is full and
we start on the next tile. |
| 149 nextTile = tile.TileIndex | 150 nextTile = tile.TileIndex |
| 150 if tile.TileIndex > 0 { | 151 if tile.TileIndex > 0 { |
| 151 tile, err := store.Get(0, tile.TileIndex-1) | 152 tile, err := store.Get(0, tile.TileIndex-1) |
| 152 if err != nil { | 153 if err != nil { |
| 153 return startTime, 0, fmt.Errorf("Failed to read
previous tile looking for start conditions: %s", err) | 154 return startTime, 0, fmt.Errorf("Failed to read
previous tile looking for start conditions: %s", err) |
| 154 } | 155 } |
| 155 // Start querying from the timestamp of the last commit
in the last full tile. | 156 // Start querying from the timestamp of the last commit
in the last full tile. |
| 156 startTime = config.NewQuerySince(time.Unix(tile.Commits[
len(tile.Commits)-1].CommitTime, 0)) | 157 startTime = config.NewQuerySince(time.Unix(tile.Commits[
len(tile.Commits)-1].CommitTime, 0)) |
| 158 glog.Infof("Picking from range: First: %v", time.Unix(ti
le.Commits[0].CommitTime, 0)) |
| 159 glog.Infof("Picking from range: Last: %v", time.Unix(til
e.Commits[len(tile.Commits)-1].CommitTime, 0)) |
| 157 } | 160 } |
| 158 } | 161 } |
| 159 return startTime, nextTile, nil | 162 return startTime, nextTile, nil |
| 160 } | 163 } |
| 161 | 164 |
| 162 func tablePrefixFromDatasetName(name config.DatasetName) string { | 165 func tablePrefixFromDatasetName(name config.DatasetName) string { |
| 163 switch name { | 166 switch name { |
| 164 case config.DATASET_SKP: | 167 case config.DATASET_SKP: |
| 165 return "perf_skps_v2.skpbench" | 168 return "perf_skps_v2.skpbench" |
| 166 case config.DATASET_MICRO: | 169 case config.DATASET_MICRO: |
| 167 return "perf_bench_v2.microbench" | 170 return "perf_bench_v2.microbench" |
| 168 } | 171 } |
| 169 return "perf_skps_v2.skpbench" | 172 return "perf_skps_v2.skpbench" |
| 170 } | 173 } |
| 171 | 174 |
| 175 type CommitSlice []*types.Commit |
| 176 |
| 177 type CommitSliceSortable []*types.Commit |
| 178 |
| 179 func (p CommitSliceSortable) Len() int { return len(p) } |
| 180 func (p CommitSliceSortable) Less(i, j int) bool { return p[i].CommitTime < p[j]
.CommitTime } |
| 181 func (p CommitSliceSortable) Swap(i, j int) { p[i], p[j] = p[j], p[i] } |
| 182 |
| 172 // gitCommits returns all the Commits that have associated test data, going | 183 // gitCommits returns all the Commits that have associated test data, going |
| 173 // from now back to 'startTime'. | 184 // from now back to 'startTime'. |
| 174 func gitCommits(service *bigquery.Service, datasetName config.DatasetName, start
Time config.QuerySince) (map[string][]string, []*types.Commit, error) { | 185 func gitCommits(service *bigquery.Service, datasetName config.DatasetName, start
Time config.QuerySince) (map[string][]string, []*types.Commit, error) { |
| 175 dateMap := make(map[string][]string) | 186 dateMap := make(map[string][]string) |
| 176 allCommits := make([]*types.Commit, 0) | 187 allCommits := make([]*types.Commit, 0) |
| 177 | 188 |
| 178 » commitHistory, err := db.readCommitsFromDB() | 189 » commitHashMap := make(map[string]bool) |
| 190 |
| 191 » commitHistory, err := db.ReadCommitsFromDB() |
| 179 if err != nil { | 192 if err != nil { |
| 180 return nil, nil, fmt.Errorf("gitCommits: Did not get the commits
history from the database: ", err) | 193 return nil, nil, fmt.Errorf("gitCommits: Did not get the commits
history from the database: ", err) |
| 181 } | 194 } |
| 182 | 195 |
| 183 queryTemplate := ` | 196 queryTemplate := ` |
| 184 SELECT | 197 SELECT |
| 185 gitHash, FIRST(timestamp) as timestamp, FIRST(gitNumber) as gitNumber | 198 gitHash, FIRST(timestamp) as timestamp, FIRST(gitNumber) as gitNumber |
| 186 FROM | 199 FROM |
| 187 %s%s | 200 %s%s |
| 188 GROUP BY | 201 GROUP BY |
| (...skipping 27 matching lines...) Expand all Loading... |
| 216 if commitHistory[historyIdx].Hash == c.Hash { | 229 if commitHistory[historyIdx].Hash == c.Hash { |
| 217 *c = *commitHistory[historyIdx] | 230 *c = *commitHistory[historyIdx] |
| 218 } else if len(allCommits) > 0 { | 231 } else if len(allCommits) > 0 { |
| 219 // Append to tail_commit | 232 // Append to tail_commit |
| 220 tailCommits := &allCommits[len(allCommit
s)-1].TailCommits | 233 tailCommits := &allCommits[len(allCommit
s)-1].TailCommits |
| 221 *tailCommits = append(*tailCommits, comm
itHistory[historyIdx]) | 234 *tailCommits = append(*tailCommits, comm
itHistory[historyIdx]) |
| 222 // TODO(jcgregorio) Truncate the commit
messages that go into the tail. | 235 // TODO(jcgregorio) Truncate the commit
messages that go into the tail. |
| 223 } | 236 } |
| 224 } | 237 } |
| 225 totalCommits++ | 238 totalCommits++ |
| 226 » » » allCommits = append(allCommits, c) | 239 » » » // Data may show up for a commit across more than one da
y, track if a |
| 240 » » » // commit has already been added, and only add if new. |
| 241 » » » if _, ok := commitHashMap[c.Hash]; !ok { |
| 242 » » » » commitHashMap[c.Hash] = true |
| 243 » » » » allCommits = append(allCommits, c) |
| 244 » » » } |
| 227 } | 245 } |
| 228 dateMap[dates.Date()] = gitHashesForDay | 246 dateMap[dates.Date()] = gitHashesForDay |
| 229 glog.Infof("Finding hashes with data, finished day %s, total com
mits so far %d", dates.Date(), totalCommits) | 247 glog.Infof("Finding hashes with data, finished day %s, total com
mits so far %d", dates.Date(), totalCommits) |
| 230 | 248 |
| 231 } | 249 } |
| 232 » // Now reverse allCommits so that it is oldest first. | 250 » sort.Sort(CommitSliceSortable(allCommits)) |
| 233 » reversedCommits := make([]*types.Commit, len(allCommits), len(allCommits
)) | 251 » for _, c := range allCommits { |
| 234 » for i, c := range allCommits { | 252 » » glog.Infof("gitCommits: allcommits: %s %d\n", c.Hash, c.CommitTi
me) |
| 235 » » reversedCommits[len(allCommits)-i-1] = c | |
| 236 } | 253 } |
| 237 » return dateMap, reversedCommits, nil | 254 » return dateMap, allCommits, nil |
| 238 } | 255 } |
| 239 | 256 |
| 240 // populateParamSet returns the set of all possible values for all the 'params' | 257 // populateParamSet returns the set of all possible values for all the 'params' |
| 241 // in Dataset. | 258 // in Dataset. |
| 242 func populateParamSet(tile *types.Tile) { | 259 func populateParamSet(tile *types.Tile) { |
| 243 // First pull the data out into a map of sets. | 260 // First pull the data out into a map of sets. |
| 244 type ChoiceSet map[string]bool | 261 type ChoiceSet map[string]bool |
| 245 c := make(map[string]ChoiceSet) | 262 c := make(map[string]ChoiceSet) |
| 246 for _, t := range tile.Traces { | 263 for _, t := range tile.Traces { |
| 247 for k, v := range t.Params { | 264 for k, v := range t.Params { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 | 406 |
| 390 func updateAllTileSets(service *bigquery.Service) { | 407 func updateAllTileSets(service *bigquery.Service) { |
| 391 glog.Infof("Starting to update all tile sets.") | 408 glog.Infof("Starting to update all tile sets.") |
| 392 for _, datasetName := range config.ALL_DATASET_NAMES { | 409 for _, datasetName := range config.ALL_DATASET_NAMES { |
| 393 glog.Infof("Starting to update tileset %s.", string(datasetName)
) | 410 glog.Infof("Starting to update tileset %s.", string(datasetName)
) |
| 394 begin := time.Now() | 411 begin := time.Now() |
| 395 | 412 |
| 396 store := filetilestore.NewFileTileStore(*tileDir, string(dataset
Name)) | 413 store := filetilestore.NewFileTileStore(*tileDir, string(dataset
Name)) |
| 397 | 414 |
| 398 startTime, nextTile, err := startConditions(store) | 415 startTime, nextTile, err := startConditions(store) |
| 399 » » glog.Infoln("Found startTime", startTime, "nextTile", nextTile) | 416 » » glog.Infoln("Found startTime", startTime.SqlTsColumn(), "nextTil
e", nextTile) |
| 400 if err != nil { | 417 if err != nil { |
| 401 glog.Errorf("Failed to compute start conditions for data
set %s: %s", string(datasetName), err) | 418 glog.Errorf("Failed to compute start conditions for data
set %s: %s", string(datasetName), err) |
| 402 continue | 419 continue |
| 403 } | 420 } |
| 404 | 421 |
| 405 glog.Infoln("Getting commits") | 422 glog.Infoln("Getting commits") |
| 406 dates, commits, err := gitCommits(service, datasetName, startTim
e) | 423 dates, commits, err := gitCommits(service, datasetName, startTim
e) |
| 407 glog.Infoln("Found commits", commits) | 424 glog.Infoln("Found commits", commits) |
| 408 if err != nil { | 425 if err != nil { |
| 409 glog.Errorf("Failed to read commits for dataset %s: %s",
string(datasetName), err) | 426 glog.Errorf("Failed to read commits for dataset %s: %s",
string(datasetName), err) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 service, err := bigquery.New(client) | 473 service, err := bigquery.New(client) |
| 457 if err != nil { | 474 if err != nil { |
| 458 glog.Fatalf("Failed to create a new BigQuery service object: %s"
, err) | 475 glog.Fatalf("Failed to create a new BigQuery service object: %s"
, err) |
| 459 } | 476 } |
| 460 | 477 |
| 461 updateAllTileSets(service) | 478 updateAllTileSets(service) |
| 462 for _ = range time.Tick(SAMPLE_PERIOD) { | 479 for _ = range time.Tick(SAMPLE_PERIOD) { |
| 463 updateAllTileSets(service) | 480 updateAllTileSets(service) |
| 464 } | 481 } |
| 465 } | 482 } |
| OLD | NEW |