Merge "Improve dominator tree view performance" into main
diff --git a/ui/src/controller/flamegraph_controller.ts b/ui/src/controller/flamegraph_controller.ts
index b1c00a4..22365ad 100644
--- a/ui/src/controller/flamegraph_controller.ts
+++ b/ui/src/controller/flamegraph_controller.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {Duration, Time, time} from '../base/time';
+import {Duration, time} from '../base/time';
import {exists} from '../base/utils';
import {Actions} from '../common/actions';
import {
@@ -25,8 +25,8 @@
CallsiteInfo,
FlamegraphState,
FlamegraphStateViewingOption,
- ProfileType,
isHeapGraphDominatorTreeViewingOption,
+ ProfileType,
} from '../common/state';
import {FlamegraphDetails, globals} from '../frontend/globals';
import {publishFlamegraphDetails} from '../frontend/publish';
@@ -116,10 +116,6 @@
private flamegraphDetails: FlamegraphDetails = {};
private areaSelectionHandler: AreaSelectionHandler;
private cache: TablesCache;
- private heapGraphSelected: {upid: number; timestamp: time} = {
- upid: -1,
- timestamp: Time.INVALID,
- };
constructor(private args: FlamegraphControllerArgs) {
super('main');
@@ -215,9 +211,8 @@
const flamegraphData = await this.getFlamegraphData(
key,
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
- selectedFlamegraphState.viewingOption
- ? /* eslint-enable */
- selectedFlamegraphState.viewingOption
+ selectedFlamegraphState.viewingOption /* eslint-enable */
+ ? selectedFlamegraphState.viewingOption
: defaultViewingOption(selectedFlamegraphState.type),
selection.start,
selection.end,
@@ -540,22 +535,14 @@
}
private async loadHeapGraphDominatorTreeQuery(upid: number, timestamp: time) {
- const selectTreeQuery = `
- -- cache invalidate: upid ${upid}, ts ${timestamp}
- SELECT * FROM heap_graph_type_dominated`;
- if (
- this.heapGraphSelected.upid === upid &&
- this.heapGraphSelected.timestamp === timestamp
- ) {
- return selectTreeQuery;
- }
- this.heapGraphSelected = {upid, timestamp};
+ const outputTableName = `heap_graph_type_dominated_${upid}_${timestamp}`;
+
this.args.engine.query(`
INCLUDE PERFETTO MODULE memory.heap_graph_dominator_tree;
-- heap graph dominator tree with objects as nodes and all relavant
-- object self stats and dominated stats
- CREATE PERFETTO TABLE heap_graph_object_dominated AS
+ CREATE PERFETTO TABLE _heap_graph_object_dominated AS
SELECT
node.id,
node.idom_id,
@@ -574,21 +561,19 @@
-- calculate for each object node in the dominator tree the
-- HASH(path of type_id's from the super root to the object)
CREATE PERFETTO TABLE _dominator_tree_path_hash AS
- WITH RECURSIVE _tree_visitor(id, path, path_hash) AS (
+ WITH RECURSIVE _tree_visitor(id, path_hash) AS (
SELECT
id,
- CAST(type_id AS text) || '-' || IFNULL(root_type, '') AS path,
HASH(
- CAST(type_id AS text) || '-' || IFNULL(root_type, '')
+ CAST(type_id AS TEXT) || '-' || IFNULL(root_type, '')
) AS path_hash
- FROM heap_graph_object_dominated
+ FROM _heap_graph_object_dominated
WHERE depth = 1
UNION ALL
SELECT
child.id,
- parent.path || '/' || CAST(type_id AS text) AS path,
- HASH(parent.path || '/' || CAST(type_id AS text)) AS path_hash
- FROM heap_graph_object_dominated child
+ HASH(CAST(parent.path_hash AS TEXT) || '/' || CAST(type_id AS TEXT)) AS path_hash
+ FROM _heap_graph_object_dominated child
JOIN _tree_visitor parent ON child.idom_id = parent.id
)
SELECT * from _tree_visitor
@@ -597,7 +582,7 @@
-- merge object nodes with the same path into one "class type node", so the
-- end result is a tree where nodes are identified by their types and the
-- dominator relationships are preserved.
- CREATE PERFETTO TABLE heap_graph_type_dominated AS
+ CREATE PERFETTO TABLE ${outputTableName} AS
SELECT
map.path_hash as id,
COALESCE(cls.deobfuscated_name, cls.name, '[NULL]') || IIF(
@@ -615,13 +600,18 @@
-1 as line_number,
sum(self_size) AS size,
count(*) AS count
- FROM heap_graph_object_dominated node
+ FROM _heap_graph_object_dominated node
JOIN _dominator_tree_path_hash map USING(id)
LEFT JOIN _dominator_tree_path_hash parent_map ON node.idom_id = parent_map.id
JOIN heap_graph_class cls ON node.type_id = cls.id
- GROUP BY map.path_hash, name, parent_id, depth, map_name, source_file, line_number;`);
+ GROUP BY map.path_hash, name, parent_id, depth, map_name, source_file, line_number;
- return selectTreeQuery;
+ -- These are intermediates and not needed
+ DROP TABLE _heap_graph_object_dominated;
+ DROP TABLE _dominator_tree_path_hash;
+ `);
+
+ return `SELECT * FROM ${outputTableName}`;
}
getMinSizeDisplayed(