1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import {BaseElement, element} from "../../../../base-ui/BaseElement.js"; 17import {LitTable} from "../../../../base-ui/table/lit-table.js"; 18import {SelectionParam} from "../../../bean/BoxSelection.js"; 19import { 20 getTabStatesGroupByState, 21 getTabStatesGroupByStatePid, 22 getTabStatesGroupByStatePidTid 23} from "../../../database/SqlLite.js"; 24import {StateProcessThread} from "../../../bean/StateProcessThread.js"; 25import {Utils} from "../base/Utils.js"; 26 27@element('tabpane-thread-switch') 28export class TabPaneThreadSwitch extends BaseElement { 29 private tbl: LitTable | null | undefined; 30 private range: HTMLLabelElement | null | undefined; 31 32 set data(val: SelectionParam | any) { 33 this.range!.textContent = "Selected range: " + parseFloat(((val.rightNs - val.leftNs) / 1000000.0).toFixed(5)) + " ms" 34 Promise.all([ 35 getTabStatesGroupByState(val.leftNs, val.rightNs), 36 getTabStatesGroupByStatePid(val.leftNs, val.rightNs), 37 getTabStatesGroupByStatePidTid(val.leftNs, val.rightNs)]).then((values) => { 38 let states = values[0]; 39 states.map((spt) => { 40 spt.id = (spt.state == "R+" ? "RP" : spt.state) 41 // @ts-ignore 42 spt.title = Utils.getEndState(spt.state); 43 }); 44 let processMap = this.groupByStateToMap(values[1]); 45 let threadMap = this.groupByStateProcessToMap(values[2]); 46 for (let state of states) { 47 let processes = processMap.get(state.state); 48 processes!.map((spt) => { 49 spt.id = (spt.state == "R+" ? "RP" : spt.state) + "_" + spt.processId; 50 spt.pid = (spt.state == "R+" ? "RP" : spt.state); 51 spt.title = (spt.process ?? "Process") + "(" + spt.processId + ")" 52 }) 53 state.children = processes ?? []; 54 let map = threadMap.get(state.state); 55 for (let process of processes!) { 56 let threads = map!.get(process.processId); 57 threads!.map((spt) => { 58 spt.id = (spt.state == "R+" ? "RP" : spt.state) + "_" + spt.processId + "_" + spt.threadId 59 spt.pid = (spt.state == "R+" ? "RP" : spt.state) + "_" + spt.processId 60 spt.title = (spt.thread ?? "Thread") + "(" + spt.threadId + ")" 61 }) 62 process.children = threads ?? []; 63 } 64 } 65 this.tbl!.dataSource = states; 66 }) 67 } 68 69 initElements(): void { 70 this.tbl = this.shadowRoot?.querySelector<LitTable>('#tb-ts'); 71 this.range = this.shadowRoot?.querySelector('#time-range') 72 } 73 74 groupByStateToMap(arr: Array<StateProcessThread>): Map<string, Array<StateProcessThread>> { 75 let map = new Map<string, Array<StateProcessThread>>(); 76 for (let spt of arr) { 77 if (map.has(spt.state)) { 78 map.get(spt.state)!.push(spt); 79 } else { 80 let list: Array<StateProcessThread> = []; 81 list.push(spt); 82 map.set(spt.state, list); 83 } 84 } 85 return map; 86 } 87 88 groupByProcessToMap(arr: Array<StateProcessThread>): Map<number, Array<StateProcessThread>> { 89 let map = new Map<number, Array<StateProcessThread>>(); 90 for (let spt of arr) { 91 if (map.has(spt.processId)) { 92 map.get(spt.processId)!.push(spt); 93 } else { 94 let list: Array<StateProcessThread> = []; 95 list.push(spt); 96 map.set(spt.processId, list); 97 } 98 } 99 return map; 100 } 101 102 groupByStateProcessToMap(arr: Array<StateProcessThread>): Map<string, Map<number, Array<StateProcessThread>>> { 103 let map = new Map<string, Map<number, Array<StateProcessThread>>>(); 104 let stateMap = this.groupByStateToMap(arr); 105 for (let key of stateMap.keys()) { 106 let processMap = this.groupByProcessToMap(stateMap.get(key)!) 107 map.set(key, processMap); 108 } 109 return map; 110 } 111 112 initHtml(): string { 113 return ` 114<style> 115:host{ 116 display: flex; 117 flex-direction: column; 118 padding: 10px 10px; 119} 120</style> 121<label id="time-range" style="width: 100%;height: 20px;text-align: end;font-size: 10pt;margin-bottom: 5px">Selected range:0.0 ms</label> 122<lit-table id="tb-ts" style="height: auto" tree> 123 <lit-table-column width="500px" title="Event/Process/Thread" data-index="title" key="title" align="flex-start"></lit-table-column> 124 <lit-table-column width="1fr" title="Count" data-index="count" key="count" align="flex-start" ></lit-table-column> 125</lit-table> 126 `; 127 } 128 129}