• 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/dynamic/experimental_counter_dur_generator.h"
18 
19 namespace perfetto {
20 namespace trace_processor {
21 
ExperimentalCounterDurGenerator(const tables::CounterTable & table)22 ExperimentalCounterDurGenerator::ExperimentalCounterDurGenerator(
23     const tables::CounterTable& table)
24     : counter_table_(&table) {}
25 ExperimentalCounterDurGenerator::~ExperimentalCounterDurGenerator() = default;
26 
CreateSchema()27 Table::Schema ExperimentalCounterDurGenerator::CreateSchema() {
28   Table::Schema schema = tables::CounterTable::Schema();
29   schema.columns.emplace_back(
30       Table::Schema::Column{"dur", SqlValue::Type::kLong, false /* is_id */,
31                             false /* is_sorted */, false /* is_hidden */});
32   schema.columns.emplace_back(
33       Table::Schema::Column{"delta", SqlValue::Type::kLong, false /* is_id */,
34                             false /* is_sorted */, false /* is_hidden */});
35   return schema;
36 }
37 
TableName()38 std::string ExperimentalCounterDurGenerator::TableName() {
39   return "experimental_counter_dur";
40 }
41 
EstimateRowCount()42 uint32_t ExperimentalCounterDurGenerator::EstimateRowCount() {
43   return counter_table_->row_count();
44 }
45 
ValidateConstraints(const QueryConstraints &)46 base::Status ExperimentalCounterDurGenerator::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 ExperimentalCounterDurGenerator::ComputeTable(
52     const std::vector<Constraint>&,
53     const std::vector<Order>&,
54     const BitVector&,
55     std::unique_ptr<Table>& table_return) {
56   if (!dur_column_) {
57     dur_column_.reset(
58         new NullableVector<int64_t>(ComputeDurColumn(*counter_table_)));
59     delta_column_.reset(
60         new NullableVector<double>(ComputeDeltaColumn(*counter_table_)));
61   }
62 
63   Table t = counter_table_
64                 ->ExtendWithColumn("dur", std::move(dur_column_.get()),
65                                    TypedColumn<int64_t>::default_flags())
66                 .ExtendWithColumn("delta", std::move(delta_column_.get()),
67                                   TypedColumn<int64_t>::default_flags());
68 
69   table_return.reset(new Table(t.Copy()));
70   return base::OkStatus();
71 }
72 
73 // static
ComputeDurColumn(const Table & table)74 NullableVector<int64_t> ExperimentalCounterDurGenerator::ComputeDurColumn(
75     const Table& table) {
76   // Keep track of the last seen row for each track id.
77   std::unordered_map<TrackId, uint32_t> last_row_for_track_id;
78   NullableVector<int64_t> dur;
79 
80   const auto* ts_col =
81       TypedColumn<int64_t>::FromColumn(table.GetColumnByName("ts"));
82   const auto* track_id_col =
83       TypedColumn<tables::CounterTrackTable::Id>::FromColumn(
84           table.GetColumnByName("track_id"));
85 
86   for (uint32_t i = 0; i < table.row_count(); ++i) {
87     // Check if we already have a previous row for the current track id.
88     TrackId track_id = (*track_id_col)[i];
89     auto it = last_row_for_track_id.find(track_id);
90     if (it == last_row_for_track_id.end()) {
91       // This means we don't have any row - start tracking this row for the
92       // future.
93       last_row_for_track_id.emplace(track_id, i);
94     } else {
95       // This means we have an previous row for the current track id. Update
96       // the duration of the previous row to be up to the current ts.
97       uint32_t old_row = it->second;
98       it->second = i;
99       dur.Set(old_row, (*ts_col)[i] - (*ts_col)[old_row]);
100     }
101     // Append -1 to mark this event as not having been finished. On a later
102     // row, we may set this to have the correct value.
103     dur.Append(-1);
104   }
105   return dur;
106 }
107 
108 // static
ComputeDeltaColumn(const Table & table)109 NullableVector<double> ExperimentalCounterDurGenerator::ComputeDeltaColumn(
110     const Table& table) {
111   // Keep track of the last seen row for each track id.
112   std::unordered_map<TrackId, uint32_t> last_row_for_track_id;
113   NullableVector<double> delta;
114 
115   const auto* value_col =
116       TypedColumn<double>::FromColumn(table.GetColumnByName("value"));
117   const auto* track_id_col =
118       TypedColumn<tables::CounterTrackTable::Id>::FromColumn(
119           table.GetColumnByName("track_id"));
120 
121   for (uint32_t i = 0; i < table.row_count(); ++i) {
122     // Check if we already have a previous row for the current track id.
123     TrackId track_id = (*track_id_col)[i];
124     auto it = last_row_for_track_id.find(track_id);
125     if (it == last_row_for_track_id.end()) {
126       // This means we don't have any row - start tracking this row for the
127       // future.
128       last_row_for_track_id.emplace(track_id, i);
129     } else {
130       // This means we have an previous row for the current track id. Update
131       // the duration of the previous row to be up to the current ts.
132       uint32_t old_row = it->second;
133       it->second = i;
134       delta.Set(old_row, (*value_col)[i] - (*value_col)[old_row]);
135     }
136     delta.Append(0);
137   }
138   return delta;
139 }
140 
141 }  // namespace trace_processor
142 }  // namespace perfetto
143