1 /* 2 * Copyright (C) 2024 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_PERFETTO_SQL_INTRINSICS_FUNCTIONS_DOMINATOR_TREE_H_ 18 #define SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_FUNCTIONS_DOMINATOR_TREE_H_ 19 20 #include "src/trace_processor/containers/string_pool.h" 21 #include "src/trace_processor/sqlite/bindings/sqlite_aggregate_function.h" 22 23 namespace perfetto::trace_processor { 24 25 // An SQL aggregate-function which computes the dominator-tree [1] of a graph. 26 // 27 // Arguments: 28 // 1) |source_node_id|: a non-null uint32 corresponding to the source of edge. 29 // 2) |dest_node_id|: a non-null uint32 corresponding to the destination of 30 // the edge. 31 // 3) |start_node_id|: a non-null uint32 corresponding to of the start node in 32 // the graph from which reachability should be computed. 33 // 34 // Returns: 35 // A table with the dominator tree of the input graph. The schema of the table 36 // is (node_id int64_t, dominator_node_id optional<int64_t>). 37 // 38 // Note: as this function takes table columns as an argument, it is not intended 39 // to be used directly from SQL: instead a "dominator_tree" macro exists in 40 // the standard library, wrapping it and making it user-friendly. 41 // 42 // Implementation notes: 43 // This class implements the Lengauer-Tarjan Dominators algorithm [2]. This was 44 // chosen as it runs on O(nlog(n)) time: as we expect this class to be used on 45 // large tables (i.e. tables containing Java heap graphs), it's important that 46 // the code is efficient. 47 // 48 // As Lengauer-Tarjan Dominators is not the most intuitive algorithm [3] might 49 // be a useful resource for grasping the key principles behind it. 50 // 51 // [1] https://en.wikipedia.org/wiki/Dominator_(graph_theory) 52 // [2] https://dl.acm.org/doi/10.1145/357062.357071 53 class DominatorTree : public SqliteAggregateFunction<DominatorTree> { 54 public: 55 static constexpr char kName[] = "__intrinsic_dominator_tree"; 56 static constexpr int kArgCount = 3; 57 using UserDataContext = StringPool; 58 59 static void Step(sqlite3_context*, int argc, sqlite3_value** argv); 60 static void Final(sqlite3_context* ctx); 61 }; 62 63 } // namespace perfetto::trace_processor 64 65 #endif // SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_FUNCTIONS_DOMINATOR_TREE_H_ 66