• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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  *      http://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.
15  */
16 
17 #include "src/trace_processor/prelude/table_functions/experimental_counter_dur.h"
18 
19 #include "src/trace_processor/prelude/table_functions/tables_py.h"
20 
21 namespace perfetto {
22 namespace trace_processor {
23 namespace tables {
24 
25 ExperimentalCounterDurTable::~ExperimentalCounterDurTable() = default;
26 
27 }  // namespace tables
28 
ExperimentalCounterDur(const tables::CounterTable & table)29 ExperimentalCounterDur::ExperimentalCounterDur(
30     const tables::CounterTable& table)
31     : counter_table_(&table) {}
32 ExperimentalCounterDur::~ExperimentalCounterDur() = default;
33 
CreateSchema()34 Table::Schema ExperimentalCounterDur::CreateSchema() {
35   return tables::ExperimentalCounterDurTable::ComputeStaticSchema();
36 }
37 
TableName()38 std::string ExperimentalCounterDur::TableName() {
39   return tables::ExperimentalCounterDurTable::Name();
40 }
41 
EstimateRowCount()42 uint32_t ExperimentalCounterDur::EstimateRowCount() {
43   return counter_table_->row_count();
44 }
45 
ValidateConstraints(const QueryConstraints &)46 base::Status ExperimentalCounterDur::ValidateConstraints(
47     const QueryConstraints&) {
48   return base::OkStatus();
49 }
50 
ComputeTable(const std::vector<Constraint> &,const std::vector<Order> &,const BitVector &,std::unique_ptr<Table> & table_return)51 base::Status ExperimentalCounterDur::ComputeTable(
52     const std::vector<Constraint>&,
53     const std::vector<Order>&,
54     const BitVector&,
55     std::unique_ptr<Table>& table_return) {
56   if (!counter_dur_table_) {
57     counter_dur_table_ = tables::ExperimentalCounterDurTable::ExtendParent(
58         *counter_table_, ComputeDurColumn(*counter_table_),
59         ComputeDeltaColumn(*counter_table_));
60   }
61   table_return.reset(new Table(counter_dur_table_->Copy()));
62   return base::OkStatus();
63 }
64 
65 // static
ComputeDurColumn(const CounterTable & table)66 ColumnStorage<int64_t> ExperimentalCounterDur::ComputeDurColumn(
67     const CounterTable& table) {
68   // Keep track of the last seen row for each track id.
69   std::unordered_map<TrackId, CounterTable::RowNumber> last_row_for_track_id;
70   ColumnStorage<int64_t> dur;
71 
72   for (auto table_it = table.IterateRows(); table_it; ++table_it) {
73     // Check if we already have a previous row for the current track id.
74     TrackId track_id = table_it.track_id();
75     auto it = last_row_for_track_id.find(track_id);
76     if (it == last_row_for_track_id.end()) {
77       // This means we don't have any row - start tracking this row for the
78       // future.
79       last_row_for_track_id.emplace(track_id, table_it.row_number());
80     } else {
81       // This means we have an previous row for the current track id. Update
82       // the duration of the previous row to be up to the current ts.
83       CounterTable::RowNumber old_row = it->second;
84       it->second = table_it.row_number();
85       dur.Set(old_row.row_number(),
86               table_it.ts() - old_row.ToRowReference(table).ts());
87     }
88     // Append -1 to mark this event as not having been finished. On a later
89     // row, we may set this to have the correct value.
90     dur.Append(-1);
91   }
92   return dur;
93 }
94 
95 // static
ComputeDeltaColumn(const CounterTable & table)96 ColumnStorage<double> ExperimentalCounterDur::ComputeDeltaColumn(
97     const CounterTable& table) {
98   // Keep track of the last seen row for each track id.
99   std::unordered_map<TrackId, CounterTable::RowNumber> last_row_for_track_id;
100   ColumnStorage<double> delta;
101 
102   for (auto table_it = table.IterateRows(); table_it; ++table_it) {
103     // Check if we already have a previous row for the current track id.
104     TrackId track_id = table_it.track_id();
105     auto it = last_row_for_track_id.find(track_id);
106     if (it == last_row_for_track_id.end()) {
107       // This means we don't have any row - start tracking this row for the
108       // future.
109       last_row_for_track_id.emplace(track_id, table_it.row_number());
110     } else {
111       // This means we have an previous row for the current track id. Update
112       // the duration of the previous row to be up to the current ts.
113       CounterTable::RowNumber old_row = it->second;
114       it->second = table_it.row_number();
115       delta.Set(old_row.row_number(),
116                 table_it.value() - old_row.ToRowReference(table).value());
117     }
118     delta.Append(0);
119   }
120   return delta;
121 }
122 
123 }  // namespace trace_processor
124 }  // namespace perfetto
125