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 17import {Computation} from 'trace/tree_node/computation'; 18import {HierarchyTreeNode} from 'trace/tree_node/hierarchy_tree_node'; 19import {PropertiesProvider} from 'trace/tree_node/properties_provider'; 20 21export abstract class HierarchyTreeBuilder { 22 protected root: PropertiesProvider | undefined; 23 protected children: PropertiesProvider[] | undefined; 24 private computations: Computation[] = []; 25 26 setRoot(value: PropertiesProvider): this { 27 this.root = value; 28 return this; 29 } 30 31 setChildren(value: PropertiesProvider[]): this { 32 this.children = value; 33 return this; 34 } 35 36 setComputations(value: Computation[]): this { 37 this.computations = value; 38 return this; 39 } 40 41 build(): HierarchyTreeNode { 42 if (!this.root) { 43 throw Error('root not set'); 44 } 45 46 if (!this.children) { 47 throw Error('children not set'); 48 } 49 50 const identifierToChildren = this.buildIdentifierToChildrenMap( 51 this.children, 52 ); 53 54 const root = this.buildHierarchyTree(this.root, identifierToChildren); 55 56 this.computations.forEach((computation) => 57 computation.setRoot(root).executeInPlace(), 58 ); 59 60 return root; 61 } 62 63 private buildHierarchyTree( 64 root: PropertiesProvider, 65 identifierToChildren: Map<string | number, readonly HierarchyTreeNode[]>, 66 ): HierarchyTreeNode { 67 const rootProperties = root.getEagerProperties(); 68 const node = this.makeNode(rootProperties.id, rootProperties.name, root); 69 this.assignParentChildRelationships(node, identifierToChildren, true); 70 return node; 71 } 72 73 protected makeNode( 74 id: string, 75 name: string, 76 propertiesProvider: PropertiesProvider, 77 ): HierarchyTreeNode { 78 return new HierarchyTreeNode(id, name, propertiesProvider); 79 } 80 81 protected setParentChildRelationship( 82 parent: HierarchyTreeNode, 83 child: HierarchyTreeNode, 84 ) { 85 parent.addOrReplaceChild(child); 86 child.setParent(parent); 87 } 88 89 protected abstract buildIdentifierToChildrenMap( 90 nodes: PropertiesProvider[], 91 ): Map<string | number, readonly HierarchyTreeNode[]>; 92 93 protected abstract assignParentChildRelationships( 94 node: HierarchyTreeNode, 95 identifierToChildren: Map<string | number, readonly HierarchyTreeNode[]>, 96 isRoot?: boolean, 97 ): void; 98} 99