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/args_tracker.h"
18 
19 #include <algorithm>
20 
21 namespace perfetto {
22 namespace trace_processor {
23 
ArgsTracker(TraceProcessorContext * context)24 ArgsTracker::ArgsTracker(TraceProcessorContext* context) : context_(context) {}
25 
AddArg(RowId row_id,StringId flat_key,StringId key,Variadic value)26 void ArgsTracker::AddArg(RowId row_id,
27                          StringId flat_key,
28                          StringId key,
29                          Variadic value) {
30   args_.emplace_back();
31 
32   auto* rid_arg = &args_.back();
33   rid_arg->row_id = row_id;
34   rid_arg->flat_key = flat_key;
35   rid_arg->key = key;
36   rid_arg->value = value;
37 }
38 
Flush()39 void ArgsTracker::Flush() {
40   using Arg = TraceStorage::Args::Arg;
41 
42   // We sort here because a single packet may add multiple args with different
43   // rowids.
44   auto comparator = [](const Arg& f, const Arg& s) {
45     return f.row_id < s.row_id;
46   };
47   std::sort(args_.begin(), args_.end(), comparator);
48 
49   auto* storage = context_->storage.get();
50   for (uint32_t i = 0; i < args_.size();) {
51     const auto& args = args_[i];
52     RowId rid = args.row_id;
53 
54     uint32_t next_rid_idx = i + 1;
55     while (next_rid_idx < args_.size() && rid == args_[next_rid_idx].row_id)
56       next_rid_idx++;
57 
58     auto set_id = storage->mutable_args()->AddArgSet(args_, i, next_rid_idx);
59     auto pair = TraceStorage::ParseRowId(rid);
60     switch (pair.first) {
61       case TableId::kRawEvents:
62         storage->mutable_raw_events()->set_arg_set_id(pair.second, set_id);
63         break;
64       case TableId::kCounterValues:
65         storage->mutable_counter_values()->set_arg_set_id(pair.second, set_id);
66         break;
67       case TableId::kInstants:
68         storage->mutable_instants()->set_arg_set_id(pair.second, set_id);
69         break;
70       default:
71         PERFETTO_FATAL("Unsupported table to insert args into");
72     }
73     i = next_rid_idx;
74   }
75   args_.clear();
76 }
77 
78 }  // namespace trace_processor
79 }  // namespace perfetto
80