1-- 2-- Copyright 2023 The Android Open Source Project 3-- 4-- Licensed under the Apache License, Version 2.0 (the "License"); 5-- you may not use this file except in compliance with the License. 6-- You may obtain a copy of the License at 7-- 8-- https://www.apache.org/licenses/LICENSE-2.0 9-- 10-- Unless required by applicable law or agreed to in writing, software 11-- distributed under the License is distributed on an "AS IS" BASIS, 12-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13-- See the License for the specific language governing permissions and 14-- limitations under the License. 15INCLUDE PERFETTO MODULE slices.with_context; 16INCLUDE PERFETTO MODULE intervals.overlap; 17 18-- The concept of a "flat slice" is to take the data in the slice table and 19-- remove all notion of nesting; we do this by projecting every slice in a stack to 20-- their ancestor slice, i.e at any point in time, taking the most specific active 21-- slice (i.e. the slice at the bottom of the stack) and representing that as the 22-- *only* slice that was running during that period. 23-- 24-- This concept becomes very useful when you try and linearise a trace and 25-- compare it with other traces spanning the same user action; "self time" (i.e. 26-- time spent in a slice but *not* any children) is easily computed and span 27-- joins with thread state become possible without limiting to only depth zero 28--- slices. 29-- 30-- Note that, no slices will be generated for intervals without without any slices. 31-- 32-- As an example, consider the following slice stack: 33-- ``` 34-- A-------------B. 35-- ----C----D----. 36-- ``` 37-- The flattened slice will be: 38-- ``` 39-- A----C----D----B. 40-- ``` 41-- 42-- @column slice_id Id of most active slice. 43-- @column ts Timestamp when `slice.id` became the most active slice. 44-- @column dur Duration of `slice.id` as the most active slice until the next active slice. 45-- @column depth Depth of `slice.id` in the original stack. 46-- @column name Name of `slice.id`. 47-- @column root_name Name of the top most slice of the stack. 48-- @column root_id Id of of the top most slice of the stack. 49-- @column track_id Alias for `slice.track_id`. 50-- @column utid Alias for `thread.utid`. 51-- @column tid Alias for `thread.tid` 52-- @column thread_name Alias for `thread.name`. 53-- @column upid Alias for `process.upid`. 54-- @column pid Alias for `process.pid`. 55-- @column process_name Alias for `process.name`. 56CREATE TABLE _slice_flattened 57AS 58WITH 59 root_slices AS ( 60 SELECT * FROM slice WHERE parent_id IS NULL 61 ), 62 child_slices AS ( 63 SELECT anc.id AS root_id, slice.* 64 FROM slice 65 JOIN ancestor_slice(slice.id) anc 66 WHERE slice.parent_id IS NOT NULL 67 ), 68 flat_slices AS ( 69 SELECT id, ts, dur FROM _intervals_flatten !(root_slices, child_slices) 70 ) 71SELECT 72 id AS slice_id, 73 flat_slices.ts, 74 flat_slices.dur, 75 depth, 76 name, 77 track_id, 78 utid, 79 tid, 80 thread_name, 81 upid, 82 pid, 83 process_name 84FROM flat_slices 85JOIN thread_slice 86 USING (id); 87 88CREATE 89 INDEX _slice_flattened_id_idx 90ON _slice_flattened(slice_id); 91 92CREATE 93 INDEX _slice_flattened_ts_idx 94ON _slice_flattened(ts); 95