blob: 89bad89921c5d4da7069ddab0ceae6bde5836f49 [file] [log] [blame]
// Package gs implements utility for accessing Skia perf data in Google Storage.
package gs
import (
"fmt"
"net/http"
"regexp"
"strings"
"time"
)
import (
storage "code.google.com/p/google-api-go-client/storage/v1"
"github.com/golang/glog"
)
var (
// dirMap maps dataset name to a slice with Google Storage subdirectory and file prefix.
dirMap = map[string][]string{
"skps": {"pics-json-v2", "bench_"},
"micro": {"stats-json-v2", "microbench2_"},
}
trybotDataPath = regexp.MustCompile(`^[a-z]*[/]?([0-9]{4}/[0-9]{2}/[0-9]{2}/[0-9]{2}/[0-9a-zA-Z-]+-Trybot/[0-9]+/[0-9]+)$`)
)
const (
GS_PROJECT_BUCKET = "chromium-skia-gm"
)
// GetStorageService returns a Cloud Storage service.
func GetStorageService() (*storage.Service, error) {
return storage.New(http.DefaultClient)
}
// lastDate takes a year and month, and returns the last day of the month.
//
// This is done by going to the first day 0:00 of the next month, subtracting an
// hour, then returning the date.
func lastDate(year int, month time.Month) int {
return time.Date(year, month+1, 1, 0, 0, 0, 0, time.UTC).Add(-time.Hour).Day()
}
// GetLatestGSDirs gets the appropriate directory names in which data
// would be stored between the given timestamp range.
//
// The returning directories cover the range till the date of startTS, and may
// be precise to the hour.
func GetLatestGSDirs(startTS int64, endTS int64, bsSubdir string) []string {
startTime := time.Unix(startTS, 0).UTC()
startYear, startMonth, startDay := startTime.Date()
glog.Infoln("GS dir start time: ", startTime)
endTime := time.Unix(endTS, 0).UTC()
lastAddedTime := startTime
results := make([]string, 0)
newYear, newMonth, newDay := endTime.Date()
newHour := endTime.Hour()
lastYear, lastMonth, _ := lastAddedTime.Date()
if lastYear != newYear {
for i := lastYear; i < newYear; i++ {
if i != startYear {
results = append(results, fmt.Sprintf("%04d", i))
} else {
for j := startMonth; j <= time.December; j++ {
if j == startMonth && startDay > 1 {
for k := startDay; k <= lastDate(i, j); k++ {
results = append(results, fmt.Sprintf("%04d/%02d/%02d", i, j, k))
}
} else {
results = append(results, fmt.Sprintf("%04d/%02d", i, j))
}
}
}
}
lastAddedTime = time.Date(newYear, time.January, 1, 0, 0, 0, 0, time.UTC)
}
lastYear, lastMonth, _ = lastAddedTime.Date()
if lastMonth != newMonth {
for i := lastMonth; i < newMonth; i++ {
if i != startMonth {
results = append(results, fmt.Sprintf("%04d/%02d", lastYear, i))
} else {
for j := startDay; j <= lastDate(lastYear, i); j++ {
results = append(results, fmt.Sprintf("%04d/%02d/%02d", lastYear, i, j))
}
}
}
lastAddedTime = time.Date(newYear, newMonth, 1, 0, 0, 0, 0, time.UTC)
}
lastYear, lastMonth, lastDay := lastAddedTime.Date()
if lastDay != newDay {
for i := lastDay; i < newDay; i++ {
results = append(results, fmt.Sprintf("%04d/%02d/%02d", lastYear, lastMonth, i))
}
lastAddedTime = time.Date(newYear, newMonth, newDay, 0, 0, 0, 0, time.UTC)
}
lastYear, lastMonth, lastDay = lastAddedTime.Date()
lastHour := lastAddedTime.Hour()
for i := lastHour; i < newHour+1; i++ {
results = append(results, fmt.Sprintf("%04d/%02d/%02d/%02d", lastYear, lastMonth, lastDay, i))
}
for i := range results {
results[i] = fmt.Sprintf("%s/%s", bsSubdir, results[i])
}
return results
}
// RequestForStorageURL returns an http.Request for a given Cloud Storage URL.
// This is workaround of a known issue: embedded slashes in URLs require use of
// URL.Opaque property
func RequestForStorageURL(url string) (*http.Request, error) {
r, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, fmt.Errorf("HTTP new request error: %s", err)
}
schemePos := strings.Index(url, ":")
queryPos := strings.Index(url, "?")
if queryPos == -1 {
queryPos = len(url)
}
r.URL.Opaque = url[schemePos+1 : queryPos]
return r, nil
}