| package types |
| |
| import ( |
| "encoding/json" |
| "io" |
| |
| "go.skia.org/infra/go/paramtools" |
| "go.skia.org/infra/go/tiling" |
| ) |
| |
| // ComplexTile contains an enriched version of a tile loaded through the ingestion process. |
| // It provides ways to handle sparse tiles, where many commits of the underlying raw tile |
| // contain no data and therefore removed. |
| // In either case (sparse or dense tile) it offers two versions of the tile. |
| // one with all ignored traces and one without the ignored traces. |
| // In addition it also contains the ignore rules and information about the larger "sparse" tile |
| // if the tiles at hand were condensed from a larger tile. |
| type ComplexTile interface { |
| // AllCommits returns all commits that were processed to get the data commits. |
| // Its first commit should match the first commit returned when calling DataCommits. |
| AllCommits() []*tiling.Commit |
| |
| // DataCommits returns all commits that contain data. In some busy repos, there are commits that |
| // don't get tested directly because the commits are batched in with others. DataCommits |
| // is a way to get just the commits where some data has been ingested. |
| DataCommits() []*tiling.Commit |
| |
| // FilledCommits returns how many commits in the tile have data. |
| FilledCommits() int |
| |
| // GetTile returns a simple tile either with or without ignored traces depending on the argument. |
| GetTile(is IgnoreState) *tiling.Tile |
| |
| // SetIgnoreRules adds ignore rules to the tile and a sub-tile with the ignores removed. |
| // In other words this function assumes that original tile has been filtered by the |
| // ignore rules that are being passed. |
| SetIgnoreRules(reducedTile *tiling.Tile, ignoreRules paramtools.ParamMatcher) |
| |
| // IgnoreRules returns the ignore rules for this tile. |
| IgnoreRules() paramtools.ParamMatcher |
| |
| // SetSparse tells the tile what the full range of commits analyzed was. |
| SetSparse(allCommits []*tiling.Commit) |
| } |
| |
| type ComplexTileImpl struct { |
| // tileExcludeIgnoredTraces is the current tile without ignored traces. |
| tileExcludeIgnoredTraces *tiling.Tile |
| |
| // tileIncludeIgnoredTraces is the current tile containing all available data. |
| tileIncludeIgnoredTraces *tiling.Tile |
| |
| // ignoreRules contains the rules used to created the TileWithIgnores. |
| ignoreRules paramtools.ParamMatcher |
| |
| // sparseCommits are all the commits that were used condense the underlying tile. |
| sparseCommits []*tiling.Commit |
| } |
| |
| func NewComplexTile(completeTile *tiling.Tile) *ComplexTileImpl { |
| return &ComplexTileImpl{ |
| tileExcludeIgnoredTraces: completeTile, |
| tileIncludeIgnoredTraces: completeTile, |
| } |
| } |
| |
| // SetIgnoreRules fulfills the ComplexTile interface. |
| func (c *ComplexTileImpl) SetIgnoreRules(reducedTile *tiling.Tile, ignoreRules paramtools.ParamMatcher) { |
| c.tileExcludeIgnoredTraces = reducedTile |
| c.ignoreRules = ignoreRules |
| } |
| |
| // SetSparse fulfills the ComplexTile interface. |
| func (c *ComplexTileImpl) SetSparse(sparseCommits []*tiling.Commit) { |
| c.sparseCommits = sparseCommits |
| } |
| |
| // FilledCommits fulfills the ComplexTile interface. |
| func (c *ComplexTileImpl) FilledCommits() int { |
| return len(c.DataCommits()) |
| } |
| |
| // DataCommits fulfills the ComplexTile interface. |
| func (c *ComplexTileImpl) DataCommits() []*tiling.Commit { |
| return c.tileIncludeIgnoredTraces.Commits |
| } |
| |
| // AllCommits fulfills the ComplexTile interface. |
| func (c *ComplexTileImpl) AllCommits() []*tiling.Commit { |
| return c.sparseCommits |
| } |
| |
| // GetTile fulfills the ComplexTile interface. |
| func (c *ComplexTileImpl) GetTile(is IgnoreState) *tiling.Tile { |
| if is == IncludeIgnoredTraces { |
| return c.tileIncludeIgnoredTraces |
| } |
| return c.tileExcludeIgnoredTraces |
| } |
| |
| // IgnoreRules fulfills the ComplexTile interface. |
| func (c *ComplexTileImpl) IgnoreRules() paramtools.ParamMatcher { |
| return c.ignoreRules |
| } |
| |
| // Make sure ComplexTileImpl fulfills the ComplexTile Interface |
| var _ ComplexTile = (*ComplexTileImpl)(nil) |
| |
| // Same as Tile but instead of Traces we preserve the raw JSON. This is a |
| // utility struct that is used to parse a tile where we don't know the |
| // Trace type upfront. |
| type TileWithRawTraces struct { |
| Traces map[tiling.TraceId]json.RawMessage `json:"traces"` |
| ParamSet map[string][]string `json:"param_set"` |
| Commits []*tiling.Commit `json:"commits"` |
| Scale int `json:"scale"` |
| TileIndex int `json:"tileIndex"` |
| } |
| |
| // TileFromJson parses a tile that has been serialized to JSON. |
| // traceExample has to be an instance of the Trace implementation |
| // that needs to be deserialized. |
| // Note: Instead of the type switch below we could use reflection |
| // to be truly generic, but it makes the code harder to read and |
| // currently we only have two types. |
| func TileFromJson(r io.Reader, traceExample tiling.Trace) (*tiling.Tile, error) { |
| factory := func() tiling.Trace { return NewGoldenTrace() } |
| |
| // Decode everything, but the traces. |
| dec := json.NewDecoder(r) |
| var rawTile TileWithRawTraces |
| err := dec.Decode(&rawTile) |
| if err != nil { |
| return nil, err |
| } |
| |
| // Parse the traces. |
| traces := map[tiling.TraceId]tiling.Trace{} |
| for k, rawJson := range rawTile.Traces { |
| newTrace := factory() |
| if err = json.Unmarshal(rawJson, newTrace); err != nil { |
| return nil, err |
| } |
| traces[k] = newTrace.(tiling.Trace) |
| } |
| |
| return &tiling.Tile{ |
| Traces: traces, |
| ParamSet: rawTile.ParamSet, |
| Commits: rawTile.Commits, |
| Scale: rawTile.Scale, |
| TileIndex: rawTile.Scale, |
| }, nil |
| } |
| |
| // TODO(kjlubick): Most (all?) places in gold, we don't look anything up by trace id |
| // Maps aren't the best choice in those cases, so maybe instead of |
| // handing around a map of TraceID -> Trace we can hand around a []TracePair |
| type TracePair struct { |
| ID tiling.TraceId |
| Trace tiling.Trace |
| } |