• 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   static constexpr uint32_t kDefaultBatchSplitThreshold = 128 * 1024;
57   explicit QueryResultSerializer(Iterator);
58   ~QueryResultSerializer();
59 
60   // No copy or move.
61   QueryResultSerializer(const QueryResultSerializer&) = delete;
62   QueryResultSerializer& operator=(const QueryResultSerializer&) = delete;
63 
64   // Appends the data to the passed protozero message. It returns true if more
65   // chunks are available (i.e. it returns NOT(|eof_reached_||)). The caller is
66   // supposed to keep calling this function until it returns false.
67   bool Serialize(protos::pbzero::QueryResult*);
68 
69   // Like the above but stitches everything together in a vector. Incurs in
70   // extra copies.
71   bool Serialize(std::vector<uint8_t>*);
72 
set_batch_size_for_testing(uint32_t cells_per_batch,uint32_t thres)73   void set_batch_size_for_testing(uint32_t cells_per_batch, uint32_t thres) {
74     cells_per_batch_ = cells_per_batch;
75     batch_split_threshold_ = thres;
76   }
77 
78  private:
79   void SerializeMetadata(protos::pbzero::QueryResult*);
80   void SerializeBatch(protos::pbzero::QueryResult*);
81   void MaybeSerializeError(protos::pbzero::QueryResult*);
82 
83   std::unique_ptr<IteratorImpl> iter_;
84   const uint32_t num_cols_;
85   bool did_write_metadata_ = false;
86   bool eof_reached_ = false;
87   uint32_t col_ = UINT32_MAX;
88 
89   // These params specify the thresholds for splitting the results in batches,
90   // in terms of: (1) max cells (row x cols); (2) serialized batch size in
91   // bytes, whichever is reached first. Note also that the byte limit is not
92   // 100% accurate and can occasionally yield to batches slighly larger than
93   // the limit (it splits on the next row *after* the limit is hit).
94   // Overridable for testing only.
95   uint32_t cells_per_batch_ = 50000;
96   uint32_t batch_split_threshold_ = kDefaultBatchSplitThreshold;
97 };
98 
99 }  // namespace trace_processor
100 }  // namespace perfetto
101 
102 #endif  // SRC_TRACE_PROCESSOR_RPC_QUERY_RESULT_SERIALIZER_H_
103