• 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 #ifndef SRC_TRACE_PROCESSOR_RPC_QUERY_RESULT_SERIALIZER_H_
18 #define SRC_TRACE_PROCESSOR_RPC_QUERY_RESULT_SERIALIZER_H_
19 
20 #include <memory>
21 #include <vector>
22 
23 #include <limits.h>
24 #include <stddef.h>
25 #include <stdint.h>
26 
27 namespace perfetto {
28 
29 namespace protos {
30 namespace pbzero {
31 class QueryResult;
32 }  // namespace pbzero
33 }  // namespace protos
34 
35 namespace trace_processor {
36 
37 class Iterator;
38 class IteratorImpl;
39 
40 // This class serializes a TraceProcessor query result (i.e. an Iterator)
41 // into batches of QueryResult (trace_processor.proto). This class
42 // returns results in batches, allowing to deal with O(M) results without
43 // full memory buffering. It works as follows:
44 // - The iterator is passed in the constructor.
45 // - The client is expected to call Serialize(out_buf) until EOF is reached.
46 // - For each Serialize() call, this class will serialize a batch of cells,
47 //   stopping when either when a number of cells (|cells_per_batch_|) is reached
48 //   or when the batch size exceeds (batch_split_threshold_).
49 //   A batch is guaranteed to contain a number of cells that is an integer
50 //   multiple of the column count (i.e. a batch is not truncated in the middle
51 //   of a row).
52 // The intended use case is streaaming these batches onto through a
53 // chunked-encoded HTTP response, or through a repetition of Wasm calls.
54 class QueryResultSerializer {
55  public:
56   explicit QueryResultSerializer(Iterator);
57   ~QueryResultSerializer();
58 
59   // No copy or move.
60   QueryResultSerializer(const QueryResultSerializer&) = delete;
61   QueryResultSerializer& operator=(const QueryResultSerializer&) = delete;
62 
63   // Appends the data to the passed protozero message. It returns true if more
64   // chunks are available (i.e. it returns NOT(|eof_reached_||)). The caller is
65   // supposed to keep calling this function until it returns false.
66   bool Serialize(protos::pbzero::QueryResult*);
67 
68   // Like the above but stitches everything together in a vector. Incurs in
69   // extra copies.
70   bool Serialize(std::vector<uint8_t>*);
71 
set_batch_size_for_testing(uint32_t cells_per_batch,uint32_t thres)72   void set_batch_size_for_testing(uint32_t cells_per_batch, uint32_t thres) {
73     cells_per_batch_ = cells_per_batch;
74     batch_split_threshold_ = thres;
75   }
76 
77  private:
78   void SerializeColumnNames(protos::pbzero::QueryResult*);
79   void SerializeBatch(protos::pbzero::QueryResult*);
80   void MaybeSerializeError(protos::pbzero::QueryResult*);
81 
82   std::unique_ptr<IteratorImpl> iter_;
83   const uint32_t num_cols_;
84   bool did_write_column_names_ = false;
85   bool eof_reached_ = false;
86   uint32_t col_ = UINT32_MAX;
87 
88   // These params specify the thresholds for splitting the results in batches,
89   // in terms of: (1) max cells (row x cols); (2) serialized batch size in
90   // bytes, whichever is reached first. Note also that the byte limit is not
91   // 100% accurate and can occasionally yield to batches slighly larger than
92   // the limit (it splits on the next row *after* the limit is hit).
93   // Overridable for testing only.
94   uint32_t cells_per_batch_ = 50000;
95   uint32_t batch_split_threshold_ = 1024 * 128;
96 };
97 
98 }  // namespace trace_processor
99 }  // namespace perfetto
100 
101 #endif  // SRC_TRACE_PROCESSOR_RPC_QUERY_RESULT_SERIALIZER_H_
102