/* * Copyright (C) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { BaseElement, element } from '../../../../../base-ui/BaseElement'; import { LitTable } from '../../../../../base-ui/table/lit-table'; import { Counter, SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; import { resizeObserver } from '../SheetUtils'; import { getTabCounters } from '../../../../database/sql/Cpu.sql'; @element('tabpane-counter') export class TabPaneCounter extends BaseElement { private counterTbl: LitTable | null | undefined; private counterRange: HTMLLabelElement | null | undefined; private counterSource: Array = []; private currentSelectionParam: SelectionParam | undefined; set data(counterParam: SelectionParam | unknown) { if (this.currentSelectionParam === counterParam) { return; } // @ts-ignore this.currentSelectionParam = counterParam; //@ts-ignore this.counterTbl?.shadowRoot?.querySelector('.table')?.style?.height = `${this.parentElement!.clientHeight - 45}px`; this.counterRange!.textContent = `Selected range: ${parseFloat( // @ts-ignore ((counterParam.rightNs - counterParam.leftNs) / 1000000.0).toFixed(5) )} ms`; this.counterTbl!.loading = true; // @ts-ignore getTabCounters(counterParam.processTrackIds, counterParam.virtualTrackIds, counterParam.rightNs).then((result) => { this.counterTbl!.loading = false; //@ts-ignore if (result !== null && result.length > 0) { let dataSource: Array = []; //@ts-ignore let collect = this.groupByTrackIdToMap(result); let sumCount = 0; for (let key of collect.keys()) { let counters = collect.get(key); let list: Array = []; // @ts-ignore let index = counters!.findIndex((item) => item.startTime >= counterParam.leftNs); if (index !== -1) { list = counters!.splice(index > 0 ? index - 1 : index); } else { list.push(counters![counters!.length - 1]); } // @ts-ignore let sd = this.createSelectCounterData(list, counterParam.leftNs, counterParam.rightNs); sumCount += Number.parseInt(sd.count); dataSource.push(sd); } let sumData = new SelectionData(); sumData.count = sumCount.toString(); sumData.process = ' '; dataSource.splice(0, 0, sumData); this.counterSource = dataSource; this.counterTbl!.recycleDataSource = dataSource; } else { this.counterSource = []; this.counterTbl!.recycleDataSource = this.counterSource; } }); } initElements(): void { this.counterTbl = this.shadowRoot?.querySelector('#tb-counter'); this.counterRange = this.shadowRoot?.querySelector('#time-range'); this.counterTbl!.addEventListener('column-click', (evt) => { // @ts-ignore this.sortByColumn(evt.detail); }); } connectedCallback(): void { super.connectedCallback(); resizeObserver(this.parentElement!, this.counterTbl!); } initHtml(): string { return ` `; } groupByTrackIdToMap(arr: Array): Map> { let map = new Map>(); for (let counter of arr) { counter.name = counter.name.replace('sys.virtual.mem.', ''); if (map.has(counter.trackId)) { map.get(counter.trackId)!.push(counter); } else { let list: Array = []; list.push(counter); map.set(counter.trackId, list); } } return map; } createSelectCounterData(list: Array, leftNs: number, rightNs: number): SelectionData { let counterData = new SelectionData(); if (list.length > 0) { let range = rightNs - leftNs; let first = list[0]; counterData.trackId = first.trackId; counterData.name = first.name; counterData.first = `${first.value}`; counterData.count = `${list.length}`; counterData.last = `${list[list.length - 1].value}`; counterData.delta = `${parseInt(counterData.last) - parseInt(counterData.first)}`; counterData.rate = (parseInt(counterData.delta) / ((range * 1.0) / 1000000000)).toFixed(4); counterData.min = `${first.value}`; counterData.max = '0'; let weightAvg = 0.0; for (let i = 0; i < list.length; i++) { let counter = list[i]; if (counter.value < parseInt(counterData.min)) { counterData.min = counter.value.toString(); } if (counter.value > parseInt(counterData.max)) { counterData.max = counter.value.toString(); } let start = i === 0 ? leftNs : counter.startTime; let end = i === list.length - 1 ? rightNs : list[i + 1].startTime; weightAvg += counter.value * (((end - start) * 1.0) / range); } counterData.avgWeight = weightAvg.toFixed(2); } return counterData; } sortByColumn(detail: unknown): void { // @ts-ignore function compare(property, sort, type) { return function (counterLeftData: SelectionData, counterRightData: SelectionData) { if (counterLeftData.process === ' ' || counterRightData.process === ' ') { return 0; } if (type === 'number') { return sort === 2 // @ts-ignore ? parseFloat(counterRightData[property]) - parseFloat(counterLeftData[property]) // @ts-ignore : parseFloat(counterLeftData[property]) - parseFloat(counterRightData[property]); } else { // @ts-ignore if (counterRightData[property] > counterLeftData[property]) { return sort === 2 ? 1 : -1; } else { // @ts-ignore if (counterRightData[property] === counterLeftData[property]) { return 0; } else { return sort === 2 ? -1 : 1; } } } }; } // @ts-ignore if (detail.key === 'name') { // @ts-ignore this.counterSource.sort(compare(detail.key, detail.sort, 'string')); } else { // @ts-ignore this.counterSource.sort(compare(detail.key, detail.sort, 'number')); } this.counterTbl!.recycleDataSource = this.counterSource; } }