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_SQLITE_QUERY_CACHE_H_ 18 #define SRC_TRACE_PROCESSOR_SQLITE_QUERY_CACHE_H_ 19 20 #include "perfetto/ext/base/optional.h" 21 22 #include "src/trace_processor/db/table.h" 23 #include "src/trace_processor/sqlite/query_constraints.h" 24 25 namespace perfetto { 26 namespace trace_processor { 27 28 // Implements a simple caching strategy for commonly executed queries. 29 // TODO(lalitm): the design of this class is very experimental. It was mainly 30 // introduced to solve a specific problem (slow process summary tracks in the 31 // Perfetto UI) and should not be modified without a full design discussion. 32 class QueryCache { 33 public: 34 using Constraint = QueryConstraints::Constraint; 35 36 // Returns a cached table if the passed query set are currenly cached or 37 // nullptr otherwise. GetIfCached(const Table * source,const std::vector<Constraint> & cs)38 std::shared_ptr<Table> GetIfCached(const Table* source, 39 const std::vector<Constraint>& cs) const { 40 if (cached_.source != source || cs.size() != cached_.constraints.size()) 41 return nullptr; 42 43 auto p = [](const Constraint& a, const Constraint& b) { 44 return a.column == b.column && a.op == b.op; 45 }; 46 bool same_cs = 47 std::equal(cs.begin(), cs.end(), cached_.constraints.begin(), p); 48 return same_cs ? cached_.table : nullptr; 49 } 50 51 // Caches the table with the given source, constraint and order set. Returns 52 // a pointer to the newly cached table. GetOrCache(const Table * source,const std::vector<QueryConstraints::Constraint> & cs,std::function<Table ()> fn)53 std::shared_ptr<Table> GetOrCache( 54 const Table* source, 55 const std::vector<QueryConstraints::Constraint>& cs, 56 std::function<Table()> fn) { 57 std::shared_ptr<Table> cached = GetIfCached(source, cs); 58 if (cached) 59 return cached; 60 61 cached_.source = source; 62 cached_.constraints = cs; 63 cached_.table.reset(new Table(fn())); 64 return cached_.table; 65 } 66 67 private: 68 struct CachedTable { 69 std::shared_ptr<Table> table; 70 71 const Table* source = nullptr; 72 std::vector<Constraint> constraints; 73 }; 74 75 CachedTable cached_; 76 }; 77 78 } // namespace trace_processor 79 } // namespace perfetto 80 81 #endif // SRC_TRACE_PROCESSOR_SQLITE_QUERY_CACHE_H_ 82