diff --git a/ide/src/base-ui/menu/LitMainMenu.ts b/ide/src/base-ui/menu/LitMainMenu.ts index de1dac4fcc7a2aa781e960a0b521827ae924c60b..19d7aa5e12ac2191ab53b8503d67675b4827d969 100644 --- a/ide/src/base-ui/menu/LitMainMenu.ts +++ b/ide/src/base-ui/menu/LitMainMenu.ts @@ -54,87 +54,37 @@ export class LitMainMenu extends BaseElement { let groupDescribe = group!.shadowRoot!.querySelector('.group-describe') as LitMainMenuGroup; menuBody?.appendChild(group); it.children?.forEach((item: any) => { - if (item.children && item.children.length > 0) { - let secondGroup = new LitMainMenuGroup(); - secondGroup.setAttribute('title', item.title || ''); - secondGroup.setAttribute('describe', item.describe || ''); - if (item.second) { - secondGroup.setAttribute('second', ''); - } else { - secondGroup.removeAttribute('second') - } - if (item.collapsed) { - secondGroup.setAttribute('collapsed', '') - } else { - secondGroup.removeAttribute('collapsed') - } - group?.appendChild(secondGroup) - item.children?.forEach((v: any) => { - let th = new LitMainMenuItem(); - th.setAttribute('icon', v.icon || ''); - th.setAttribute('title', v.title || '');if (this.getAttribute('main_menu') === '1' && window.localStorage.getItem('Theme') === 'dark') { - groupName.style.color = 'white'; - groupDescribe.style.color = 'white'; - th!.style.color = 'white'; - } else { - groupName.style.color = 'black'; - groupDescribe.style.color = 'black'; - th!.style.color = 'black'; - } - if (v.fileChoose) { - th.setAttribute('file', ''); - th.addEventListener('file-change', (e) => { - if (v.fileHandler && !th.disabled) { - v.fileHandler(e); - } - }); - } else { - th.removeAttribute('file'); - th.addEventListener('click', (e) => { - if (v.clickHandler && !th.disabled) { - v.clickHandler(v); - } - }); - } - if (v.disabled != undefined) { - th.disabled = v.disabled; + let th = new LitMainMenuItem(); + th.setAttribute('icon', item.icon || ''); + th.setAttribute('title', item.title || ''); + if (this.getAttribute('main_menu') === '1' && window.localStorage.getItem('Theme') === 'dark') { + groupName.style.color = 'white'; + groupDescribe.style.color = 'white'; + th!.style.color = 'white'; + } else { + groupName.style.color = 'black'; + groupDescribe.style.color = 'black'; + th!.style.color = 'black'; + } + if (item.fileChoose) { + th.setAttribute('file', ''); + th.addEventListener('file-change', (e) => { + if (item.fileHandler && !th.disabled) { + item.fileHandler(e); } - secondGroup.appendChild(th) - }) + }); } else { - let th = new LitMainMenuItem(); - th.setAttribute('icon', item.icon || ''); - th.setAttribute('title', item.title || ''); - if (this.getAttribute('main_menu') === '1' && window.localStorage.getItem('Theme') === 'dark') { - groupName.style.color = 'white'; - groupDescribe.style.color = 'white'; - th!.style.color = 'white'; - } else { - groupName.style.color = 'black'; - groupDescribe.style.color = 'black'; - th!.style.color = 'black'; - } - if (item.fileChoose) { - th.setAttribute('file', ''); - th.addEventListener('file-change', (e) => { - if (item.fileHandler && !th.disabled) { - item.fileHandler(e); - } - }); - } else { - th.removeAttribute('file'); - th.addEventListener('click', (e) => { - if (item.clickHandler && !th.disabled) { - item.clickHandler(item); - } - }); - } - if (item.disabled != undefined) { - th.disabled = item.disabled; - } - group?.appendChild(th); + th.removeAttribute('file'); + th.addEventListener('click', (e) => { + if (item.clickHandler && !th.disabled) { + item.clickHandler(item); + } + }); } - + if (item.disabled != undefined) { + th.disabled = item.disabled; + } + group?.appendChild(th); }); }); } @@ -144,7 +94,7 @@ export class LitMainMenu extends BaseElement { st?.addEventListener('slotchange', (e) => { this.slotElements = st?.assignedElements(); this.slotElements?.forEach((it) => { - it.querySelectorAll('lit-main-menu-item').forEach((cell) => { }); + it.querySelectorAll('lit-main-menu-item').forEach((cell) => {}); }); }); let versionDiv: HTMLElement | null | undefined = this.shadowRoot?.querySelector('.version'); @@ -242,9 +192,8 @@ export class LitMainMenu extends BaseElement { export interface MenuGroup { title: string; describe: string; - second: boolean; collapsed: boolean; - children: any; + children: Array; } export interface MenuItem { diff --git a/ide/src/base-ui/menu/LitMainMenuGroup.ts b/ide/src/base-ui/menu/LitMainMenuGroup.ts index e7491ab109097ceb9359b6741c7fa014a6251b6c..884fad542a26d94288d19262a1f0dee302e8c7e0 100644 --- a/ide/src/base-ui/menu/LitMainMenuGroup.ts +++ b/ide/src/base-ui/menu/LitMainMenuGroup.ts @@ -23,7 +23,7 @@ export class LitMainMenuGroup extends BaseElement { private group: HTMLElement | null | undefined; static get observedAttributes() { - return ['title', 'describe', 'collapsed', 'nocollapse', 'radius','second']; + return ['title', 'describe', 'collapsed', 'nocollapse', 'radius']; } get collapsed(): boolean { @@ -38,18 +38,6 @@ export class LitMainMenuGroup extends BaseElement { } } - get second(){ - return this.hasAttribute('second'); - } - - set second(value:boolean){ - if (value) { - this.setAttribute('second', ''); - } else { - this.removeAttribute('second'); - } - } - get nocollapsed() { return this.hasAttribute('nocollapsed'); } @@ -92,15 +80,9 @@ export class LitMainMenuGroup extends BaseElement { user-select: none; transition: background-color .3s; } - :host(:not([collapsed])),:host(:not([second])) ::slotted(lit-main-menu-item){ + :host(:not([collapsed])) ::slotted(lit-main-menu-item){ display: flex; } - host(:not([collapsed])) :host([second]) ::slotted(lit-main-menu-group){ - display:flex; - } - :host([second]) .group-name{ - padding-left:40px; - } :host(:not([collapsed])) .group-describe{ height: 0; visibility: hidden; @@ -125,9 +107,6 @@ export class LitMainMenuGroup extends BaseElement { :host([collapsed]) ::slotted(lit-main-menu-item){ display: none; } - :host([collapsed]) ::slotted(lit-main-menu-group){ - display:none; - } .group-name{ font-size: 14px; font-family: Helvetica; diff --git a/ide/src/trace/SpApplication.ts b/ide/src/trace/SpApplication.ts index 862742f60e65c10f21a88c88253ee088f7e60fe9..e268dadef7aa1da48b2db8613f598fe26a9541f6 100644 --- a/ide/src/trace/SpApplication.ts +++ b/ide/src/trace/SpApplication.ts @@ -1061,7 +1061,6 @@ export class SpApplication extends BaseElement { mainMenu.menus!.splice(1, mainMenu.menus!.length > 2 ? 1 : 0, { collapsed: false, title: 'Current Trace', - second:false, describe: 'Actions on the current trace', children: getTraceOptionMenus(showFileName, fileSize, fileName, true, dbName), }); @@ -1408,7 +1407,6 @@ export class SpApplication extends BaseElement { mainMenu.menus!.splice(2, 1, { collapsed: false, title: 'Convert trace', - second:false, describe: 'Convert to other formats', children: pushConvertTrace(fileName), }); @@ -1417,7 +1415,6 @@ export class SpApplication extends BaseElement { mainMenu.menus!.splice(index, 1, { collapsed: false, title: 'Support', - second:false, describe: 'Support', children: [ { @@ -1452,7 +1449,6 @@ export class SpApplication extends BaseElement { mainMenu.menus!.splice(1, mainMenu.menus!.length > 2 ? 1 : 0, { collapsed: false, title: 'Current Trace', - second:false, describe: 'Actions on the current trace', children: getTraceOptionMenus(showFileName, fileSize, fileName, false), }); @@ -1747,7 +1743,6 @@ export class SpApplication extends BaseElement { mainMenu.menus!.splice(1, mainMenu.menus!.length > 2 ? 1 : 0, { collapsed: false, title: 'Current Trace', - second:false, describe: 'Actions on the current trace', children: getTraceOptionMenus(showFileName, fileSize, fileName, false), }); @@ -1773,7 +1768,6 @@ export class SpApplication extends BaseElement { { collapsed: false, title: 'Navigation', - second:false, describe: 'Open or record a new trace', children: [ { @@ -1832,7 +1826,6 @@ export class SpApplication extends BaseElement { { collapsed: false, title: 'Support', - second:false, describe: 'Support', children: [ { diff --git a/ide/src/trace/component/SpHelp.ts b/ide/src/trace/component/SpHelp.ts index 6dbfb20550d3b0a77a01faacc1e9177f2bdbdd9c..c87c806a568ec748a92cae53df3f8bad5b2b7ad4 100644 --- a/ide/src/trace/component/SpHelp.ts +++ b/ide/src/trace/component/SpHelp.ts @@ -54,7 +54,6 @@ export class SpHelp extends BaseElement { { collapsed: false, title: 'QuickStart', - second: false, describe: '', children: [ { @@ -387,7 +386,6 @@ export class SpHelp extends BaseElement { { collapsed: false, title: 'TraceStreamer', - second: false, describe: '', children: [ { @@ -462,7 +460,6 @@ export class SpHelp extends BaseElement { { collapsed: false, title: 'SmartPerf', - second: false, describe: '', children: [ { diff --git a/ide/src/trace/component/SpRecordTrace.ts b/ide/src/trace/component/SpRecordTrace.ts index 039518716fb0cd9a5bb9aa569dfb4e2866ecbdab..f8794aa04bd1cf07473e37be7a39f77121675b2a 100644 --- a/ide/src/trace/component/SpRecordTrace.ts +++ b/ide/src/trace/component/SpRecordTrace.ts @@ -528,7 +528,7 @@ export class SpRecordTrace extends BaseElement { freshMenuDisable(disable: boolean): void { let mainMenu = this.sp!.shadowRoot?.querySelector('#main-menu') as LitMainMenu; mainMenu.menus?.forEach((men) => { - men.children.forEach((child:any) => { + men.children.forEach((child) => { // @ts-ignore child.disabled = disable; }); diff --git a/ide/src/trace/component/SpSystemTrace.ts b/ide/src/trace/component/SpSystemTrace.ts index 5723b050cc32ae133496cb86ca786ed66ee7faf3..2d26d5cbdbec745bc401991dc8343876e2fbcae0 100644 --- a/ide/src/trace/component/SpSystemTrace.ts +++ b/ide/src/trace/component/SpSystemTrace.ts @@ -23,16 +23,7 @@ import { querySceneSearchFunc, querySearchFunc, threadPool, - queryProcessMemData, - queryProcess, - queryProcessByTable, - queryProcessThreads, - queryProcessThreadsByTable, - getFunDataByTid, - queryProcessMem, } from '../database/SqlLite.js'; -import { MemRender,ProcessMemStruct } from '../database/ui-worker/ProcedureWorkerMem.js'; -import { renders } from '../database/ui-worker/ProcedureWorker.js'; import { RangeSelectStruct, TraceRow } from './trace/base/TraceRow.js'; import { TimerShaftElement } from './trace/TimerShaftElement.js'; import './trace/base/TraceSheet.js'; @@ -54,7 +45,6 @@ import { drawWakeUp, drawWakeUpList, isFrameContainPoint, - drawVsync, LineType, ns2x, ns2xByTimeShaft, @@ -67,7 +57,7 @@ import { ProcessStruct } from '../database/ui-worker/ProcedureWorkerProcess.js'; import { CpuFreqStruct } from '../database/ui-worker/ProcedureWorkerFreq.js'; import { CpuFreqLimitsStruct } from '../database/ui-worker/ProcedureWorkerCpuFreqLimits.js'; import { ThreadStruct } from '../database/ui-worker/ProcedureWorkerThread.js'; -import { func, FuncStruct,FuncRender } from '../database/ui-worker/ProcedureWorkerFunc.js'; +import { func, FuncStruct } from '../database/ui-worker/ProcedureWorkerFunc.js'; import { CpuStateStruct } from '../database/ui-worker/ProcedureWorkerCpuState.js'; import { HiPerfCpuStruct } from '../database/ui-worker/ProcedureWorkerHiPerfCPU.js'; import { HiPerfProcessStruct } from '../database/ui-worker/ProcedureWorkerHiPerfProcess.js'; @@ -205,15 +195,7 @@ export class SpSystemTrace extends BaseElement { private expandRowList: Array> = []; private _slicesList: Array = []; private _flagList: Array = []; - private _frameList: Array = []; - private _isVsync: boolean = false; - private processes: Array =[]; - private processFromTable: Array =[]; - private queryProcessThreadResult: Array=[]; - private queryProcessThreadsByTableResult: Array=[]; - private queryFunData: Array =[]; - private querydbData : Array=[]; - private dbProcessMen: Array=[]; + set snapshotFile(data: FileInfo) { this.snapshotFiles = data; } @@ -242,164 +224,6 @@ export class SpSystemTrace extends BaseElement { this.linkNodes.push([startPoint, endPoint]); } - async makeVsyncLine(){ - if(this._isVsync){ - let vsyncPid: number = 0;//单框架进程Id - let vsyncUPid: number = 0;//单框架 - let vsyncTid: number = 0;//单框架 - let vsyncDbPid : number = 0;//双框架进程Id - let context = this.canvasPanelCtx!; - this.processes = this.processes.length>0? this.processes:await queryProcess(); - this.processFromTable = this.processFromTable.length>0?this.processFromTable:await queryProcessByTable(); - this.queryProcessThreadResult = this.queryProcessThreadResult.length>0?this.queryProcessThreadResult:await queryProcessThreads(); - this.queryProcessThreadsByTableResult = this.queryProcessThreadsByTableResult.length>0?this.queryProcessThreadsByTableResult:await queryProcessThreadsByTable(); - let processList = Utils.removeDuplicates(this.processes,this.processFromTable,'pid'); - info('ProcessList Data size is: ', processList!.length); - let processThreads = Utils.removeDuplicates(this.queryProcessThreadResult,this.queryProcessThreadsByTableResult,'tid'); - info('The amount of initialized process threads data is : ', processThreads!.length); - processList.forEach((ele:any)=>{ - if(ele.processName === 'render_service'){//单框架 - vsyncPid = Number(`${ele.pid}`) - }else if(ele.processName === 'surfaceflinger'){ - vsyncDbPid = Number(`${ele.pid}`) - } - }) - if(vsyncPid){ - let vsyncThreads = processThreads.filter((thread:any)=>thread.pid == vsyncPid && thread.tid !=0); - vsyncThreads.forEach((ele:any)=>{ - if(ele.threadName == 'VSyncGenerator'){ - vsyncTid = Number(`${ele.tid}`); - vsyncUPid = Number(`${ele.upid}`); - } - }) - let funcRow = TraceRow.skeleton(); - this.queryFunData = this.queryFunData.length>0?this.queryFunData:await getFunDataByTid(vsyncTid || 0,vsyncUPid || 0); - if(this.queryFunData.length >0){ - for(let i =0;i { - return ( - data.funName != null && - (data.funName.toLowerCase().startsWith('binder transaction async') || //binder transaction - data.funName.toLowerCase().startsWith('binder async') || - data.funName.toLowerCase().startsWith('binder reply')) - ); - }; - this.queryFunData.forEach((fun) => { - if (isBinder(fun)) { - } else { - if (fun.dur === -1) { - fun.dur = (TraceRow.range?.totalNS || 0) - (fun.startTs || 0); - fun.flag = 'Did not end'; - } - } - }); - funcRow.dataList = []; - funcRow.dataList.push(...this.queryFunData); - (renders.func as FuncRender).renderMainThread( - { - context:context, - useCache:false, - type:`fun${vsyncTid}VSyncGenerator` - }, - funcRow - ); - if(funcRow.dataListCache.length > 0){ - let drawVsData = []; - let dataStart:any={}; - let dataEnd: any={}; - let drawLineList = []; - if(funcRow.dataListCache[0]!.color! == '#fff'){ - dataStart = { - color: '#808080', - frame:{ - x:0,y:0,width:1,height:20 - } - } - }else{ - dataStart = { - color: '#fff', - frame:{ - x:0,y:0,width:1,height:20 - } - } - } - if(funcRow.dataListCache[funcRow.dataListCache.length-1]!.color! == '#fff'){ - dataEnd = { - color: '#808080', - frame:{ - x:this.canvasPanel!.clientWidth,y:0,width:1,height:20 - } - } - }else{ - dataEnd = { - color: '#fff', - frame:{ - x:this.canvasPanel!.clientWidth,y:0,width:1,height:20 - } - } - } - drawVsData.push(dataStart); - drawVsData.push(...funcRow.dataListCache); - drawVsData.push(dataEnd); - for(let i = 0;i(); - this.dbProcessMen = this.dbProcessMen.length>0?this.dbProcessMen:await queryProcessMem(); - let vsyncDbThreads = this.dbProcessMen.filter((thread:any)=> thread.pid == vsyncDbPid && thread.tid != 0); - vsyncDbThreads.forEach(async(ele:any)=>{ - if(ele.trackName == 'VSYNC-app'){ - this.querydbData = this.querydbData.length>0?this.querydbData:await queryProcessMemData(ele.trackId); - dbRow.dataList = []; - dbRow.dataList.push(...this.querydbData); - let context = this.canvasPanelCtx!; - (renders['mem'] as MemRender).renderMainThread( - { - context:context, - useCache:false, - type:`mem ${ele.trackId} VSYNC-app` - }, - dbRow - ); - let value_1_list = []; - let value_0_list = []; - let drawList = []; - this._frameList = []; - for(let i =0; i 0){ - for(let i =0; i < this._frameList.length; i++){ - if(this._frameList[i].frame){ - drawVsync( - this.canvasPanelCtx, - TraceRow.range!.startNS, - TraceRow.range!.endNS, - TraceRow.range!.totalNS, - { - x:this._frameList[i].frame!.x!, - y:this._frameList[i].frame!.y!, - width:this._frameList[i].frame!.width!, - height:this.canvasPanel!.clientHeight! - } as Rect, - this._frameList[i]!.color! - ); - } - } - } - -//---------------------------新增代码结束-------------------------- - // Draw the connection curve if (this.linkNodes) { drawLinkLines( @@ -1984,11 +1780,6 @@ export class SpSystemTrace extends BaseElement { this.offsetMouse = 0; this.mouseCurrentPosition = 0; this.style.cursor = 'default'; - requestAnimationFrame(()=>{ - setTimeout(()=>{ - this.makeVsyncLine(); - },100) - }) return; } TraceRow.isUserInteraction = false; @@ -2078,11 +1869,6 @@ export class SpSystemTrace extends BaseElement { if (keyPressWASD) { this.keyPressMap.set(keyPress, true); this.hoverFlag = null; - requestAnimationFrame(()=>{ - setTimeout(()=>{ - this.makeVsyncLine(); - },100) - }) } this.timerShaftEL!.documentOnKeyPress(ev, this.currentSlicesTime); if (keyPress === 'f') { @@ -2218,22 +2004,8 @@ export class SpSystemTrace extends BaseElement { documentOnKeyUp = (ev: KeyboardEvent) => { if (!this.loadTraceCompleted) return; let keyPress = ev.key.toLocaleLowerCase(); - if(keyPress === 'v'){ - this._isVsync = !this._isVsync; - if(this._isVsync){ - this.makeVsyncLine(); - }else{ - this.refreshCanvas(true,'',[]) - } - - } if (keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd') { this.keyPressMap.set(keyPress, false); - requestAnimationFrame(()=>{ - setTimeout(()=>{ - this.makeVsyncLine(); - },100) - }) } TraceRow.isUserInteraction = false; this.observerScrollHeightEnable = false; @@ -3809,11 +3581,6 @@ export class SpSystemTrace extends BaseElement { (e) => { if (e.ctrlKey) { if (e.deltaY > 0) { - requestAnimationFrame(()=>{ - setTimeout(()=>{ - this.makeVsyncLine(); - },100) - }) e.preventDefault(); e.stopPropagation(); let eventS = new KeyboardEvent('keypress', { @@ -3827,11 +3594,6 @@ export class SpSystemTrace extends BaseElement { }, 200); } if (e.deltaY < 0) { - requestAnimationFrame(()=>{ - setTimeout(()=>{ - this.makeVsyncLine(); - },100) - }) e.preventDefault(); e.stopPropagation(); let eventW = new KeyboardEvent('keypress', { @@ -4498,15 +4260,6 @@ export class SpSystemTrace extends BaseElement { } init = async (param: { buf?: ArrayBuffer; url?: string }, wasmConfigUri: string, progress: Function) => { - this._frameList = []; - this.processes = []; - this.processFromTable = []; - this.queryProcessThreadResult = []; - this.queryProcessThreadsByTableResult = []; - this.queryFunData = []; - this.dbProcessMen = []; - this.querydbData = []; - this._isVsync = false; progress('Load database', 6); this.rowsPaneEL!.scroll({ top: 0, diff --git a/ide/src/trace/component/trace/TimerShaftElement.ts b/ide/src/trace/component/trace/TimerShaftElement.ts index 80c8c13c6ec6c9596f405457327c0aa927abf896..cc618b7c1b3ca019a74266d0eab1de82579755a9 100644 --- a/ide/src/trace/component/trace/TimerShaftElement.ts +++ b/ide/src/trace/component/trace/TimerShaftElement.ts @@ -27,21 +27,12 @@ import { type SpSystemTrace, CurrentSlicesTime } from '../SpSystemTrace.js'; import './timer-shaft/CollapseButton.js'; //随机生成十六位进制颜色 export function randomRgbColor() { - let r = Math.floor(Math.random() * 255); - let g = Math.floor(Math.random() * 255); - let b = Math.floor(Math.random() * 255); - if (r * 0.299 + g * 0.587 + b * 0.114 < 192) { - let r16 = r.toString(16).length === 1 - && r.toString(16) <= 'f' ? 0 + r.toString(16) : r.toString(16); - let g16 = g.toString(16).length === 1 - && g.toString(16) <= 'f' ? 0 + g.toString(16) : g.toString(16); - let b16 = b.toString(16).length === 1 - && b.toString(16) <= 'f' ? 0 + b.toString(16) : b.toString(16); - let color = '#' + r16 + g16 + b16; - return color; - } else { - randomRgbColor() + const letters = '0123456789ABCDEF'; + let color = '#'; + for (let index = 0; index < 6; index++) { + color += letters[Math.floor(Math.random() * 16)]; } + return color; } export function ns2s(ns: number): string { diff --git a/ide/src/trace/component/trace/base/TraceSheetConfig.ts b/ide/src/trace/component/trace/base/TraceSheetConfig.ts index ba7b9d8dbbcd12e3f05f1e1ba554e0d9a9aba098..7b2f793a28726fcf3274eec1a02243f7111461d3 100644 --- a/ide/src/trace/component/trace/base/TraceSheetConfig.ts +++ b/ide/src/trace/component/trace/base/TraceSheetConfig.ts @@ -631,11 +631,11 @@ export let tabConfig: any = { 'tabpane-frequsage': { title: 'Freq Usage', type: TabPaneFreqUsage, - require: (param: SelectionParam) => param.threadIds.length > 0, + require: (param: SelectionParam) => param.threadIds.length > 0 && param.threadIds.length < 2, }, 'tabpane-freqdatacut': { title: 'Freq DataCut', type: TabPaneFreqDataCut, - require: (param: SelectionParam) => param.threadIds.length > 0, + require: (param: SelectionParam) => param.threadIds.length > 0 && param.threadIds.length < 2, }, }; diff --git a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts index fef2afeebab98590ccadf38f8e055ee9aac504fe..4551fab84c4c6e9f8006c91a260506ff4ac1c268 100644 --- a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts +++ b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts @@ -14,13 +14,13 @@ */ import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table.js'; +import { LitTable } from '../../../../../base-ui/table/lit-table'; import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; import '../../../StackBar.js' import { getTabRunningPercent, querySearchFuncData, queryCpuFreqUsageData, queryCpuFreqFilterId } from '../../../../database/SqlLite.js'; import { Utils } from '../../base/Utils.js'; +import { log } from '../../../../../log/Log.js'; import { resizeObserver } from '../SheetUtils.js'; -import { SliceGroup } from '../../../../bean/StateProcessThread.js'; @element('tabpane-freqdatacut') export class TabPaneFreqDataCut extends BaseElement { @@ -28,10 +28,7 @@ export class TabPaneFreqDataCut extends BaseElement { private threadStatesTblSource: Array = []; private currentSelectionParam: SelectionParam | any; private threadStatesDIV: Element | null | undefined; - private initData: any = new Map(); - private processArr: any = new Array(); - private threadArr: any = new Array(); - private originData: any = new Array(); + private initData: Array = []; set data(threadStatesParam: SelectionParam | any) { if (this.currentSelectionParam === threadStatesParam) { @@ -40,52 +37,34 @@ export class TabPaneFreqDataCut extends BaseElement { this.currentSelectionParam = threadStatesParam; this.threadStatesTblSource = []; this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = true; - this.initData = new Map(); - this.originData = new Array(); let tableValue: any = this.threadStatesTbl; tableValue.value = []; let divRoot1: any = this.shadowRoot?.querySelector('#dataCutThreadId'); divRoot1.value = ''; let divRoot2: any = this.shadowRoot?.querySelector('#dataCutThreadFunc'); divRoot2.value = ''; - // 查询running状态线程数据 getTabRunningPercent(threadStatesParam.threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs).then((result) => { - // 查询cpu及id信息 queryCpuFreqFilterId().then(r => { - // 以键值对形式将cpu及id进行对应,后续会将频点数据与其对应cpu进行整合 let IdMap = new Map(); let queryId = new Array(); for (let i = 0; i < r.length; i++) { queryId.push(r[i].id); IdMap.set(r[i].id, r[i].cpu); } - // 通过id去查询频点数据 queryCpuFreqUsageData(queryId).then((res) => { if (result != null && result.length > 0) { + log('getTabRunningPercent result size : ' + result.length); let sum = 0; let dealArr = new Array(); for (let i of res) { dealArr.push({ 'startNS': i.startNS + threadStatesParam.recordStartNs, 'dur': i.dur, 'value': i.value, 'cpu': IdMap.get(i.filter_id) }); } - let needDeal = new Map(); - let cpuMap = new Map(); - let pidArr = new Array(); - let threadArr = new Array(); - // 整理进程级的数组信息 - let processArr:any = threadStatesParam.processIds.length > 1 ? [...new Set(threadStatesParam.processIds)] : threadStatesParam.processIds; - for (let i of processArr) { - pidArr.push({ 'process': Utils.PROCESS_MAP.get(i) == null ? 'Process ' + i : Utils.PROCESS_MAP.get(i) + ' ' + i, 'thread': Utils.PROCESS_MAP.get(i) == null ? 'Process ' + i : Utils.PROCESS_MAP.get(i) + ' ' + i, 'pid': i, 'tid': '', 'count': 0, 'cpu': '', 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array() }); - } - // 拷贝给私有属性,以便后续进行数据切割时免除整理进程层级数据 - this.processArr = JSON.parse(JSON.stringify(pidArr)); + let targetList = new Array(); + let cpuArr = new Array(); + let finalResultArr = new Array(); + finalResultArr.push({ 'thread': '', 'count': 0, 'cpu': '', 'freq': '', 'dur': 0, 'percent': '100.00', 'state': 'Running', children: new Array() }); for (let e of result) { - if (processArr.includes(e.pid) && e.state == 'Running') { - if (needDeal.get(e.pid + '_' + e.tid) == undefined) { - threadArr.push({ 'process': Utils.PROCESS_MAP.get(e.pid) == null ? 'Process ' + e.pid : Utils.PROCESS_MAP.get(e.pid) + ' ' + e.pid, 'thread': Utils.THREAD_MAP.get(e.tid) + ' ' + e.tid, 'pid': e.pid, 'tid': e.tid, 'count': 0, 'cpu': '', 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array() }); - needDeal.set(e.pid + '_' + e.tid, new Array()); - } - let arr = needDeal.get(e.pid + '_' + e.tid); + if (threadStatesParam.processIds.includes(e.pid) && e.state == 'Running') { let process = Utils.PROCESS_MAP.get(e.pid); let thread = Utils.THREAD_MAP.get(e.tid); e.process = process == null || process.length == 0 ? '[NULL]' : process; @@ -93,79 +72,99 @@ export class TabPaneFreqDataCut extends BaseElement { e.stateJX = e.state; e.state = Utils.getEndState(e.stateJX); sum += e.dur; - arr.push(e); + targetList.push(e); + if (!cpuArr.includes(e.cpu)) { + cpuArr.push(e.cpu); + finalResultArr[0].thread = finalResultArr[0].thread == '' ? e.tid + '_' + e.thread : finalResultArr[0].thread; + finalResultArr[0].children.push({ 'thread': e.tid + '_' + e.thread, 'count': 0, 'cpu': e.cpu, 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array() }); + } } } - // 拷贝给私有属性,以便后续进行数据切割时免除整理线程层级数据 - this.threadArr = JSON.parse(JSON.stringify(threadArr)); - // 整理running线程数据、cpu层级信息 - this.mergeFreqData(needDeal, cpuMap, dealArr, sum, threadStatesParam); - // 将频点数据放置到对应cpu层级下 - this.mergeCpuData(cpuMap, needDeal); - // 将cpu层级数据放置到线程分组下 - this.mergeThreadData(threadArr, cpuMap); - // 原始数据拷贝一份,后续切割后可以放置在对应的周期前以供查看 - this.originData = JSON.parse(JSON.stringify(threadArr)); - // 将线程层级数据放置到进程级分组下 - this.mergePidData(pidArr, threadArr); - this.threadClick(pidArr); - this.threadStatesTbl!.loading = false; - } else { - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; - } - }) - }); - }) - } - private threadClick(data: Array) { - let labels = this.threadStatesTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - if (labels) { - for (let i = 0; i < labels.length; i++) { - let label = labels[i].innerHTML; - labels[i].addEventListener('click', (e) => { - if (label.includes('Process') && i === 0) { - this.threadStatesTbl!.setStatus(data, false); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('Thread') && i === 1) { - for (let item of data) { - item.status = true; - if (item.children != undefined && item.children.length > 0) { - this.threadStatesTbl!.setStatus(item.children, false); + // 用来存放数据切割之前的汇总数据 + let resultList = new Array(); + // 通过循环获取每个running状态线程的相关信息,此处或许可以进行算法优化 + const tsMutiple = 1000000000; + for (let i = 0; i < targetList.length; i++) { + for (let j = 0; j < dealArr.length; j++) { + if (targetList[i].cpu == dealArr[j].cpu) { + if (targetList[i].ts > dealArr[j].startNS) { + if (targetList[i].ts < (dealArr[j].startNS + dealArr[j].dur)) { + if (targetList[i].dur < (dealArr[j].startNS + dealArr[j].dur - targetList[i].ts)) { + resultList.push({ 'thread': targetList[i].tid + '_' + targetList[i].thread, 'count': (dealArr[j].value * targetList[i].dur) / 1000, 'cpu': targetList[i].cpu, 'freq': dealArr[j].value, 'dur': targetList[i].dur, 'percent': targetList[i].dur / sum * 100, 'state': 'Running', 'ts': targetList[i].ts / tsMutiple }); + break; + } else { + resultList.push({ 'thread': targetList[i].tid + '_' + targetList[i].thread, 'count': (dealArr[j].value * (dealArr[j].startNS + dealArr[j].dur - targetList[i].ts)) / 1000, 'cpu': targetList[i].cpu, 'freq': dealArr[j].value, 'dur': (dealArr[j].startNS + dealArr[j].dur - targetList[i].ts), 'percent': (dealArr[j].startNS + dealArr[j].dur - targetList[i].ts) / sum * 100, 'state': 'Running', 'ts': targetList[i].ts / tsMutiple }); + } + } + } else { + if ((targetList[i].ts + targetList[i].dur) > dealArr[j].startNS) { + if ((targetList[i].dur + targetList[i].ts - dealArr[j].startNS) < dealArr[j].dur) { + resultList.push({ 'thread': targetList[i].tid + '_' + targetList[i].thread, 'count': (dealArr[j].value * (targetList[i].dur + targetList[i].ts - dealArr[j].startNS)) / 1000, 'cpu': targetList[i].cpu, 'freq': dealArr[j].value, 'dur': (targetList[i].dur + targetList[i].ts - dealArr[j].startNS), 'percent': (targetList[i].dur + targetList[i].ts - dealArr[j].startNS) / sum * 100, 'state': 'Running', 'ts': dealArr[j].startNS / tsMutiple }); + break; + } else { + resultList.push({ 'thread': targetList[i].tid + '_' + targetList[i].thread, 'count': (dealArr[j].value * dealArr[j].dur) / 1000, 'cpu': targetList[i].cpu, 'freq': dealArr[j].value, 'dur': dealArr[j].dur, 'percent': dealArr[j].dur / sum * 100, 'state': 'Running', 'ts': dealArr[j].startNS / tsMutiple }); + } + } else { + resultList.push({ 'thread': targetList[i].tid + '_' + targetList[i].thread, 'count': 0, 'cpu': targetList[i].cpu, 'freq': 'unknown', 'dur': targetList[i].dur, 'percent': targetList[i].dur / sum * 100, 'state': 'Running', 'ts': targetList[i].ts / tsMutiple }); + break; + } + } + } } } - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('Cycle') && i === 2) { - for (let item of data) { - item.status = true; - for (let value of item.children ? item.children : []) { - value.status = true; - if (value.children != undefined && value.children.length > 0) { - this.threadStatesTbl!.setStatus(value.children, false); + // 深拷贝,用来进行数据切割操作,避免数据污染 + this.initData = JSON.parse(JSON.stringify(resultList)); + //合并同一线程内,当运行所在cpu和频点相同时,dur及percent进行累加求和,或许可以进行算法优化 + for (let i = 0; i < resultList.length; i++) { + for (let j = i + 1; j < resultList.length; j++) { + if (resultList[i].cpu == resultList[j].cpu && resultList[i].freq == resultList[j].freq) { + resultList[i].dur += resultList[j].dur; + resultList[i].percent += resultList[j].percent; + resultList[i].count += resultList[j].count; + resultList.splice(j, 1); + j--; } } + resultList[i].percent = Number((resultList[i].percent).toFixed(2)); + resultList[i].ts = (resultList[i].ts * tsMutiple - threadStatesParam.recordStartNs) / tsMutiple; } - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('CPU') && i === 3) { - this.threadStatesTbl!.setStatus(data, true); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand); + finalResultArr[0].children.sort((a: any, b: any) => a.cpu - b.cpu); + // 转成树结构数据进行展示 + for (let i = 0; i < finalResultArr[0].children.length; i++) { + for (let j = 0; j < resultList.length; j++) { + if (finalResultArr[0].children[i].cpu == resultList[j].cpu) { + finalResultArr[0].children[i].children.push(resultList[j]); + finalResultArr[0].children[i].dur += resultList[j].dur; + finalResultArr[0].children[i].percent += resultList[j].percent; + finalResultArr[0].children[i].count += resultList[j].count; + resultList.splice(j, 1); + j--; + } + } + finalResultArr[0].children[i].percent = finalResultArr[0].children[i].percent.toFixed(2); + finalResultArr[0].dur += finalResultArr[0].children[i].dur; + finalResultArr[0].count += finalResultArr[0].children[i].count; + } + this.threadStatesTblSource = finalResultArr; + this.threadStatesTbl!.recycleDataSource = finalResultArr; + } else { + this.threadStatesTblSource = []; + this.threadStatesTbl!.recycleDataSource = []; + this.initData = []; } - }); - } - } - } + }) + }) + }); + } initElements(): void { this.threadStatesTbl = this.shadowRoot?.querySelector('#tb-running-percent'); // 暂时屏蔽列排序功能,后续增加则重写排序方法 this.threadStatesDIV = this.shadowRoot?.querySelector('#dataCut'); this.threadStatesDIV?.children[2].children[0].addEventListener('click', (e) => { - this.threadStatesTbl!.loading = true; this.dataSingleCut(this.threadStatesDIV?.children[0], this.threadStatesDIV?.children[1], this.initData); }) this.threadStatesDIV?.children[2].children[1].addEventListener('click', (e) => { - this.threadStatesTbl!.loading = true; this.dataLoopCut(this.threadStatesDIV?.children[0], this.threadStatesDIV?.children[1], this.initData); }) } @@ -202,22 +201,22 @@ export class TabPaneFreqDataCut extends BaseElement { }
- - + +
- - + + - - + + @@ -229,423 +228,198 @@ export class TabPaneFreqDataCut extends BaseElement { ` } - sortByColumn(treadStateDetail: any) { - function compare(property: any, treadStatesSort: any, type: any) { - return function (threadStatesLeftData: SelectionData | any, threadStatesRightData: SelectionData | any) { - if (threadStatesLeftData.process == ' ' || threadStatesRightData.process == ' ') { - return 0; - } - if (type === 'number') { - return treadStatesSort === 2 - ? parseFloat(threadStatesRightData[property]) - parseFloat(threadStatesLeftData[property]) - : parseFloat(threadStatesLeftData[property]) - parseFloat(threadStatesRightData[property]); - } else { - if (threadStatesRightData[property] > threadStatesLeftData[property]) { - return treadStatesSort === 2 ? 1 : -1; - } else if (threadStatesRightData[property] == threadStatesLeftData[property]) { - return 0; - } else { - return treadStatesSort === 2 ? -1 : 1; - } - } - }; - } - - if (treadStateDetail.key === 'name' || treadStateDetail.key === 'thread' || treadStateDetail.key === 'state') { - this.threadStatesTblSource.sort(compare(treadStateDetail.key, treadStateDetail.sort, 'string')); - } else { - this.threadStatesTblSource.sort(compare(treadStateDetail.key, treadStateDetail.sort, 'number')); - } - this.threadStatesTbl!.recycleDataSource = this.threadStatesTblSource; - } - // single方式切割数据功能 - dataSingleCut(threadId: any, threadFunc: any, resultList: any) { + dataLoopCut(threadId: any, threadFunc: any, resultList: any) { let threadIdValue = threadId.value.trim(); let threadFuncName = threadFunc.value.trim(); let leftNS = this.currentSelectionParam.leftNs; let rightNS = this.currentSelectionParam.rightNs; let tableValue: any = this.threadStatesTbl; tableValue.value = []; - if (/^[0-9]*$/.test(threadIdValue) && threadIdValue != '' && threadFuncName != '') { - threadId.style.border = '1px solid rgb(151,151,151)'; - threadFunc.style.border = '1px solid rgb(151,151,151)'; - // 根据用户输入的线程ID,方法名去查询数据库,得到对应的方法起始时间,持续时间等数据,以便作为依据进行后续数据切割 - querySearchFuncData(threadFuncName, Number(threadIdValue), leftNS, rightNS).then(result => { - if (result != null && result.length > 0) { - let targetMap = new Map(); - // 新创建map对象接收传过来的实参map - resultList.forEach((item: any, key: any) => { - targetMap.set(key, JSON.parse(JSON.stringify(item))); - }) - let timeDur = this.currentSelectionParam.recordStartNs; - // 周期切割依据数据整理 - let dealArr = new Array(); - for (let i of result) { - if (i.startTime + timeDur + i.dur < this.currentSelectionParam.rightNs + timeDur) { - dealArr.push({ 'ts': i.startTime + timeDur, 'dur': i.dur }); - } - } - let cycleMap = new Map(); - targetMap.forEach((item, key) => { - cycleMap.set(key, new Array()); - for (let i = 0; i < dealArr.length; i++) { - let cpuArr = new Array(); - let cpuMap = new Map(); - let resList = new Array(); - // 时间由纳秒转换为秒的倍数 - const multiple = 1000000000; - // 算力倍数值 - const countMutiple = 1000; - cpuMap.set(key, new Array()); - cycleMap.get(key).push({ 'thread': item[0].thread, 'ts': (dealArr[i].ts - timeDur) / multiple, 'count': 0, 'cpu': '', 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array() }); - let value = JSON.parse(JSON.stringify(item)); - for (let j = 0; j < value.length; j++) { - value[j].ts = value[j].ts * multiple; - value[j].freq = value[j].freq == 'unknown'? 0 : value[j].freq; - if (!cpuArr.includes(value[j].cpu)) { - cpuArr.push(value[j].cpu); - cpuMap.get(key).push({ 'thread': value[j].thread, 'count': 0, 'cpu': value[j].cpu, 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array() }); - } - if (dealArr[i].ts < value[j].ts) { - if (dealArr[i].ts + dealArr[i].dur > value[j].ts) { - if (dealArr[i].ts + dealArr[i].dur > value[j].ts + value[j].dur) { - resList.push({ 'thread': value[j].thread, 'ts': (value[j].ts - timeDur) / multiple, 'count': (value[j].freq * value[j].dur) / countMutiple, 'cpu': value[j].cpu, 'freq': value[j].freq, 'dur': value[j].dur, 'percent': value[j].percent, 'state': 'Running', 'id': i }); - } else { - resList.push({ 'thread': value[j].thread, 'ts': (value[j].ts - timeDur) / multiple, 'count': (dealArr[i].ts + dealArr[i].dur - value[j].ts) * value[j].freq / countMutiple, 'cpu': value[j].cpu, 'freq': value[j].freq, 'dur': dealArr[i].ts + dealArr[i].dur - value[j].ts, 'percent': (dealArr[i].ts + dealArr[i].dur - value[j].ts) / value[j].dur * value[j].percent, 'state': 'Running', 'id': i }); - break; - } - } - } else { - if (value[j].ts + value[j].dur > dealArr[i].ts) { - if (value[j].ts + value[j].dur > dealArr[i].ts + dealArr[i].dur) { - resList.push({ 'thread': value[j].thread, 'ts': (dealArr[i].ts - timeDur) / multiple, 'count': dealArr[i].dur * value[j].freq / countMutiple, 'cpu': value[j].cpu, 'freq': value[j].freq, 'dur': dealArr[i].dur, 'percent': dealArr[i].dur / value[j].dur * value[j].percent, 'state': 'Running', 'id': i }); - break; - } else { - resList.push({ 'thread': value[j].thread, 'ts': (dealArr[i].ts - timeDur) / multiple, 'count': (value[j].ts + value[j].dur - dealArr[i].ts) * value[j].freq / countMutiple, 'cpu': value[j].cpu, 'freq': value[j].freq, 'dur': value[j].ts + value[j].dur - dealArr[i].ts, 'percent': (value[j].ts + value[j].dur - dealArr[i].ts) / value[j].dur * value[j].percent, 'state': 'Running', 'id': i }); - } - } + if (/^[0-9]*$/.test(threadIdValue)) { + querySearchFuncData(threadFuncName, threadIdValue, leftNS, rightNS).then(res => { + let displayArr = JSON.parse(JSON.stringify(resultList)); + let timeDur = this.currentSelectionParam.recordStartNs; + let cutArr = new Array(); + // 根据线程id及方法名获取的数据,处理后用作切割时间依据,时间跨度为整个方法开始时间到末个方法开始时间 + for (let i of res) { + cutArr.push({ 'ts': i.startTime + timeDur }); + } + // 将数据进行切割处理 + let finalArr = new Array(); + let finalResultArr = new Array(); + const tsMutiple = 1000000000; + finalResultArr.push({ 'thread': displayArr[0].thread, 'ts': '', 'count': 0, 'cpu': '', 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array() }); + for (let i = 0; i < cutArr.length - 1; i++) { + for (let j = 0; j < displayArr.length; j++) { + displayArr[j].ts = displayArr[j].ts * tsMutiple; + if (displayArr[j].ts >= cutArr[i].ts) { + if ((displayArr[j].ts + displayArr[j].dur) <= cutArr[i + 1].ts) { + finalArr.push({ 'thread': displayArr[j].thread, 'count': (displayArr[j].freq * displayArr[j].dur) / 1000, 'cpu': displayArr[j].cpu, 'freq': displayArr[j].freq, 'dur': displayArr[j].dur, 'percent': displayArr[j].percent, 'state': 'Running', 'ts': (displayArr[j].ts - timeDur) / tsMutiple, 'id': i }); + } else { + if (cutArr[i + 1].ts - displayArr[j].ts > 0) { + finalArr.push({ 'thread': displayArr[j].thread, 'count': (displayArr[j].freq * (cutArr[i + 1].ts - displayArr[j].ts)) / 1000, 'cpu': displayArr[j].cpu, 'freq': displayArr[j].freq, 'dur': cutArr[i + 1].ts - displayArr[j].ts, 'percent': displayArr[j].percent * ((cutArr[i + 1].ts - displayArr[j].ts) / displayArr[j].dur), 'state': 'Running', 'ts': (displayArr[j].ts - timeDur) / tsMutiple, 'id': i }); + break; } } - this.mergeData(resList); - resList.sort((a, b) => b.count - a.count); - cpuMap.get(key).sort((a: any, b: any) => a.cpu - b.cpu); - cpuMap.get(key).forEach((item: any) => { - for (let s = 0; s < resList.length; s++) { - if (item.cpu == resList[s].cpu) { - item.children.push(resList[s]); - item.count += resList[s].count; - item.dur += resList[s].dur; - item.percent += resList[s].percent; - } - } - item.percent = Number(item.percent.toFixed(2)); - }); - // 将cpu数据放置到对应周期层级下 - this.mergeCycleData(cycleMap.get(key)[i], cpuMap.get(key)); + } else { + if ((displayArr[j].ts + displayArr[j].dur) > cutArr[i + 1].ts) { + finalArr.push({ 'thread': displayArr[j].thread, 'count': (displayArr[j].freq * (cutArr[i + 1].ts - cutArr[i].ts)) / 1000, 'cpu': displayArr[j].cpu, 'freq': displayArr[j].freq, 'dur': cutArr[i + 1].ts - cutArr[i].ts, 'percent': displayArr[j].percent * ((cutArr[i + 1].ts - cutArr[i].ts) / displayArr[j].dur), 'state': 'Running', 'ts': (cutArr[i].ts - timeDur) / tsMutiple, 'id': i }); + } + if ((displayArr[j].ts + displayArr[j].dur) > cutArr[i].ts && (displayArr[j].ts + displayArr[j].dur) < cutArr[i + 1].ts) { + finalArr.push({ 'thread': displayArr[j].thread, 'count': (displayArr[j].freq * (displayArr[j].dur + displayArr[j].ts - cutArr[i].ts)) / 1000, 'cpu': displayArr[j].cpu, 'freq': displayArr[j].freq, 'dur': displayArr[j].dur + displayArr[j].ts - cutArr[i].ts, 'percent': displayArr[j].percent * ((displayArr[j].dur + displayArr[j].ts - cutArr[i].ts) / displayArr[j].dur), 'state': 'Running', 'ts': (cutArr[i].ts - timeDur) / tsMutiple, 'id': i }); + } } - }); - // 拷贝线程数组,防止数据污染 - let threadArr = JSON.parse(JSON.stringify(this.threadArr)); - // 拷贝进程数组,防止数据污染 - let processArr = JSON.parse(JSON.stringify(this.processArr)); - // 将周期层级防止到线程层级下 - this.mergeThreadData(threadArr, cycleMap); - let totalData = JSON.parse(JSON.stringify(this.originData)); - // 将原始数据放置到对应的线程层级下,周期数据前 - this.mergeTotalData(threadArr, totalData); - // 合并数据到进程层级下 - this.mergePidData(processArr, threadArr); - this.fixedDeal(processArr); - this.threadStatesTblSource = processArr; - this.threadStatesTbl!.recycleDataSource = processArr; - this.threadStatesTbl!.loading = false; - this.threadClick(processArr); - } else { - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; + } + finalResultArr[0].children.push({ 'thread': displayArr[0].thread, 'ts': (cutArr[i].ts - timeDur) / tsMutiple, 'count': 0, 'cpu': '', 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array(), 'id': i }); + } + + for (let i = 0; i < finalArr.length; i++) { + for (let j = i + 1; j < finalArr.length; j++) { + if (finalArr[i].cpu === finalArr[j].cpu && finalArr[i].freq === finalArr[j].freq && finalArr[i].id === finalArr[j].id) { + finalArr[i].dur += finalArr[j].dur; + finalArr[i].percent += finalArr[j].percent; + finalArr[i].count += finalArr[j].count; + finalArr.splice(j, 1); + j--; + } + } + finalArr[i].percent = Number((finalArr[i].percent).toFixed(2)); } + + let newArr1 = JSON.parse(JSON.stringify(finalResultArr[0])); + let newArr2 = JSON.parse(JSON.stringify(finalArr)); + let finalResult = new Array(this.mergeTree(newArr1, newArr2)); + this.threadStatesTblSource = finalResult[0].children.length > 0 ? finalResult : []; + this.threadStatesTbl!.recycleDataSource = finalResult[0].children.length > 0 ? finalResult : []; }) } else { - this.threadStatesTbl!.loading = false; - if(threadIdValue == ''){ - threadId.style.border = '1px solid rgb(255,0,0)'; - threadId.setAttribute('placeholder', 'Please input threadId!'); - } - if(threadFuncName == ''){ - threadFunc.style.border = '1px solid rgb(255,0,0)'; - threadFunc.setAttribute('placeholder', 'Please input funcName!'); - } - if(/^[0-9]*$/.test(threadIdValue) == false){ - threadId.style.border = '1px solid rgb(255,0,0)'; - threadId.setAttribute('placeholder', 'Please check the input!'); - } + alert('请输入正确的线程ID'); } } - // Loop方式切割数据功能 - dataLoopCut(threadId: any, threadFunc: any, resultList: any) { + dataSingleCut(threadId: any, threadFunc: any, resultList: any) { let threadIdValue = threadId.value.trim(); let threadFuncName = threadFunc.value.trim(); let leftNS = this.currentSelectionParam.leftNs; let rightNS = this.currentSelectionParam.rightNs; let tableValue: any = this.threadStatesTbl; tableValue.value = []; - if (/^[0-9]*$/.test(threadIdValue) && threadIdValue != '' && threadFuncName != '') { - threadId.style.border = '1px solid rgb(151,151,151)'; - threadFunc.style.border = '1px solid rgb(151,151,151)'; - querySearchFuncData(threadFuncName, Number(threadIdValue), leftNS, rightNS).then(res => { - if (res != null && res.length > 0) { - let targetMap = new Map(); - // 新创建map对象接收传过来的实参map - resultList.forEach((item: any, key: any) => { - targetMap.set(key, JSON.parse(JSON.stringify(item))); - }) - let timeDur = this.currentSelectionParam.recordStartNs; - let cutArr = new Array(); - // 根据线程id及方法名获取的数据,处理后用作切割时间依据,时间跨度为整个方法开始时间到末个方法开始时间 - for (let i of res) { - cutArr.push({ 'ts': i.startTime + timeDur }); + if (/^[0-9]*$/.test(threadIdValue)) { + querySearchFuncData(threadFuncName, threadIdValue, leftNS, rightNS).then(result => { + let [...targetList] = JSON.parse(JSON.stringify(resultList)); + let timeDur = this.currentSelectionParam.recordStartNs; + let dealArr = new Array(); + for (let i of result) { + if (i.startTime + timeDur + i.dur < this.currentSelectionParam.rightNs + timeDur) { + dealArr.push({ 'ts': i.startTime + timeDur, 'dur': i.dur }); } - let cycleMap = new Map(); - targetMap.forEach((item, key) => { - cycleMap.set(key, new Array()); - for (let i = 0; i < cutArr.length - 1; i++) { - let cpuArr = new Array(); - let cpuMap = new Map(); - let resList = new Array(); - // 时间由纳秒转换为秒的倍数 - const multiple = 1000000000; - // 算力倍数值 - const countMutiple = 1000; - cpuMap.set(key, new Array()); - cycleMap.get(key).push({ 'thread': item[0].thread, 'ts': (cutArr[i].ts - timeDur) / multiple, 'count': 0, 'cpu': '', 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array() }); - let value = JSON.parse(JSON.stringify(item)); - for (let j = 0; j < value.length; j++) { - value[j].ts = value[j].ts * multiple; - value[j].freq = value[j].freq == 'unknown'? 0 : value[j].freq; - if (!cpuArr.includes(value[j].cpu)) { - cpuArr.push(value[j].cpu); - cpuMap.get(key).push({ 'thread': value[j].thread, 'count': 0, 'cpu': value[j].cpu, 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array() }); - } - if (value[j].ts >= cutArr[i].ts) { - if ((value[j].ts + value[j].dur) <= cutArr[i + 1].ts) { - resList.push({ 'thread': value[j].thread, 'count': (value[j].freq * value[j].dur) / countMutiple, 'cpu': value[j].cpu, 'freq': value[j].freq, 'dur': value[j].dur, 'percent': value[j].percent, 'state': 'Running', 'ts': (value[j].ts - timeDur) / multiple, 'id': i }); - } else { - if (cutArr[i + 1].ts - value[j].ts > 0) { - resList.push({ 'thread': value[j].thread, 'count': (value[j].freq * (cutArr[i + 1].ts - value[j].ts)) / countMutiple, 'cpu': value[j].cpu, 'freq': value[j].freq, 'dur': cutArr[i + 1].ts - value[j].ts, 'percent': value[j].percent * ((cutArr[i + 1].ts - value[j].ts) / value[j].dur), 'state': 'Running', 'ts': (value[j].ts - timeDur) / multiple, 'id': i }); - break; - } - } - } else { - if ((value[j].ts + value[j].dur) > cutArr[i + 1].ts) { - resList.push({ 'thread': value[j].thread, 'count': (value[j].freq * (cutArr[i + 1].ts - cutArr[i].ts)) / countMutiple, 'cpu': value[j].cpu, 'freq': value[j].freq, 'dur': cutArr[i + 1].ts - cutArr[i].ts, 'percent': value[j].percent * ((cutArr[i + 1].ts - cutArr[i].ts) / value[j].dur), 'state': 'Running', 'ts': (cutArr[i].ts - timeDur) / multiple, 'id': i }); - } - if ((value[j].ts + value[j].dur) > cutArr[i].ts && (value[j].ts + value[j].dur) < cutArr[i + 1].ts) { - resList.push({ 'thread': value[j].thread, 'count': (value[j].freq * (value[j].dur + value[j].ts - cutArr[i].ts)) / countMutiple, 'cpu': value[j].cpu, 'freq': value[j].freq, 'dur': value[j].dur + value[j].ts - cutArr[i].ts, 'percent': value[j].percent * ((value[j].dur + value[j].ts - cutArr[i].ts) / value[j].dur), 'state': 'Running', 'ts': (cutArr[i].ts - timeDur) / multiple, 'id': i }); - } - } - } - // 合并相同周期内的数据 - this.mergeData(resList); - // 以算力消耗降序排列 - resList.sort((a, b) => b.count - a.count); - // 以cpu升序排列 - cpuMap.get(key).sort((a: any, b: any) => a.cpu - b.cpu); - cpuMap.get(key).forEach((item: any) => { - for (let s = 0; s < resList.length; s++) { - if (item.cpu == resList[s].cpu) { - item.children.push(resList[s]); - item.count += resList[s].count; - item.dur += resList[s].dur; - item.percent += resList[s].percent; - } - } - item.percent = Number(item.percent.toFixed(2)); - }); - // 将cpu数据放置到对应周期层级下 - this.mergeCycleData(cycleMap.get(key)[i], cpuMap.get(key)); - } - }); - let threadArr = JSON.parse(JSON.stringify(this.threadArr)); - let processArr = JSON.parse(JSON.stringify(this.processArr)); - this.mergeThreadData(threadArr, cycleMap); - let totalData = JSON.parse(JSON.stringify(this.originData)); - this.mergeTotalData(threadArr, totalData); - this.mergePidData(processArr, threadArr); - this.fixedDeal(processArr); - this.threadStatesTblSource = processArr; - this.threadStatesTbl!.recycleDataSource = processArr; - this.threadStatesTbl!.loading = false; - this.threadClick(processArr); - } else { - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; } - }) - } else { - this.threadStatesTbl!.loading = false; - if(threadIdValue == ''){ - threadId.style.border = '1px solid rgb(255,0,0)'; - threadId.setAttribute('placeholder', 'Please input threadId!'); - } - if(threadFuncName == ''){ - threadFunc.style.border = '1px solid rgb(255,0,0)'; - threadFunc.setAttribute('placeholder', 'Please input funcName!'); - } - if(/^[0-9]*$/.test(threadIdValue) == false){ - threadId.style.border = '1px solid rgb(255,0,0)'; - threadId.setAttribute('placeholder', 'Please check the input!'); - } - } - } - mergeFreqData(needDeal: any, cpuMap: any, dealArr: any, sum: number, threadStatesParam: SelectionParam | any) { - needDeal.forEach((value: any, key: any) => { - let resultList = new Array(); - cpuMap.set(key, new Array()); - let cpuArr = new Array(); - // 时间由纳秒转换为秒的倍数 - const multiple = 1000000000; - // 算力倍数值 - const countMutiple = 1000; - for (let i = 0; i < value.length; i++) { - if (!cpuArr.includes(value[i].cpu)) { - cpuArr.push(value[i].cpu); - cpuMap.get(key).push({ 'process': Utils.PROCESS_MAP.get(value[i].pid) == null ? 'Process ' + value[i].pid : Utils.PROCESS_MAP.get(value[i].pid) + ' ' + value[i].pid, 'thread': value[i].tid + '_' + Utils.THREAD_MAP.get(value[i].tid), 'pid': value[i].pid, 'tid': value[i].tid, 'count': 0, 'cpu': value[i].cpu, 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array() }); - } - for (let j = 0; j < dealArr.length; j++) { - if (value[i].cpu == dealArr[j].cpu) { - if (value[i].ts > dealArr[j].startNS) { - if (value[i].ts < (dealArr[j].startNS + dealArr[j].dur)) { - if (value[i].dur < (dealArr[j].startNS + dealArr[j].dur - value[i].ts)) { - resultList.push({ 'thread': value[i].tid + '_' + value[i].thread, 'count': (dealArr[j].value * value[i].dur) / countMutiple, 'cpu': value[i].cpu, 'freq': dealArr[j].value, 'dur': value[i].dur, 'percent': value[i].dur / sum * 100, 'state': 'Running', 'ts': value[i].ts / multiple }); - break; + let finalResultArr = new Array(); + finalResultArr.push({ 'thread': targetList[0].thread, 'ts': '', 'count': 0, 'cpu': '', 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array() }); + let resList = new Array(); + const tsMutiple = 1000000000; + for (let i = 0; i < dealArr.length; i++) { + for (let j = 0; j < targetList.length; j++) { + targetList[j].ts = targetList[j].ts * tsMutiple; + if (dealArr[i].ts < targetList[j].ts) { + if (dealArr[i].ts + dealArr[i].dur > targetList[j].ts) { + if (dealArr[i].ts + dealArr[i].dur > targetList[j].ts + targetList[j].dur) { + resList.push({ 'thread': targetList[i].thread, 'ts': (targetList[j].ts - timeDur) / tsMutiple, 'count': (targetList[j].freq * targetList[j].dur) / 1000, 'cpu': targetList[j].cpu, 'freq': targetList[j].freq, 'dur': targetList[j].dur, 'percent': targetList[j].percent, 'state': 'Running', 'id': i }); } else { - resultList.push({ 'thread': value[i].tid + '_' + value[i].thread, 'count': (dealArr[j].value * (dealArr[j].startNS + dealArr[j].dur - value[i].ts)) / countMutiple, 'cpu': value[i].cpu, 'freq': dealArr[j].value, 'dur': (dealArr[j].startNS + dealArr[j].dur - value[i].ts), 'percent': (dealArr[j].startNS + dealArr[j].dur - value[i].ts) / sum * 100, 'state': 'Running', 'ts': value[i].ts / multiple }); + resList.push({ 'thread': targetList[j].thread, 'ts': (targetList[j].ts - timeDur) / tsMutiple, 'count': (dealArr[i].ts + dealArr[i].dur - targetList[j].ts) * targetList[j].freq / 1000, 'cpu': targetList[j].cpu, 'freq': targetList[j].freq, 'dur': dealArr[i].ts + dealArr[i].dur - targetList[j].ts, 'percent': (dealArr[i].ts + dealArr[i].dur - targetList[j].ts) / targetList[j].dur * targetList[j].percent, 'state': 'Running', 'id': i }); + break; } } } else { - if ((value[i].ts + value[i].dur) > dealArr[j].startNS) { - if ((value[i].dur + value[i].ts - dealArr[j].startNS) < dealArr[j].dur) { - resultList.push({ 'thread': value[i].tid + '_' + value[i].thread, 'count': (dealArr[j].value * (value[i].dur + value[i].ts - dealArr[j].startNS)) / countMutiple, 'cpu': value[i].cpu, 'freq': dealArr[j].value, 'dur': (value[i].dur + value[i].ts - dealArr[j].startNS), 'percent': (value[i].dur + value[i].ts - dealArr[j].startNS) / sum * 100, 'state': 'Running', 'ts': dealArr[j].startNS / multiple }); + if (targetList[j].ts + targetList[j].dur > dealArr[i].ts) { + if (targetList[j].ts + targetList[j].dur > dealArr[i].ts + dealArr[i].dur) { + resList.push({ 'thread': targetList[j].thread, 'ts': (dealArr[i].ts - timeDur) / tsMutiple, 'count': dealArr[i].dur * targetList[j].freq / 1000, 'cpu': targetList[j].cpu, 'freq': targetList[j].freq, 'dur': dealArr[i].dur, 'percent': dealArr[i].dur / targetList[j].dur * targetList[j].percent, 'state': 'Running', 'id': i }); break; } else { - resultList.push({ 'thread': value[i].tid + '_' + value[i].thread, 'count': (dealArr[j].value * dealArr[j].dur) / countMutiple, 'cpu': value[i].cpu, 'freq': dealArr[j].value, 'dur': dealArr[j].dur, 'percent': dealArr[j].dur / sum * 100, 'state': 'Running', 'ts': dealArr[j].startNS / multiple }); + resList.push({ 'thread': targetList[j].thread, 'ts': (dealArr[i].ts - timeDur) / tsMutiple, 'count': (targetList[j].ts + targetList[j].dur - dealArr[i].ts) * targetList[j].freq / 1000, 'cpu': targetList[j].cpu, 'freq': targetList[j].freq, 'dur': targetList[j].ts + targetList[j].dur - dealArr[i].ts, 'percent': (targetList[j].ts + targetList[j].dur - dealArr[i].ts) / targetList[j].dur * targetList[j].percent, 'state': 'Running', 'id': i }); } - } else { - resultList.push({ 'thread': value[i].tid + '_' + value[i].thread, 'count': 0, 'cpu': value[i].cpu, 'freq': 'unknown', 'dur': value[i].dur, 'percent': value[i].dur / sum * 100, 'state': 'Running', 'ts': value[i].ts / multiple }); - break; } } } + finalResultArr[0].children.push({ 'thread': targetList[0].thread, 'ts': (dealArr[i].ts - timeDur) / tsMutiple, 'count': 0, 'cpu': '', 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array(), 'id': i }); } - } - this.initData.set(key, JSON.parse(JSON.stringify(resultList))); - //合并同一线程内,当运行所在cpu和频点相同时,dur及percent进行累加求和,或许可以进行算法优化 - for (let i = 0; i < resultList.length; i++) { - for (let j = i + 1; j < resultList.length; j++) { - if (resultList[i].cpu == resultList[j].cpu && resultList[i].freq == resultList[j].freq) { - resultList[i].dur += resultList[j].dur; - resultList[i].percent += resultList[j].percent; - resultList[i].count += resultList[j].count; - resultList.splice(j, 1); - j--; - } - } - resultList[i].percent = Number((resultList[i].percent).toFixed(2)); - resultList[i].ts = (resultList[i].ts * 1000000000 - threadStatesParam.recordStartNs) / 1000000000; - } - resultList.sort((a, b) => b.count - a.count); - cpuMap.get(key).sort((a: any, b: any) => a.cpu - b.cpu); - needDeal.set(key, resultList); - }) - } - mergeCpuData(cpuMap: any, needDeal: any) { - cpuMap.forEach((value: any, key: any) => { - let arr = needDeal.get(key); - for (let i = 0; i < value.length; i++) { - for (let j = 0; j < arr.length; j++) { - if (arr[j].cpu == value[i].cpu) { - value[i].children.push(arr[j]); - value[i].count += arr[j].count; - value[i].dur += arr[j].dur; - value[i].percent += arr[j].percent; + // 合并相同周期内的数据 + for (let i = 0; i < resList.length; i++) { + for (let j = i + 1; j < resList.length; j++) { + if (resList[i].cpu === resList[j].cpu && resList[i].freq === resList[j].freq && resList[i].id === resList[j].id) { + resList[i].dur += resList[j].dur; + resList[i].percent += resList[j].percent; + resList[i].count += resList[j].count; + resList.splice(j, 1); + j--; + } } + resList[i].percent = Number((resList[i].percent).toFixed(2)); } - value[i].percent = Number(value[i].percent.toFixed(2)); - } - }); - } - mergeThreadData(threadArr: any, cpuMap: any) { - for (let i = 0; i < threadArr.length; i++) { - let cpuMapData = cpuMap.get(threadArr[i].pid + '_' + threadArr[i].tid); - for (let j = 0; j < cpuMapData.length; j++) { - threadArr[i].children.push(cpuMapData[j]); - threadArr[i].count += cpuMapData[j].count; - threadArr[i].dur += cpuMapData[j].dur; - threadArr[i].percent += cpuMapData[j].percent; - } - threadArr[i].percent = Number(threadArr[i].percent.toFixed(2)); - } - } - mergePidData(pidArr: any, threadArr: any) { - for (let i = 0; i < pidArr.length; i++) { - for (let j = 0; j < threadArr.length; j++) { - if (pidArr[i].pid == threadArr[j].pid) { - pidArr[i].children.push(threadArr[j]); - pidArr[i].count += threadArr[j].count; - pidArr[i].dur += threadArr[j].dur; - pidArr[i].percent += threadArr[j].percent; - } - } - pidArr[i].percent = Number(pidArr[i].percent.toFixed(2)); - } - } - mergeData(resList: any) { - // 合并相同周期内的数据 - for (let i = 0; i < resList.length; i++) { - for (let j = i + 1; j < resList.length; j++) { - if (resList[i].cpu === resList[j].cpu && resList[i].freq === resList[j].freq && resList[i].id === resList[j].id) { - resList[i].dur += resList[j].dur; - resList[i].percent += resList[j].percent; - resList[i].count += resList[j].count; - resList.splice(j, 1); - j--; - } - } - resList[i].percent = Number((resList[i].percent).toFixed(2)); - } - } - mergeCycleData(obj: any, arr: any) { - for (let i = 0; i < arr.length; i++) { - if (arr[i].count === 0 && arr[i].dur === 0) { - continue; - } - obj.children.push(arr[i]); - obj.count += arr[i].count; - obj.dur += arr[i].dur; - obj.percent += arr[i].percent; + + let newArr1 = JSON.parse(JSON.stringify(finalResultArr[0])); + let newArr2 = JSON.parse(JSON.stringify(resList)); + let finalResult = new Array(this.mergeTree(newArr1, newArr2)); + + this.threadStatesTblSource = finalResult[0].children.length > 0 ? finalResult : []; + this.threadStatesTbl!.recycleDataSource = finalResult[0].children.length > 0 ? finalResult : []; + }) + } else { + alert('请输入正确的线程ID'); } - obj.percent = Number(obj.percent.toFixed(2)); } - mergeTotalData(threadArr: any, totalData: any) { - for (let i = 0; i < threadArr.length; i++) { - for (let j = 0; j < totalData.length; j++) { - if (threadArr[i].pid == totalData[j].pid && threadArr[i].tid == totalData[j].tid) { - totalData[j].thread = 'TotalData'; - threadArr[i].children.unshift(totalData[j]); + + mergeTree(arr1: any, arr2: any) { + for (let i = 0; i < arr1.children.length; i++) { + // 改成map对象做标记 + let cpuArr = new Array(); + let flagMap = new Map(); + let flag = 0; + for (let j = 0; j < arr2.length; j++) { + if (arr1.children[i].id == arr2[j].id) { + if (!cpuArr.includes(arr2[j].cpu)) { + flagMap.set(arr2[j].cpu, flag); + cpuArr.push(arr2[j].cpu); + arr1.children[i].children.push({ 'thread': arr2[j].thread, 'count': 0, 'cpu': arr2[j].cpu, 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', 'ts': '', children: new Array(), 'id': arr2[j].id }); + if (arr1.children[i].children[flag].cpu == arr2[j].cpu && arr1.children[i].children[flag].id == arr2[j].id) { + arr1.children[i].children[flag].children.push(arr2[j]); + arr1.children[i].children[flag].dur += arr2[j].dur; + arr1.children[i].children[flag].percent += arr2[j].percent; + arr1.children[i].children[flag].count += arr2[j].count; + arr1.children[i].percent += arr1.children[i].children[flag].percent; + arr1.children[i].children[flag].percent = Number(arr1.children[i].children[flag].percent.toFixed(2)); + arr1.children[i].dur += arr1.children[i].children[flag].dur; + arr1.children[i].count += arr1.children[i].children[flag].count; + flag++; + arr2.splice(j, 1); + j--; + } + } else { + // 利用map做数据处理 + let count = flagMap.get(arr2[j].cpu); + if (arr1.children[i].children[count].cpu == arr2[j].cpu && arr1.children[i].children[count].id == arr2[j].id) { + arr1.children[i].children[count].children.push(arr2[j]); + arr1.children[i].children[count].dur += arr2[j].dur; + arr1.children[i].children[count].percent += arr2[j].percent; + arr1.children[i].children[count].count += arr2[j].count; + arr1.children[i].percent += arr2[j].percent; + arr1.children[i].children[count].percent = Number(arr2[j].percent.toFixed(2)); + arr1.children[i].dur += arr2[j].dur; + arr1.children[i].count += arr2[j].count; + arr2.splice(j, 1); + j--; + } + } + } else { + break; } } + arr1.children[i].children.sort((a: any, b: any) => a.cpu - b.cpu); + arr1.percent += arr1.children[i].percent; + arr1.children[i].percent = Number(arr1.children[i].percent.toFixed(2)); + arr1.dur += arr1.children[i].dur; + arr1.count += arr1.children[i].count; } - } - fixedDeal(arr: any){ - if(arr == undefined){ - return ; - } - for(let i = 0; i < arr.length; i++){ - arr[i].percent = arr[i].percent.toFixed(2); - arr[i].percent = arr[i].percent > 100 ? 100 : arr[i].percent; - this.fixedDeal(arr[i].children); - } + arr1.percent = Number(arr1.percent.toFixed(2)); + return arr1; } } \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts index 288916582cf51c05b39e6c574ed092c5308c3da3..d0301e1c7caea81794dce3f1668ae2faaa7cc91c 100644 --- a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts +++ b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts @@ -14,244 +14,215 @@ */ import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; -import { LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table.js'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection.js'; -import '../../../StackBar.js' +import { LitTable } from '../../../../../base-ui/table/lit-table'; +import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; +import '../../../StackBar.js'; import { getTabRunningPercent, queryCpuFreqUsageData, queryCpuFreqFilterId } from '../../../../database/SqlLite.js'; import { Utils } from '../../base/Utils.js'; import { resizeObserver } from '../SheetUtils.js'; -import { SliceGroup } from '../../../../bean/StateProcessThread.js'; @element('tabpane-frequsage') export class TabPaneFreqUsage extends BaseElement { - private threadStatesTbl: LitTable | null | undefined; - private threadStatesTblSource: Array = []; - private currentSelectionParam: Selection | undefined; + private threadStatesTbl: LitTable | null | undefined; + private threadStatesTblSource: Array = []; + private currentSelectionParam: Selection | undefined; - set data(threadStatesParam: SelectionParam | any) { - if (this.currentSelectionParam === threadStatesParam) { - return; - } - this.threadStatesTbl!.loading = true; - this.currentSelectionParam = threadStatesParam; - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - let tableValue: any = this.threadStatesTbl; - tableValue.value = []; - // 查询框选区域内的状态为running的数据 - getTabRunningPercent(threadStatesParam.threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs).then((result) => { - // 查询该trace文件中的cpu核数及id - queryCpuFreqFilterId().then(r => { - // 将查询结果以键值对形式存入Map对象,仪表后续将频点数据与Cpu进行关联 - let IdMap = new Map(); - let queryId = new Array(); - for (let i = 0; i < r.length; i++) { - queryId.push(r[i].id); - IdMap.set(r[i].id, r[i].cpu); - } - // 通过cpu的id去查询总的cpu频点数据 - queryCpuFreqUsageData(queryId).then((res) => { - if (result != null && result.length > 0) { - let sum = 0; - let dealArr = new Array(); - // 将cpu频点数据进行整合 - for (let i of res) { - dealArr.push({ 'startNS': i.startNS + threadStatesParam.recordStartNs, 'dur': i.dur, 'value': i.value, 'cpu': IdMap.get(i.filter_id) }); - } - let needDeal = new Map(); - let cpuMap = new Map(); - let pidArr = new Array(); - let threadArr = new Array(); - // 创建进程级的数组 - let processArr: any = threadStatesParam.processIds.length > 1 ? [...new Set(threadStatesParam.processIds)] : threadStatesParam.processIds; - for (let i of processArr) { - pidArr.push({ 'process': Utils.PROCESS_MAP.get(i) == null ? 'Process ' + i : Utils.PROCESS_MAP.get(i) + ' ' + i, 'thread': Utils.PROCESS_MAP.get(i) == null ? 'Process ' + i : Utils.PROCESS_MAP.get(i) + ' ' + i, 'pid': i, 'tid': '', 'count': 0, 'cpu': '', 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array() }); - } - // 将running线程数据存到map中 - for (let e of result) { - if (processArr.includes(e.pid) && e.state == 'Running') { - if (needDeal.get(e.pid + '_' + e.tid) == undefined) { - threadArr.push({ 'process': Utils.PROCESS_MAP.get(e.pid) == null ? 'Process ' + e.pid : Utils.PROCESS_MAP.get(e.pid) + ' ' + e.pid, 'thread': Utils.THREAD_MAP.get(e.tid) + ' ' + e.tid, 'pid': e.pid, 'tid': e.tid, 'count': 0, 'cpu': '', 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array() }); - needDeal.set(e.pid + '_' + e.tid, new Array()); - } - let arr = needDeal.get(e.pid + '_' + e.tid); - let process = Utils.PROCESS_MAP.get(e.pid); - let thread = Utils.THREAD_MAP.get(e.tid); - e.process = process == null || process.length == 0 ? '[NULL]' : process; - e.thread = thread == null || thread.length == 0 ? '[NULL]' : thread; - e.stateJX = e.state; - e.state = Utils.getEndState(e.stateJX); - sum += e.dur; - arr.push(e); - } - } - // 整理running线程数据、cpu层级信息 - this.mergeFreqData(needDeal, cpuMap, dealArr, sum, threadStatesParam); - // 将频点数据放置到对应cpu层级下 - this.mergeCpuData(cpuMap, needDeal); - // 将cpu层级数据放置到线程分组下 - this.mergeThreadData(threadArr, cpuMap); - // 将线程层级数据放置到进程级分组下 - this.mergePidData(pidArr, threadArr); - // 百分比保留两位小数 - this.fixedDeal(pidArr) - this.threadStatesTblSource = pidArr; - this.threadStatesTbl!.recycleDataSource = pidArr; - this.threadStatesTbl!.loading = false; - this.theadClick(pidArr); - } else { - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; - } - }) - }) - - }) + set data(threadStatesParam: SelectionParam | any) { + if (this.currentSelectionParam === threadStatesParam) { + return; } - - private theadClick(data: Array) { - let labels = this.threadStatesTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - if (labels) { - for (let i = 0; i < labels.length; i++) { - let label = labels[i].innerHTML; - labels[i].addEventListener('click', (e) => { - if (label.includes('Process') && i === 0) { - this.threadStatesTbl!.setStatus(data, false); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('Thread') && i === 1) { - for (let item of data) { - item.status = true; - if (item.children != undefined && item.children.length > 0) { - this.threadStatesTbl!.setStatus(item.children, false); - } - } - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('CPU') && i === 2) { - this.threadStatesTbl!.setStatus(data, true); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand); - } + this.currentSelectionParam = threadStatesParam; + this.threadStatesTblSource = []; + this.threadStatesTbl!.recycleDataSource = []; + let tableValue: any = this.threadStatesTbl; + tableValue.value = []; + getTabRunningPercent(threadStatesParam.threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs).then( + (result) => { + queryCpuFreqFilterId().then((r) => { + let IdMap = new Map(); + let queryId = new Array(); + for (let i = 0; i < r.length; i++) { + queryId.push(r[i].id); + IdMap.set(r[i].id, r[i].cpu); + } + queryCpuFreqUsageData(queryId).then((res) => { + if (result != null && result.length > 0) { + let sum = 0; + let dealArr = new Array(); + for (let i of res) { + dealArr.push({ + startNS: i.startNS + threadStatesParam.recordStartNs, + dur: i.dur, + value: i.value, + cpu: IdMap.get(i.filter_id), }); - } - } - } - mergeFreqData(needDeal: any, cpuMap: any, dealArr: any, sum: number, threadStatesParam: SelectionParam | any) { - needDeal.forEach((value: any, key: any) => { - let resultList = new Array(); - cpuMap.set(key, new Array()); - let cpuArr = new Array(); - const multiple = 1000; - for (let i = 0; i < value.length; i++) { - if (!cpuArr.includes(value[i].cpu)) { - cpuArr.push(value[i].cpu); - cpuMap.get(key).push({ 'process': Utils.PROCESS_MAP.get(value[i].pid) == null ? 'Process ' + value[i].pid : Utils.PROCESS_MAP.get(value[i].pid) + ' ' + value[i].pid, 'thread': value[i].tid + '_' + Utils.THREAD_MAP.get(value[i].tid), 'pid': value[i].pid, 'tid': value[i].tid, 'count': 0, 'cpu': value[i].cpu, 'freq': '', 'dur': 0, 'percent': 0, 'state': 'Running', children: new Array() }); + } + let targetList = new Array(); + let cpuArr = new Array(); + let finalResultArr = new Array(); + finalResultArr.push({ + thread: '', + count: 0, + cpu: '', + freq: '', + dur: 0, + percent: '100.00', + state: 'Running', + children: new Array(), + }); + for (let e of result) { + if (threadStatesParam.processIds.includes(e.pid) && e.state == 'Running') { + let process = Utils.PROCESS_MAP.get(e.pid); + let thread = Utils.THREAD_MAP.get(e.tid); + e.process = process == null || process.length == 0 ? '[NULL]' : process; + e.thread = thread == null || thread.length == 0 ? '[NULL]' : thread; + e.stateJX = e.state; + e.state = Utils.getEndState(e.stateJX); + sum += e.dur; + targetList.push(e); + if (!cpuArr.includes(e.cpu)) { + cpuArr.push(e.cpu); + finalResultArr[0].thread = + finalResultArr[0].thread == '' ? e.tid + '_' + e.thread : finalResultArr[0].thread; + finalResultArr[0].children.push({ + thread: e.tid + '_' + e.thread, + count: 0, + cpu: e.cpu, + freq: '', + dur: 0, + percent: 0, + state: 'Running', + children: new Array(), + }); + } } + } + let resultList = new Array(); + for (let i = 0; i < targetList.length; i++) { for (let j = 0; j < dealArr.length; j++) { - if (value[i].cpu == dealArr[j].cpu) { - if (value[i].ts > dealArr[j].startNS) { - if (value[i].ts < (dealArr[j].startNS + dealArr[j].dur)) { - if (value[i].dur < (dealArr[j].startNS + dealArr[j].dur - value[i].ts)) { - resultList.push({ 'thread': value[i].tid + '_' + value[i].thread, 'count': (dealArr[j].value * value[i].dur) / multiple, 'cpu': value[i].cpu, 'freq': dealArr[j].value, 'dur': value[i].dur, 'percent': value[i].dur / sum * 100, 'state': 'Running', 'ts': value[i].ts }); - break; - } else { - resultList.push({ 'thread': value[i].tid + '_' + value[i].thread, 'count': (dealArr[j].value * (dealArr[j].startNS + dealArr[j].dur - value[i].ts)) / multiple, 'cpu': value[i].cpu, 'freq': dealArr[j].value, 'dur': (dealArr[j].startNS + dealArr[j].dur - value[i].ts), 'percent': (dealArr[j].startNS + dealArr[j].dur - value[i].ts) / sum * 100, 'state': 'Running', 'ts': value[i].ts }); - } - } + if (targetList[i].cpu == dealArr[j].cpu) { + if (targetList[i].ts > dealArr[j].startNS) { + if (targetList[i].ts < dealArr[j].startNS + dealArr[j].dur) { + if (targetList[i].dur < dealArr[j].startNS + dealArr[j].dur - targetList[i].ts) { + resultList.push({ + thread: targetList[i].tid + '_' + targetList[i].thread, + count: (dealArr[j].value * targetList[i].dur) / 1000, + cpu: targetList[i].cpu, + freq: dealArr[j].value, + dur: targetList[i].dur, + percent: (targetList[i].dur / sum) * 100, + state: 'Running', + ts: targetList[i].ts, + }); + break; + } else { + resultList.push({ + thread: targetList[i].tid + '_' + targetList[i].thread, + count: (dealArr[j].value * (dealArr[j].startNS + dealArr[j].dur - targetList[i].ts)) / 1000, + cpu: targetList[i].cpu, + freq: dealArr[j].value, + dur: dealArr[j].startNS + dealArr[j].dur - targetList[i].ts, + percent: ((dealArr[j].startNS + dealArr[j].dur - targetList[i].ts) / sum) * 100, + state: 'Running', + ts: targetList[i].ts, + }); + } + } + } else { + if (targetList[i].ts + targetList[i].dur > dealArr[j].startNS) { + if (targetList[i].dur + targetList[i].ts - dealArr[j].startNS < dealArr[j].dur) { + resultList.push({ + thread: targetList[i].tid + '_' + targetList[i].thread, + count: + (dealArr[j].value * (targetList[i].dur + targetList[i].ts - dealArr[j].startNS)) / 1000, + cpu: targetList[i].cpu, + freq: dealArr[j].value, + dur: targetList[i].dur + targetList[i].ts - dealArr[j].startNS, + percent: ((targetList[i].dur + targetList[i].ts - dealArr[j].startNS) / sum) * 100, + state: 'Running', + ts: dealArr[j].startNS, + }); + break; } else { - if ((value[i].ts + value[i].dur) > dealArr[j].startNS) { - if ((value[i].dur + value[i].ts - dealArr[j].startNS) < dealArr[j].dur) { - resultList.push({ 'thread': value[i].tid + '_' + value[i].thread, 'count': (dealArr[j].value * (value[i].dur + value[i].ts - dealArr[j].startNS)) / multiple, 'cpu': value[i].cpu, 'freq': dealArr[j].value, 'dur': (value[i].dur + value[i].ts - dealArr[j].startNS), 'percent': (value[i].dur + value[i].ts - dealArr[j].startNS) / sum * 100, 'state': 'Running', 'ts': dealArr[j].startNS }); - break; - } else { - resultList.push({ 'thread': value[i].tid + '_' + value[i].thread, 'count': (dealArr[j].value * dealArr[j].dur) / multiple, 'cpu': value[i].cpu, 'freq': dealArr[j].value, 'dur': dealArr[j].dur, 'percent': dealArr[j].dur / sum * 100, 'state': 'Running', 'ts': dealArr[j].startNS }); - } - } else { - resultList.push({ 'thread': value[i].tid + '_' + value[i].thread, 'count': 0, 'cpu': value[i].cpu, 'freq': 'unknown', 'dur': value[i].dur, 'percent': value[i].dur / sum * 100, 'state': 'Running', 'ts': value[i].ts }); - break; - } + resultList.push({ + thread: targetList[i].tid + '_' + targetList[i].thread, + count: (dealArr[j].value * dealArr[j].dur) / 1000, + cpu: targetList[i].cpu, + freq: dealArr[j].value, + dur: dealArr[j].dur, + percent: (dealArr[j].dur / sum) * 100, + state: 'Running', + ts: dealArr[j].startNS, + }); } + } else { + resultList.push({ + thread: targetList[i].tid + '_' + targetList[i].thread, + count: 0, + cpu: targetList[i].cpu, + freq: 'unknown', + dur: targetList[i].dur, + percent: (targetList[i].dur / sum) * 100, + state: 'Running', + ts: targetList[i].ts, + }); + break; + } } + } } - } - //合并同一线程内,当运行所在cpu和频点相同时,dur及percent进行累加求和,或许可以进行算法优化 - for (let i = 0; i < resultList.length; i++) { + } + //合并同一线程内,当运行所在cpu和频点相同时,dur及percent进行累加求和,或许可以进行算法优化 + for (let i = 0; i < resultList.length; i++) { for (let j = i + 1; j < resultList.length; j++) { - if (resultList[i].cpu == resultList[j].cpu && resultList[i].freq == resultList[j].freq) { - resultList[i].dur += resultList[j].dur; - resultList[i].percent += resultList[j].percent; - resultList[i].count += resultList[j].count; - resultList.splice(j, 1); - j--; - } + if (resultList[i].cpu == resultList[j].cpu && resultList[i].freq == resultList[j].freq) { + resultList[i].dur += resultList[j].dur; + resultList[i].percent += resultList[j].percent; + resultList[i].count += resultList[j].count; + resultList.splice(j, 1); + j--; + } } - resultList[i].percent = Number((resultList[i].percent).toFixed(2)); + resultList[i].percent = Number(resultList[i].percent.toFixed(2)); resultList[i].ts = resultList[i].ts - threadStatesParam.recordStartNs; - } - resultList.sort((a, b) => b.count - a.count); - cpuMap.get(key).sort((a: any, b: any) => a.cpu - b.cpu); - needDeal.set(key, resultList); - }) - } - mergeCpuData(cpuMap: any, needDeal: any) { - cpuMap.forEach((value: any, key: any) => { - let arr = needDeal.get(key); - for (let i = 0; i < value.length; i++) { - for (let j = 0; j < arr.length; j++) { - if (arr[j].cpu == value[i].cpu) { - value[i].children.push(arr[j]); - value[i].count += arr[j].count; - value[i].dur += arr[j].dur; - value[i].percent += arr[j].percent; - } + } + finalResultArr[0].children.sort((a: any, b: any) => a.cpu - b.cpu); + // 转成树结构数据进行展示 + for (let i = 0; i < finalResultArr[0].children.length; i++) { + for (let j = 0; j < resultList.length; j++) { + if (finalResultArr[0].children[i].cpu == resultList[j].cpu) { + finalResultArr[0].children[i].children.push(resultList[j]); + finalResultArr[0].children[i].dur += resultList[j].dur; + finalResultArr[0].children[i].percent += resultList[j].percent; + finalResultArr[0].children[i].count += resultList[j].count; + resultList.splice(j, 1); + j--; + } } - value[i].percent = Number(value[i].percent.toFixed(2)); + finalResultArr[0].children[i].percent = finalResultArr[0].children[i].percent.toFixed(2); + finalResultArr[0].dur += finalResultArr[0].children[i].dur; + finalResultArr[0].count += finalResultArr[0].children[i].count; + } + this.threadStatesTblSource = finalResultArr; + this.threadStatesTbl!.recycleDataSource = finalResultArr; + } else { + this.threadStatesTblSource = []; + this.threadStatesTbl!.recycleDataSource = []; } + }); }); - } - mergeThreadData(threadArr: any, cpuMap: any) { - for (let i = 0; i < threadArr.length; i++) { - let cpuMapData = cpuMap.get(threadArr[i].pid + '_' + threadArr[i].tid); - for (let j = 0; j < cpuMapData.length; j++) { - threadArr[i].children.push(cpuMapData[j]); - threadArr[i].count += cpuMapData[j].count; - threadArr[i].dur += cpuMapData[j].dur; - threadArr[i].percent += cpuMapData[j].percent; - } - threadArr[i].percent = Number(threadArr[i].percent.toFixed(2)); - } - } - mergePidData(pidArr: any, threadArr: any) { - for (let i = 0; i < pidArr.length; i++) { - for (let j = 0; j < threadArr.length; j++) { - if (pidArr[i].pid == threadArr[j].pid) { - pidArr[i].children.push(threadArr[j]); - pidArr[i].count += threadArr[j].count; - pidArr[i].dur += threadArr[j].dur; - pidArr[i].percent += threadArr[j].percent; - } - } - pidArr[i].percent = Number(pidArr[i].percent.toFixed(2)); - } - } - fixedDeal(arr: any) { - if (arr == undefined) { - return; - } - for (let i = 0; i < arr.length; i++) { - arr[i].percent = arr[i].percent > 100 ? 100 : arr[i].percent; - arr[i].percent = arr[i].percent.toFixed(2); - this.fixedDeal(arr[i].children); - } - } - initElements(): void { - this.threadStatesTbl = this.shadowRoot?.querySelector('#tb-running-percent'); - } - connectedCallback() { - super.connectedCallback(); - resizeObserver(this.parentElement!, this.threadStatesTbl!); - } - initHtml(): string { - return ` + } + ); + } + initElements(): void { + this.threadStatesTbl = this.shadowRoot?.querySelector('#tb-running-percent'); + } + connectedCallback() { + super.connectedCallback(); + resizeObserver(this.parentElement!, this.threadStatesTbl!); + } + initHtml(): string { + return ` - - - + + + @@ -275,36 +246,6 @@ export class TabPaneFreqUsage extends BaseElement { - ` - } - sortByColumn(treadStateDetail: any) { - function compare(property: any, treadStatesSort: any, type: any) { - return function (threadStatesLeftData: SelectionData | any, threadStatesRightData: SelectionData | any) { - if (threadStatesLeftData.process == ' ' || threadStatesRightData.process == ' ') { - return 0; - } - if (type === 'number') { - return treadStatesSort === 2 - ? parseFloat(threadStatesRightData[property]) - parseFloat(threadStatesLeftData[property]) - : parseFloat(threadStatesLeftData[property]) - parseFloat(threadStatesRightData[property]); - } else { - if (threadStatesRightData[property] > threadStatesLeftData[property]) { - return treadStatesSort === 2 ? 1 : -1; - } else if (threadStatesRightData[property] == threadStatesLeftData[property]) { - return 0; - } else { - return treadStatesSort === 2 ? -1 : 1; - } - } - }; - } - - if (treadStateDetail.key === 'name' || treadStateDetail.key === 'thread' || treadStateDetail.key === 'state') { - this.threadStatesTblSource.sort(compare(treadStateDetail.key, treadStateDetail.sort, 'string')); - } else { - this.threadStatesTblSource.sort(compare(treadStateDetail.key, treadStateDetail.sort, 'number')); - } - this.threadStatesTbl!.recycleDataSource = this.threadStatesTblSource; - } - -} \ No newline at end of file + `; + } +} diff --git a/ide/src/trace/component/trace/timer-shaft/SportRuler.ts b/ide/src/trace/component/trace/timer-shaft/SportRuler.ts index 6ff2a4bab286800ccd13d9e370c31832a91a89eb..ea1c9e339fe27dbde16881d70343bc40fd6726a5 100644 --- a/ide/src/trace/component/trace/timer-shaft/SportRuler.ts +++ b/ide/src/trace/component/trace/timer-shaft/SportRuler.ts @@ -203,7 +203,7 @@ export class SportRuler extends Graph { this.drawFlag(flagObj.x, flagObj.color, flagObj.selected, flagObj.text, flagObj.type); } }); - // !this.hoverFlag.hidden && this.drawFlag(this.hoverFlag.x, this.hoverFlag.color, true, this.hoverFlag.text); + !this.hoverFlag.hidden && this.drawFlag(this.hoverFlag.x, this.hoverFlag.color, true, this.hoverFlag.text); //If region selection is enabled, the serial number draws a line on the axis to show the length of the box selection if (this.isRangeSelect) { let range = TraceRow.rangeSelectObject; @@ -443,7 +443,7 @@ export class SportRuler extends Graph { (this.rulerW * (startTime - this.range.startNS)) / (this.range.endNS - this.range.startNS) ); let endX = Math.round((this.rulerW * (endTime - this.range.startNS)) / (this.range.endNS - this.range.startNS)); - let color = randomRgbColor() || '#ff0000'; + let color = randomRgbColor(); this.slicesTime.color = color; newSlicestime = new SlicesTime( this.slicesTime.startTime || 0, diff --git a/ide/src/trace/database/SqlLite.ts b/ide/src/trace/database/SqlLite.ts index a1090c5549b7a750b59bf9f8a76f5fc048e59119..9fdde25ff150f50d679751d8ad48fc2509813437 100644 --- a/ide/src/trace/database/SqlLite.ts +++ b/ide/src/trace/database/SqlLite.ts @@ -864,7 +864,7 @@ export const getTabSlices = ( on T.id = C.callid where - C.ts not null + C.ts > 0 and c.dur >= 0 and @@ -908,7 +908,7 @@ export const getTabSlicesAsyncFunc = ( A.id = C.callid left join process P on P.id = A.ipid where - C.ts not null + C.ts > 0 and c.dur >= -1 and @@ -5500,7 +5500,7 @@ export const queryTraceType = (): Promise< export const queryTransferList = (): Promise> => query('queryTransferList', `select id, report_value as cmdStr from perf_report where report_type = 'config_name'`); -export const getTabRunningPercent = (tIds: Array, leftNS: number, rightNS: number): Promise> => + export const getTabRunningPercent = (tIds: Array, leftNS: number, rightNS: number): Promise> => query( 'getTabRunningPercent', ` @@ -5517,11 +5517,11 @@ export const getTabRunningPercent = (tIds: Array, leftNS: number, rightN and not ((B.ts - TR.start_ts + ifnull(B.dur,0) < ${leftNS}) or (B.ts - TR.start_ts > ${rightNS})) order by ts - `, + `, { $leftNS: leftNS, $rightNS: rightNS } ); -export const querySearchFuncData = (funcName: string, tIds: number, leftNS: number, rightNS: number): Promise> => +export const querySearchFuncData = (funcName: string, tIds: Array, leftNS: number, rightNS: number): Promise> => query( 'querySearchFuncData', ` @@ -5549,12 +5549,13 @@ export const querySearchFuncData = (funcName: string, tIds: number, leftNS: numb left join trace_range r where - c.name like '${funcName}%' + c.name = '${funcName}' and t.tid = ${tIds} and not ((startTime < ${leftNS}) or (startTime > ${rightNS})); - ` + `, + { $search: funcName } ); export const queryCpuFreqUsageData = (Ids: Array): Promise> => diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts index e08be9aca2c4109773aeada5ce5cb5902d4100c6..a10edceb7cab1a1c3ab883e48290646dc9cb3dc5 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts @@ -745,26 +745,6 @@ export function drawSelectionRange(context: any, params: TraceRow) { } } -//---------------------------新增代码开始-------------------------- - -export function drawVsync( - vsyncContext: CanvasRenderingContext2D | any, - startNS: number, - endNS: number, - totalNS: number, - frame:Rect, - color:string -){ - vsyncContext.lineWidth = 2; - vsyncContext.fillStyle = color?color:"#808080"; - vsyncContext.globalAlpha = 0.4; - vsyncContext.fillRect(frame.x,frame.y,frame.width,frame.height); - // vsyncContext.stroke(); - // vsyncContext.closePath(); -} - -//---------------------------新增代码结束-------------------------- - export function drawWakeUp( wakeUpContext: CanvasRenderingContext2D | any, wake: WakeupBean | undefined | null, diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerFunc.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerFunc.ts index 502f39b8dd070ea845b42ad386919d9f7e17e5de..363d3c87f6c83b3fc9bd7640a9d78f874fc904fe 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerFunc.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerFunc.ts @@ -116,7 +116,6 @@ export function func( } export class FuncStruct extends BaseFuncStruct { - [x: string]: any; static hoverFuncStruct: FuncStruct | undefined; static selectFuncStruct: FuncStruct | undefined; flag: string | undefined; // 570000 diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfCPU.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfCPU.ts index d38de318c166aa1f439dd3baf9bc686cfa04dabb..e535924fff3367531f758801f04b5928bd7def32 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfCPU.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerHiPerfCPU.ts @@ -15,6 +15,11 @@ import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; import { + BaseStruct, + drawFlagLine, + drawLines, + drawLoading, + drawSelection, HiPerfStruct, hiPerf, PerfRender, diff --git a/trace_streamer/src/base/index_map.h b/trace_streamer/src/base/index_map.h index 9127159e75eea546cd1836e2b112d477e4fe272f..6b8b63f5d3c8945be68decbf4f481adfba0d5761 100644 --- a/trace_streamer/src/base/index_map.h +++ b/trace_streamer/src/base/index_map.h @@ -200,6 +200,7 @@ public: rowIndex_.push_back(i); } } + empty_ = false; } indexType_ = INDEX_TYPE_OUTER_INDEX; FixSize();