diff --git a/ide/src/trace/bean/BoxSelection.ts b/ide/src/trace/bean/BoxSelection.ts index d8b22b6d4454d88c3f3314e029a2ababa9019e77..4e98c12040fdf297e24a8be42a99311b9e06bb38 100644 --- a/ide/src/trace/bean/BoxSelection.ts +++ b/ide/src/trace/bean/BoxSelection.ts @@ -72,7 +72,7 @@ export class SelectionParam { irqCallIds: Array = []; softIrqCallIds: Array = []; funTids: Array = []; - funAsync: Array<{ name: string; pid: number }> = []; + funAsync: Array<{ name: string; pid: number, tid: number | undefined }> = []; funCatAsync: Array<{ pid: number; threadName: string }> = []; nativeMemory: Array = []; nativeMemoryStatistic: Array = []; @@ -251,6 +251,7 @@ export class SelectionParam { this.funAsync.push({ name: th.asyncFuncName, pid: th.asyncFuncNamePID || 0, + tid: th.asyncFuncStartTID }); } else { for (let i = 0; i < th.asyncFuncName.length; i++) { @@ -258,6 +259,7 @@ export class SelectionParam { this.funAsync.push({ name: el, pid: th.asyncFuncNamePID || 0, + tid: th.asyncFuncStartTID }); } } @@ -324,6 +326,7 @@ export class SelectionParam { this.funAsync.push({ name: it.asyncFuncName, pid: it.asyncFuncNamePID || 0, + tid: it.asyncFuncStartTID }); } else { //@ts-ignore @@ -332,6 +335,7 @@ export class SelectionParam { this.funAsync.push({ name: el, pid: it.asyncFuncNamePID || 0, + tid: it.asyncFuncStartTID }); } } @@ -1275,8 +1279,7 @@ export class SliceBoxJumpParam { threadId: Array = []; name: string[] | undefined | null; isJumpPage: boolean | undefined; - asyncNames: Array = []; - asyncCatNames: Array = []; + isSummary: boolean | undefined; } export class SelectionData { diff --git a/ide/src/trace/component/chart/SpProcessChart.ts b/ide/src/trace/component/chart/SpProcessChart.ts index e558a6243d4166a004d70bbec457b427a6c0e21c..54e3f77feb93f3b639ec7f7328282777b5ae21d2 100644 --- a/ide/src/trace/component/chart/SpProcessChart.ts +++ b/ide/src/trace/component/chart/SpProcessChart.ts @@ -1317,13 +1317,21 @@ export class SpProcessChart { ({ asyncRemoveCatArr, asyncCat } = this.hanldCatFunc(asyncFuncList, flag));//处理是否cat ({ setArrayLenThanOne, setArrayLenOnlyOne } = this.hanldAsyncFunc(it, asyncRemoveCatArr));//len等于0和大于0的分类 //@ts-ignore - let aggregateData = { ...asyncCat, ...setArrayLenThanOne, ...setArrayLenOnlyOne }; - Reflect.ownKeys(aggregateData).map((key: unknown) => {//处理business first和length大于1的数据 - //@ts-ignore - let param: Array = aggregateData[key]; - //@ts-ignore + let aggregateData = {...setArrayLenThanOne, ...setArrayLenOnlyOne }; + Reflect.ownKeys(aggregateData).map((key: any) => { + let param: Array = aggregateData[key]; this.makeAddAsyncFunction(param, it, processRow, key); - }); + }) + //@ts-ignore + Reflect.ownKeys(asyncCat).map((key: any) => { + //@ts-ignore + let param: Array = asyncCat[key]; + if (flag) {//处理business + this.makeAddAsyncFunction(param, it, processRow, key); + } else {//处理thread + this.makeAddAsyncFunction(param, it, processRow, key, param[0].tid); + } + }) } else { //不聚合异步trace let asyncFuncGroup = Utils.groupBy(asyncFuncList, 'funName'); @@ -1438,7 +1446,8 @@ export class SpProcessChart { asyncFunctions: unknown[], it: { pid: number; processName: string | null }, processRow: TraceRow, - key: string + key: string, + rowSingleTid?: number ): void { let maxDepth: number = -1; let i = 0; @@ -1497,7 +1506,7 @@ export class SpProcessChart { this.toAsyncFuncCache(noEndData[index], `${key}-${it.pid}`); }); } - this.lanesConfig([...normalData, ...noEndData], it, processRow, key); + this.lanesConfig([...normalData, ...noEndData], it, processRow, key, rowSingleTid); } } //初始化异步泳道信息 @@ -1505,7 +1514,8 @@ export class SpProcessChart { asyncFunctions: unknown[], it: { pid: number; processName: string | null }, processRow: TraceRow, - key: string + key: string, + rowSingleTid?: number ): void { const maxHeight = this.calMaxHeight(asyncFunctions); // @ts-ignore @@ -1515,6 +1525,7 @@ export class SpProcessChart { funcRow.rowId = `${key}-${it.pid}`; funcRow.asyncFuncName = asyncFuncName; funcRow.asyncFuncNamePID = it.pid; + funcRow.asyncFuncStartTID = rowSingleTid ? rowSingleTid : undefined; funcRow.rowType = TraceRow.ROW_TYPE_FUNC; funcRow.enableCollapseChart(FOLD_HEIGHT, this.trace); //允许折叠泳道图 funcRow.rowParentId = `${it.pid}`; diff --git a/ide/src/trace/component/trace/base/TraceRow.ts b/ide/src/trace/component/trace/base/TraceRow.ts index db2c3a27b4a57a42c0aa1b538d6d0058e9a2c285..81d78d733d07e04d2e02fbd979c3ec33276704a2 100644 --- a/ide/src/trace/component/trace/base/TraceRow.ts +++ b/ide/src/trace/component/trace/base/TraceRow.ts @@ -212,6 +212,7 @@ export class TraceRow extends HTMLElement { currentContext: CanvasRenderingContext2D | undefined | null; static ROW_TYPE_LTPO: string | null | undefined; static ROW_TYPE_HITCH_TIME: string | null | undefined; + asyncFuncStartTID!: number | undefined; constructor( args: { diff --git a/ide/src/trace/component/trace/base/TraceSheet.ts b/ide/src/trace/component/trace/base/TraceSheet.ts index fd44ff5c58ee1c7b88717422a463a1b3f76905e0..ce1ba8744273d5b3e0ab817fefc412826520d71b 100644 --- a/ide/src/trace/component/trace/base/TraceSheet.ts +++ b/ide/src/trace/component/trace/base/TraceSheet.ts @@ -1165,10 +1165,9 @@ export class TraceSheet extends BaseElement { param.processId = this.selection!.processIds; param.threadId = this.selection!.funTids;//@ts-ignore2 param.name = e.detail.allName ? e.detail.allName : [e.detail.name];//@ts-ignore2 - param.asyncNames = e.detail.asyncNames;//@ts-ignore2 - param.asyncCatNames = e.detail.asyncCatNames; - param.isJumpPage = true; - (pane.children.item(0) as TabPaneSliceChild).data = param; + param.isJumpPage = true;// @ts-ignore + param.isSummary = e.detail.allName ? true : false; + (pane.children.item(0) as TabPaneSliceChild).data = {param: param, selection: this.selection}; } clearMemory(): void { diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneSliceChild.ts b/ide/src/trace/component/trace/sheet/process/TabPaneSliceChild.ts index 7daca5c594f63a681f128e11b5fbe337c00c7ed2..2116a2875cd5738bafd5527c88846a71463ba265 100644 --- a/ide/src/trace/component/trace/sheet/process/TabPaneSliceChild.ts +++ b/ide/src/trace/component/trace/sheet/process/TabPaneSliceChild.ts @@ -15,30 +15,49 @@ import { BaseElement, element } from '../../../../../base-ui/BaseElement'; import { LitTable } from '../../../../../base-ui/table/lit-table'; -import { SelectionData, SliceBoxJumpParam } from '../../../../bean/BoxSelection'; +import { SelectionData, SelectionParam, SliceBoxJumpParam } from '../../../../bean/BoxSelection'; import { Utils } from '../../base/Utils'; import { resizeObserver } from '../SheetUtils'; -import { getTabDetails, getCatDetails } from '../../../../database/sql/Func.sql'; +import { getTabDetails, getGhDetails, getSfDetails } from '../../../../database/sql/Func.sql'; @element('box-slice-child') export class TabPaneSliceChild extends BaseElement { private sliceChildTbl: LitTable | null | undefined; - private boxChildSource: Array = []; - private sliceChildParam: SliceBoxJumpParam | null | undefined; + private boxChildSource: Array = []; + private sliceChildParam: {param: SliceBoxJumpParam, selection: SelectionParam} | null | undefined; - set data(boxChildValue: SliceBoxJumpParam) { + set data(boxChildValue: {param: SliceBoxJumpParam, selection: SelectionParam | null | undefined}) { //切换Tab页 保持childTab数据不变 除非重新点击跳转 - if (boxChildValue === this.sliceChildParam || !boxChildValue.isJumpPage) { + if (boxChildValue === this.sliceChildParam || !boxChildValue.param.isJumpPage) { return; } // @ts-ignore this.sliceChildParam = boxChildValue; this.sliceChildTbl!.recycleDataSource = []; - this.getDataByDB(boxChildValue); + //合并SF异步信息,相同pid和tid的name + let sfAsyncFuncMap:Map = new Map(); + let filterSfAsyncFuncName = boxChildValue.selection!.funAsync; + if (!boxChildValue.param.isSummary!) { + filterSfAsyncFuncName = filterSfAsyncFuncName.filter((item) => item.name === boxChildValue.param.name![0]) + } + filterSfAsyncFuncName.forEach((it: { name: string; pid: number, tid: number | undefined }) => { + if (sfAsyncFuncMap.has(`${it.pid}-${it.tid}`)) { + let item = sfAsyncFuncMap.get(`${it.pid}-${it.tid}`); + item?.name.push(it.name); + } else { + sfAsyncFuncMap.set(`${it.pid}-${it.tid}`, { + name: [it.name], + pid: it.pid, + tid: it.tid + }) + } + }) + //@ts-ignore + this.getDataByDB(boxChildValue, sfAsyncFuncMap, boxChildValue.selection!.funCatAsync); } initElements(): void { - this.sliceChildTbl = this.shadowRoot?.querySelector('#tb-slice-child'); + this.sliceChildTbl = this.shadowRoot?.querySelector('#tb-slice-child'); this.sliceChildTbl!.addEventListener('column-click', (evt): void => { // @ts-ignore this.sortByColumn(evt.detail); @@ -63,43 +82,71 @@ export class TabPaneSliceChild extends BaseElement { resizeObserver(this.parentElement!, this.sliceChildTbl!, 25); } - getDataByDB(val: SliceBoxJumpParam): void { - this.sliceChildTbl!.loading = true; - //处理异步方法 - getTabDetails(val.name!, val.processId, val.leftNs, val.rightNs, 'async').then((res1: unknown) => {//@ts-ignore - //处理cat方法 - getCatDetails(val.name!, val.asyncCatNames!, val.processId, val.leftNs, val.rightNs).then((res2) => {//@ts-ignore - //处理同步方法 - getTabDetails(val.name!, val.processId, val.leftNs, val.rightNs, 'sync', val.threadId).then( - (res3: unknown) => {//@ts-ignore - let result: unknown = (res1 || []).concat(res2 || []).concat(res3 || []); - this.sliceChildTbl!.loading = false;//@ts-ignore - if (result.length !== null && result.length > 0) {//@ts-ignore - result.map((e: unknown) => {//@ts-ignore - e.startTime = Utils.getTimeString(e.startNs); - // @ts-ignore - e.absoluteTime = ((window as unknown).recordStartNS + e.startNs) / 1000000000;//@ts-ignore - e.duration = e.duration / 1000000;//@ts-ignore - e.state = Utils.getEndState(e.state)!;//@ts-ignore - e.processName = `${e.process === undefined || e.process === null ? 'process' : e.process}(${e.processId})`;//@ts-ignore - e.threadName = `${e.thread === undefined || e.thread === null ? 'thread' : e.thread}(${e.threadId})`; - });//@ts-ignore - this.boxChildSource = result; - if (this.sliceChildTbl) { - // @ts-ignore - this.sliceChildTbl.recycleDataSource = result; - } - } else { - this.boxChildSource = []; - if (this.sliceChildTbl) { - // @ts-ignore - this.sliceChildTbl.recycleDataSource = []; - } - } - } - ); + getDataByDB( + val: {param: SliceBoxJumpParam, selection: SelectionParam}, + sfAsyncFuncMap: Map, + ghAsyncFunc:{ threadName: string; pid: number}[]): void { + //获取点击跳转,SF异步Func数据 + let result1 = () => { + let promises: unknown[] = []; + sfAsyncFuncMap.forEach(async (item: { name: string[]; pid: number, tid: number | undefined }) => { + let res = await getSfDetails(item.name, item.pid, item.tid, val.param.leftNs, val.param.rightNs); + if (res !== undefined && res.length > 0) { + promises.push(...res); + } + }) + return promises + } + + //获取点击跳转,GH异步Func数据 + let result2 = () => { + let promises: unknown[] = []; + ghAsyncFunc.forEach(async (item: { pid: number; threadName: string }) => { + let res = await getGhDetails(val.param.name!, item.threadName, item.pid, val.param.leftNs, val.param.rightNs); + if (res !== undefined && res.length > 0) { + promises.push(...res); + } }); - }); + return promises + } + + //获取同步Func数据,同步Func数据 + let result3 = async () => { + let promises: unknown[] = []; + let res = await getTabDetails(val.param.name!, val.param.processId, val.param.threadId, val.param.leftNs, val.param.rightNs); + if (res !== undefined && res.length > 0) { + promises.push(...res); + } + return promises + } + this.sliceChildTbl!.loading = true; + Promise.all([result1(), result2(), result3()]).then(res => { + this.sliceChildTbl!.loading = false; + let result: any = (res[0] || []).concat(res[1] || []).concat(res[2] || []); + this.sliceChildTbl!.loading = false; + if (result.length !== null && result.length > 0) { + result.map((e: any) => { + e.startTime = Utils.getTimeString(e.startNs); + // @ts-ignore + e.absoluteTime = ((window as unknown).recordStartNS + e.startNs) / 1000000000; + e.duration = e.duration / 1000000; + e.state = Utils.getEndState(e.state)!; + e.processName = `${e.process === undefined || e.process === null ? 'process' : e.process}[${e.processId}]`; + e.threadName = `${e.thread === undefined || e.thread === null ? 'thread' : e.thread}[${e.threadId}]`; + }); + this.boxChildSource = result; + if (this.sliceChildTbl) { + // @ts-ignore + this.sliceChildTbl.recycleDataSource = result; + } + } else { + this.boxChildSource = []; + if (this.sliceChildTbl) { + // @ts-ignore + this.sliceChildTbl.recycleDataSource = []; + } + } + }) } initHtml(): string { @@ -152,8 +199,8 @@ export class TabPaneSliceChild extends BaseElement { }; } //@ts-ignore - if (detail.key === 'startTime' || detail.key === 'processName' || detail.key === 'threadName' || //@ts-ignore - detail.key === 'name') { + if (detail.key === 'startTime' || detail.key === 'processName'|| detail.key === 'threadName' ||//@ts-ignore + detail.key === 'name') { // @ts-ignore this.boxChildSource.sort(compare(detail.key, detail.sort, 'string'));// @ts-ignore } else if (detail.key === 'absoluteTime' || detail.key === 'duration') {// @ts-ignore diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneSlices.ts b/ide/src/trace/component/trace/sheet/process/TabPaneSlices.ts index 11ac0d06f9c38ec2a20a895ef61b85c5a31f4306..2790e37f8e9c5c7a0078bcdc8cfacd84d73c1432 100644 --- a/ide/src/trace/component/trace/sheet/process/TabPaneSlices.ts +++ b/ide/src/trace/component/trace/sheet/process/TabPaneSlices.ts @@ -33,7 +33,7 @@ export class TabPaneSlices extends BaseElement { private currentSelectionParam: SelectionParam | undefined; private sliceSearchCount: Element | undefined | null; - set data(slicesParam: SelectionParam | unknown) { + set data(slicesParam: SelectionParam) { if (this.currentSelectionParam === slicesParam) { return; } //@ts-ignore @@ -42,20 +42,22 @@ export class TabPaneSlices extends BaseElement { //@ts-ignore ((slicesParam.rightNs - slicesParam.leftNs) / 1000000.0).toFixed(5) )} ms`; - let asyncNames: Array = []; - let asyncPid: Array = []; //@ts-ignore - slicesParam.funAsync.forEach((it: unknown) => { - //@ts-ignore - asyncNames.push(it.name); //@ts-ignore - asyncPid.push(it.pid); - }); - let asyncCatNames: Array = []; - let asyncCatPid: Array = [];//@ts-ignore - slicesParam.funCatAsync.forEach((it: unknown) => { //@ts-ignore - asyncCatNames.push(it.threadName);//@ts-ignore - asyncCatPid.push(it.pid); - }); - this.slicesTbl!.loading = true; + + //合并SF异步信息,相同pid和tid的name + let sfAsyncFuncMap: Map = new Map(); + slicesParam.funAsync.forEach((it: { name: string; pid: number, tid: number | undefined }) => { + if (sfAsyncFuncMap.has(`${it.pid}-${it.tid}`)) { + let item = sfAsyncFuncMap.get(`${it.pid}-${it.tid}`); + item?.name.push(it.name); + } else { + sfAsyncFuncMap.set(`${it.pid}-${it.tid}`, { + name: [it.name], + pid: it.pid, + tid: it.tid + }) + } + }) + let filterNameEL: HTMLInputElement | undefined | null = this.shadowRoot?.querySelector('#filterName'); filterNameEL?.addEventListener('keyup', (ev) => { @@ -63,59 +65,8 @@ export class TabPaneSlices extends BaseElement { ev.stopPropagation(); } }); - //@ts-ignore - getTabSlicesAsyncFunc(asyncNames, asyncPid, slicesParam.leftNs, slicesParam.rightNs).then((res) => {//@ts-ignore - getTabSlicesAsyncCatFunc(asyncCatNames, asyncCatPid, slicesParam.leftNs, slicesParam.rightNs).then((res1) => { - //@ts-ignore - getTabSlices(slicesParam.funTids, slicesParam.processIds, slicesParam.leftNs, slicesParam.rightNs).then( - (res2) => { - this.slicesTbl!.loading = false; - let processSlicesResult = (res || []).concat(res1 || []).concat(res2 || []); - if (processSlicesResult !== null && processSlicesResult.length > 0) { - let sumWall = 0.0; - let sumOcc = 0; - for (let processSliceItem of processSlicesResult) { - //@ts-ignore - processSliceItem.name = processSliceItem.name === null ? '' : processSliceItem.name; - //@ts-ignore - processSliceItem.tabTitle = processSliceItem.name; - //@ts-ignore - sumWall += processSliceItem.wallDuration; - //@ts-ignore - sumOcc += processSliceItem.occurrences; - //@ts-ignore - processSliceItem.wallDuration = parseFloat((processSliceItem.wallDuration / 1000000.0).toFixed(5)); - //@ts-ignore - processSliceItem.avgDuration = parseFloat((processSliceItem.avgDuration / 1000000.0).toFixed(5)); - //@ts-ignore - processSliceItem.asyncNames = asyncNames; - //@ts-ignore - processSliceItem.asyncCatNames = asyncCatNames; - } - let count = new SelectionData(); - count.process = ' '; - count.wallDuration = parseFloat((sumWall / 1000000.0).toFixed(5)); - count.occurrences = sumOcc; - count.tabTitle = 'Summary';//@ts-ignore - count.allName = processSlicesResult.map((item: unknown) => item.name); - count.asyncNames = asyncNames; - count.asyncCatNames = asyncCatNames; - processSlicesResult.splice(0, 0, count); //@ts-ignore - this.slicesSource = processSlicesResult; - this.slicesTbl!.recycleDataSource = processSlicesResult; - this.sliceSearchCount!.textContent = this.slicesSource.length - 1 + ''; - if (filterNameEL && filterNameEL.value.trim() !== '') { - this.findName(filterNameEL.value); - } - } else { - this.slicesSource = []; - this.slicesTbl!.recycleDataSource = this.slicesSource; - this.sliceSearchCount!.textContent = '0'; - } - } - ); - }); - }); + + this.getSliceDb(slicesParam, filterNameEL, sfAsyncFuncMap, slicesParam.funCatAsync) } initElements(): void { @@ -158,6 +109,102 @@ export class TabPaneSlices extends BaseElement { spSystemTrace.focusTarget = ''; }); } + + getSliceDb( + slicesParam: SelectionParam, + filterNameEL: HTMLInputElement | undefined | null, + sfAsyncFuncMap: Map, + ghAsyncFunc: { threadName: string; pid: number }[]) { + //获取SF异步Func数据 + let result1 = () => { + let promises: unknown[] = []; + sfAsyncFuncMap.forEach(async (item: { name: string[]; pid: number, tid: number | undefined }) => { + let res = await getTabSlicesAsyncFunc(item.name, item.pid, item.tid, slicesParam.leftNs, slicesParam.rightNs); + if (res !== undefined && res.length > 0) { + promises.push(...res); + } + }) + return promises + } + + //获取GH异步Func数据 + let result2 = () => { + let promises: unknown[] = []; + ghAsyncFunc.forEach(async (item: { pid: number; threadName: string }) => { + let res = await getTabSlicesAsyncCatFunc(item.threadName, item.pid, slicesParam.leftNs, slicesParam.rightNs); + if (res !== undefined && res.length > 0) { + promises.push(...res); + } + }); + return promises + } + + //获取同步Func数据 + let result3 = async () => { + let promises: unknown[] = []; + let res = await getTabSlices(slicesParam.funTids, slicesParam.processIds, slicesParam.leftNs, slicesParam.rightNs); + if (res !== undefined && res.length > 0) { + promises.push(...res); + } + return promises + } + + this.slicesTbl!.loading = true; + Promise.all([result1(), result2(), result3()]).then(res => { + let processSlicesResult = (res[0] || []).concat(res[1] || []).concat(res[2] || []); + if (processSlicesResult !== null && processSlicesResult.length > 0) { + let sumWall = 0.0; + let sumOcc = 0; + let processSlicesResultMap: Map = new Map(); + for (let processSliceItem of processSlicesResult) { + //@ts-ignore + processSliceItem.name = processSliceItem.name === null ? '' : processSliceItem.name; + //@ts-ignore + sumWall += processSliceItem.wallDuration; + //@ts-ignore + sumOcc += processSliceItem.occurrences; + //@ts-ignore + processSliceItem.wallDuration = parseFloat((processSliceItem.wallDuration / 1000000.0).toFixed(5)); + //@ts-ignore + if (processSlicesResultMap.has(processSliceItem.name)) {//@ts-ignore + let item = processSlicesResultMap.get(processSliceItem.name); + //@ts-ignore + item.occurrences = item.occurrences + processSliceItem.occurrences; + //@ts-ignore + item.wallDuration = parseFloat((item.wallDuration + processSliceItem.wallDuration).toFixed(5)); + } else { + //@ts-ignore + processSlicesResultMap.set(processSliceItem.name, {//@ts-ignore + ...processSliceItem, //@ts-ignore + tabTitle: processSliceItem.name + }) + } + } + let processSlicesResultsValue = [...processSlicesResultMap.values()]; + processSlicesResultsValue.forEach(element => {//@ts-ignore + element.avgDuration = parseFloat((element.wallDuration / element.occurrences).toFixed(5)); + }); + let count = new SelectionData(); + count.process = ' '; + count.wallDuration = parseFloat((sumWall / 1000000.0).toFixed(5)); + count.occurrences = sumOcc; + count.tabTitle = 'Summary'; + count.allName = processSlicesResultsValue.map((item: any) => item.name); + processSlicesResultsValue.splice(0, 0, count); //@ts-ignore + this.slicesSource = processSlicesResultsValue; + this.slicesTbl!.recycleDataSource = processSlicesResultsValue; + this.sliceSearchCount!.textContent = this.slicesSource.length - 1 + ''; + if (filterNameEL && filterNameEL.value.trim() !== '') { + this.findName(filterNameEL.value); + } + } else { + this.slicesSource = []; + this.slicesTbl!.recycleDataSource = this.slicesSource; + this.sliceSearchCount!.textContent = '0'; + } + this.slicesTbl!.loading = false; + }); + } async orgnazitionData(data: Object): Promise { let spApplication = document.querySelector('body > sp-application'); let spSystemTrace = spApplication?.shadowRoot?.querySelector( diff --git a/ide/src/trace/database/sql/Func.sql.ts b/ide/src/trace/database/sql/Func.sql.ts index bb2d52bbf42f15f9ccf002d067bc3da01b4d546a..44d8f1dd971d1c3d6e4d46464a6f7286aa09f0aa 100644 --- a/ide/src/trace/database/sql/Func.sql.ts +++ b/ide/src/trace/database/sql/Func.sql.ts @@ -302,74 +302,56 @@ export const fuzzyQueryFuncRowData = (funcName: string, tIds: number): ); export const getTabSlicesAsyncFunc = ( - asyncNames: Array, - asyncPid: Array, + asyncNames: string[], + asyncPid: number, + asyncTid: number | undefined, leftNS: number, rightNS: number ): //@ts-ignore - Promise> => - query( - 'getTabSlicesAsyncFunc', - `SELECT + Promise> => { + let condition = `${asyncTid !== null && asyncTid !== undefined ? `and A.tid = ${asyncTid}` : ''}`; + let sql = ` + SELECT c.name AS name, sum( c.dur ) AS wallDuration, - avg( c.dur ) AS avgDuration, count( c.name ) AS occurrences - FROM - thread A, + FROM + (SELECT id, ts, parent_id, dur, name from callstack where cookie NOT NULL) C, trace_range D + LEFT JOIN thread A ON A.id = C.parent_id LEFT JOIN process P ON P.id = A.ipid - LEFT JOIN callstack C ON A.id = C.callid where - C.ts > 0 - and - c.dur >= -1 - and - c.cookie not null - and - P.pid in (${asyncPid.join(',')}) - and - c.name in (${asyncNames.map((it) => "'" + it + "'").join(',')}) - and - not ((C.ts - D.start_ts + C.dur < $leftNS) or (C.ts - D.start_ts > $rightNS)) - group by - c.name + C.ts > 0 + and + c.dur >= -1 + and + P.pid = ${asyncPid} + and + c.name in (${asyncNames.map((it) => "\"" + it + "\"").join(',')}) + and + not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) ${condition} + group by + c.name order by - wallDuration desc;`, - { $leftNS: leftNS, $rightNS: rightNS } - ); + wallDuration desc;`; + return query('getTabSlicesAsyncFunc', sql, {}); +} export const getTabDetails = ( asyncNames: Array, asyncPid: Array, + funTids: Array, leftNS: number, - rightNS: number, - key: string, - funTids?: Array + rightNS: number ): //@ts-ignore Promise> => { - let asyncCondition = ''; - let catCondition = ''; - let syncCondition = ''; - if (key === 'async') { - asyncCondition = ` - and c.cookie not null - and c.parent_id not null - `; - } else if (key === 'sync') { - syncCondition = ` + let condition = ` and A.tid in (${funTids!.join(',')}) and c.cookie is null - `; - } - let condition = ` - ${asyncCondition} - ${catCondition} - ${syncCondition} ${`and P.pid in (${asyncPid.join(',')})`} - ${`and c.name in (${asyncNames.map((it) => '\"' + it + '\"').join(',')})`} - `; - let sql = ` + ${`and c.name in (${asyncNames.map((it) => "\"" + it + "\"").join(',')})`} + ` + let sql = ` SELECT c.name AS name, c.dur AS duration, @@ -388,18 +370,55 @@ export const getTabDetails = ( c.dur >= -1 and not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) ${condition} - `; - return query('getTabDetails', sql, {}); -}; -export const getCatDetails = ( + ` + return query('getTabDetails', sql, {}); + } +export const getSfDetails = ( asyncNames: Array, - catName: Array, - asyncPid: Array, + asyncPid: number, + asyncTid: number | undefined, leftNS: number, rightNS: number ): //@ts-ignore Promise> => { - let sql = ` + let condition = ` + and c.parent_id not null + ${asyncTid !== null && asyncTid !== undefined ? `and A.tid = ${asyncTid}` : ''} + ${`and P.pid = ${asyncPid}`} + ${`and c.name in (${asyncNames.map((it) => "\"" + it + "\"").join(',')})`} + ` + let sql = ` + SELECT + c.name AS name, + c.dur AS duration, + P.pid AS processId, + P.name AS process, + A.tid AS threadId, + A.name AS thread, + c.ts - D.start_ts as startNs + FROM + (SELECT id, ts, parent_id, dur, name from callstack where cookie NOT NULL) C, + trace_range D + LEFT JOIN thread A ON A.id = C.parent_id + LEFT JOIN process P ON P.id = A.ipid + where + C.ts > 0 + and + c.dur >= -1 + and + not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) ${condition} + ` + return query('getSfDetails', sql, {}); + } + export const getGhDetails = ( + asyncNames: Array, + catName: string, + asyncPid: number, + leftNS: number, + rightNS: number + ): //@ts-ignore + Promise> => { + let sql = ` SELECT c.name AS name, c.dur AS duration, @@ -423,53 +442,54 @@ export const getCatDetails = ( and c.parent_id is null and - P.pid in (${asyncPid.join(',')}) + P.pid = ${asyncPid} and - c.cat in (${catName.map((it) => '\"' + it + '\"').join(',')}) + cat = '${catName}' and - c.name in (${asyncNames.map((it) => '\"' + it + '\"').join(',')}) + c.name in (${asyncNames.map((it) => "\"" + it + "\"").join(',')}) and not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) - `; - return query('getCatDetails', sql, {}); -}; + ` + return query('getGhDetails', sql, {}); + } export const getTabSlicesAsyncCatFunc = ( - asyncCatNames: Array, - asyncCatPid: Array, + asyncCatNames: string, + asyncCatPid: number, leftNS: number, rightNS: number ): Promise> => - query( - 'getTabSlicesAsyncCatFunc', - ` - select - c.name as name, - sum(c.dur) as wallDuration, - avg(c.dur) as avgDuration, - count(c.name) as occurrences - from - thread A, trace_range D - left join process P on P.id = A.ipid - left join callstack C on A.id = C.callid - where - C.ts > 0 - and - c.dur >= -1 - and - c.cookie not null - and - c.cat not null - and - P.pid in (${asyncCatPid.join(',')}) - and - c.cat in (${asyncCatNames.map((it) => "'" + it + "'").join(',')}) - and - not ((C.ts - D.start_ts + C.dur < $leftNS) or (C.ts - D.start_ts > $rightNS)) - group by - c.name - order by - wallDuration desc;`, - { $leftNS: leftNS, $rightNS: rightNS } +query( + 'getTabSlicesAsyncCatFunc', + ` + select + c.name as name, + sum(c.dur) as wallDuration, + count(c.name) as occurrences + from + thread A, trace_range D + left join process P on P.id = A.ipid + left join callstack C on A.id = C.callid + where + C.ts > 0 + and + c.dur >= -1 + and + c.cookie not null + and + c.cat not null + and + c.parent_id is null + and + P.pid = ${asyncCatPid} + and + c.cat = '${asyncCatNames}' + and + not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) + group by + c.name + order by + wallDuration desc;`, + { $leftNS: leftNS, $rightNS: rightNS } ); export const querySearchFunc = (search: string): Promise> => diff --git a/ide/src/trace/database/sql/ProcessThread.sql.ts b/ide/src/trace/database/sql/ProcessThread.sql.ts index e02ccd36ed291184943afe8e9f463ce05eaabc89..5bd293421c049b5f090a25d71b7592ce00179207 100644 --- a/ide/src/trace/database/sql/ProcessThread.sql.ts +++ b/ide/src/trace/database/sql/ProcessThread.sql.ts @@ -1146,15 +1146,13 @@ export const getTabSlices = ( pids: Array, leftNS: number, rightNS: number -): //@ts-ignore - Promise> => +): Promise> => query( 'getTabSlices', ` select c.name as name, sum(c.dur) as wallDuration, - avg(c.dur) as avgDuration, count(c.name) as occurrences from thread T, trace_range TR