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 {Actions} from '../../common/actions'; 16import {ColumnDef} from '../../common/aggregation_data'; 17import {Engine} from '../../common/engine'; 18import { 19 SLICE_AGGREGATION_PIVOT_TABLE_ID 20} from '../../common/pivot_table_common'; 21import {Area, Sorting} from '../../common/state'; 22import {toNs} from '../../common/time'; 23import {PIVOT_TABLE_FLAG} from '../../frontend/keyboard_event_handler'; 24import { 25 ASYNC_SLICE_TRACK_KIND, 26 Config as AsyncSliceConfig 27} from '../../tracks/async_slices/common'; 28import { 29 Config as SliceConfig, 30 SLICE_TRACK_KIND 31} from '../../tracks/chrome_slices/common'; 32import {globals} from '../globals'; 33 34import {AggregationController} from './aggregation_controller'; 35 36function addPivotTableOnAreaSelection( 37 selectedTrackIds: number[], startSec: number, endSec: number) { 38 const selectedPivots = 39 [{tableName: 'slice', columnName: 'name', isStackPivot: false}]; 40 41 const selectedAggregations = [ 42 {tableName: 'slice', columnName: 'dur', aggregation: 'SUM', order: 'DESC'}, 43 {tableName: 'slice', columnName: 'dur', aggregation: 'AVG', order: 'DESC'}, 44 {tableName: 'slice', columnName: 'id', aggregation: 'COUNT', order: 'DESC'} 45 ]; 46 47 globals.dispatch(Actions.addNewPivotTable({ 48 name: 'Pivot Table - Slices', 49 pivotTableId: SLICE_AGGREGATION_PIVOT_TABLE_ID, 50 selectedPivots, 51 selectedAggregations, 52 traceTime: {startSec, endSec}, 53 selectedTrackIds 54 })); 55 56 globals.dispatch(Actions.setPivotTableRequest( 57 {pivotTableId: SLICE_AGGREGATION_PIVOT_TABLE_ID, action: 'QUERY'})); 58} 59 60export function getSelectedTrackIds(area: Area): number[] { 61 const selectedTrackIds = []; 62 for (const trackId of area.tracks) { 63 const track = globals.state.tracks[trackId]; 64 // Track will be undefined for track groups. 65 if (track !== undefined) { 66 if (track.kind === SLICE_TRACK_KIND) { 67 selectedTrackIds.push((track.config as SliceConfig).trackId); 68 } 69 if (track.kind === ASYNC_SLICE_TRACK_KIND) { 70 const config = track.config as AsyncSliceConfig; 71 for (const id of config.trackIds) { 72 selectedTrackIds.push(id); 73 } 74 } 75 } 76 } 77 return selectedTrackIds; 78} 79 80export class SliceAggregationController extends AggregationController { 81 async createAggregateView(engine: Engine, area: Area) { 82 await engine.query(`drop view if exists ${this.kind};`); 83 84 const selectedTrackIds = getSelectedTrackIds(area); 85 86 if (selectedTrackIds.length === 0) return false; 87 88 if (PIVOT_TABLE_FLAG.get()) { 89 addPivotTableOnAreaSelection( 90 selectedTrackIds, area.startSec, area.endSec); 91 } 92 93 const query = `create view ${this.kind} as 94 SELECT 95 name, 96 sum(dur) AS total_dur, 97 sum(dur)/count(1) as avg_dur, 98 count(1) as occurrences 99 FROM slices 100 WHERE track_id IN (${selectedTrackIds}) AND 101 ts + dur > ${toNs(area.startSec)} AND 102 ts < ${toNs(area.endSec)} group by name`; 103 104 await engine.query(query); 105 return true; 106 } 107 108 getTabName() { 109 return 'Slices'; 110 } 111 112 async getExtra() {} 113 114 getDefaultSorting(): Sorting { 115 return {column: 'total_dur', direction: 'DESC'}; 116 } 117 118 getColumnDefinitions(): ColumnDef[] { 119 return [ 120 { 121 title: 'Name', 122 kind: 'STRING', 123 columnConstructor: Uint16Array, 124 columnId: 'name', 125 }, 126 { 127 title: 'Wall duration (ms)', 128 kind: 'TIMESTAMP_NS', 129 columnConstructor: Float64Array, 130 columnId: 'total_dur', 131 sum: true 132 }, 133 { 134 title: 'Avg Wall duration (ms)', 135 kind: 'TIMESTAMP_NS', 136 columnConstructor: Float64Array, 137 columnId: 'avg_dur' 138 }, 139 { 140 title: 'Occurrences', 141 kind: 'NUMBER', 142 columnConstructor: Uint16Array, 143 columnId: 'occurrences', 144 sum: true 145 } 146 ]; 147 } 148} 149