• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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/importers/common/args_tracker.h"
18 
19 #include <algorithm>
20 #include <cstdint>
21 
22 #include "src/trace_processor/db/column.h"
23 #include "src/trace_processor/importers/common/args_translation_table.h"
24 #include "src/trace_processor/storage/trace_storage.h"
25 #include "src/trace_processor/types/trace_processor_context.h"
26 #include "src/trace_processor/types/variadic.h"
27 
28 namespace perfetto::trace_processor {
29 
ArgsTracker(TraceProcessorContext * context)30 ArgsTracker::ArgsTracker(TraceProcessorContext* context) : context_(context) {}
31 
~ArgsTracker()32 ArgsTracker::~ArgsTracker() {
33   Flush();
34 }
35 
AddArg(ColumnLegacy * arg_set_id,uint32_t row,StringId flat_key,StringId key,Variadic value,UpdatePolicy update_policy)36 void ArgsTracker::AddArg(ColumnLegacy* arg_set_id,
37                          uint32_t row,
38                          StringId flat_key,
39                          StringId key,
40                          Variadic value,
41                          UpdatePolicy update_policy) {
42   args_.emplace_back();
43 
44   auto* rid_arg = &args_.back();
45   rid_arg->column = arg_set_id;
46   rid_arg->row = row;
47   rid_arg->flat_key = flat_key;
48   rid_arg->key = key;
49   rid_arg->value = value;
50   rid_arg->update_policy = update_policy;
51 }
52 
Flush()53 void ArgsTracker::Flush() {
54   using Arg = GlobalArgsTracker::Arg;
55 
56   if (args_.empty())
57     return;
58 
59   // We sort here because a single packet may add multiple args with different
60   // rowids.
61   auto comparator = [](const Arg& f, const Arg& s) {
62     // We only care that all args for a specific arg set appear in a contiguous
63     // block and that args within one arg set are sorted by key, but not about
64     // the relative order of one block to another. The simplest way to achieve
65     // that is to sort by table column pointer & row, which identify the arg
66     // set, and then by key.
67     if (f.column == s.column && f.row == s.row)
68       return f.key < s.key;
69     if (f.column == s.column)
70       return f.row < s.row;
71     return f.column < s.column;
72   };
73   std::stable_sort(args_.begin(), args_.end(), comparator);
74 
75   for (uint32_t i = 0; i < args_.size();) {
76     const GlobalArgsTracker::Arg& arg = args_[i];
77     auto* col = arg.column;
78     uint32_t row = arg.row;
79 
80     uint32_t next_rid_idx = i + 1;
81     while (next_rid_idx < args_.size() && col == args_[next_rid_idx].column &&
82            row == args_[next_rid_idx].row) {
83       next_rid_idx++;
84     }
85 
86     ArgSetId set_id =
87         context_->global_args_tracker->AddArgSet(&args_[0], i, next_rid_idx);
88     if (col->IsNullable()) {
89       TypedColumn<std::optional<uint32_t>>::FromColumn(col)->Set(row, set_id);
90     } else {
91       TypedColumn<uint32_t>::FromColumn(col)->Set(row, set_id);
92     }
93 
94     i = next_rid_idx;
95   }
96   args_.clear();
97 }
98 
ToCompactArgSet(const ColumnLegacy & column,uint32_t row_number)99 ArgsTracker::CompactArgSet ArgsTracker::ToCompactArgSet(
100     const ColumnLegacy& column,
101     uint32_t row_number) && {
102   CompactArgSet compact_args;
103   for (const auto& arg : args_) {
104     PERFETTO_DCHECK(arg.column == &column);
105     PERFETTO_DCHECK(arg.row == row_number);
106     compact_args.emplace_back(arg.ToCompactArg());
107   }
108   args_.clear();
109   return compact_args;
110 }
111 
NeedsTranslation(const ArgsTranslationTable & table) const112 bool ArgsTracker::NeedsTranslation(const ArgsTranslationTable& table) const {
113   return std::any_of(
114       args_.begin(), args_.end(), [&table](const GlobalArgsTracker::Arg& arg) {
115         return table.NeedsTranslation(arg.flat_key, arg.key, arg.value.type);
116       });
117 }
118 
BoundInserter(ArgsTracker * args_tracker,ColumnLegacy * arg_set_id_column,uint32_t row)119 ArgsTracker::BoundInserter::BoundInserter(ArgsTracker* args_tracker,
120                                           ColumnLegacy* arg_set_id_column,
121                                           uint32_t row)
122     : args_tracker_(args_tracker),
123       arg_set_id_column_(arg_set_id_column),
124       row_(row) {}
125 
126 ArgsTracker::BoundInserter::~BoundInserter() = default;
127 
128 }  // namespace perfetto::trace_processor
129