• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2020 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {ColumnDef} from '../../common/aggregation_data';
16import {Area, Sorting} from '../../common/state';
17import {globals} from '../../frontend/globals';
18import {Engine} from '../../trace_processor/engine';
19
20import {AggregationController} from './aggregation_controller';
21import {
22  ASYNC_SLICE_TRACK_KIND,
23  THREAD_SLICE_TRACK_KIND,
24} from '../../core/track_kinds';
25
26export function getSelectedTrackKeys(area: Area): number[] {
27  const selectedTrackKeys: number[] = [];
28  for (const trackKey of area.tracks) {
29    const track = globals.state.tracks[trackKey];
30    // Track will be undefined for track groups.
31    if (track?.uri !== undefined) {
32      const trackInfo = globals.trackManager.resolveTrackInfo(track.uri);
33      if (trackInfo?.kind === THREAD_SLICE_TRACK_KIND) {
34        trackInfo.trackIds && selectedTrackKeys.push(...trackInfo.trackIds);
35      }
36      if (trackInfo?.kind === ASYNC_SLICE_TRACK_KIND) {
37        trackInfo.trackIds && selectedTrackKeys.push(...trackInfo.trackIds);
38      }
39    }
40  }
41  return selectedTrackKeys;
42}
43
44export class SliceAggregationController extends AggregationController {
45  async createAggregateView(engine: Engine, area: Area) {
46    await engine.query(`drop view if exists ${this.kind};`);
47
48    const selectedTrackKeys = getSelectedTrackKeys(area);
49
50    if (selectedTrackKeys.length === 0) return false;
51
52    const query = `create view ${this.kind} as
53        SELECT
54        name,
55        sum(dur) AS total_dur,
56        sum(dur)/count(1) as avg_dur,
57        count(1) as occurrences
58        FROM slices
59        WHERE track_id IN (${selectedTrackKeys}) AND
60        ts + dur > ${area.start} AND
61        ts < ${area.end} group by name`;
62
63    await engine.query(query);
64    return true;
65  }
66
67  getTabName() {
68    return 'Slices';
69  }
70
71  async getExtra() {}
72
73  getDefaultSorting(): Sorting {
74    return {column: 'total_dur', direction: 'DESC'};
75  }
76
77  getColumnDefinitions(): ColumnDef[] {
78    return [
79      {
80        title: 'Name',
81        kind: 'STRING',
82        columnConstructor: Uint32Array,
83        columnId: 'name',
84      },
85      {
86        title: 'Wall duration (ms)',
87        kind: 'TIMESTAMP_NS',
88        columnConstructor: Float64Array,
89        columnId: 'total_dur',
90        sum: true,
91      },
92      {
93        title: 'Avg Wall duration (ms)',
94        kind: 'TIMESTAMP_NS',
95        columnConstructor: Float64Array,
96        columnId: 'avg_dur',
97      },
98      {
99        title: 'Occurrences',
100        kind: 'NUMBER',
101        columnConstructor: Uint32Array,
102        columnId: 'occurrences',
103        sum: true,
104      },
105    ];
106  }
107}
108