1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15import { query } from '../SqlLite'; 16import { FuncStruct } from '../ui-worker/ProcedureWorkerFunc'; 17import { SearchFuncBean } from '../../bean/SearchFuncBean'; 18import { SelectionData } from '../../bean/BoxSelection'; 19import { HeapTraceFunctionInfo } from '../../../js-heap/model/DatabaseStruct'; 20import { FunctionItem } from '../../bean/BinderProcessThread'; 21import { StateGroup } from '../../bean/StateModle'; 22import { FuncNameCycle } from '../../bean/BinderProcessThread'; 23import { Utils } from '../../component/trace/base/Utils'; 24 25export const queryFuncNameCycle = ( 26 funcName: string, 27 tIds: string, 28 leftNS: number, 29 rightNS: number 30): Promise<Array<FunctionItem>> => 31 query( 32 'queryFuncNameCycle', 33 ` 34 SELECT 35 c.ts - r.start_ts AS cycleStartTime, 36 c.dur, 37 c.id, 38 t.tid, 39 p.pid 40 FROM 41 callstack c, trace_range r 42 LEFT JOIN 43 thread t 44 ON 45 c.callid = t.id 46 LEFT JOIN 47 process p 48 ON 49 t.ipid = p.id 50 WHERE 51 c.name like '${funcName}%' 52 AND 53 t.tid = ${tIds} 54 AND NOT 55 ((cycleStartTime < ${leftNS}) 56 OR 57 ((c.ts - r.start_ts + c.dur) > ${rightNS})) 58 `, 59 { 60 $funcName: funcName, 61 $tIds: tIds, 62 $leftNS: leftNS, 63 $rightNS: rightNS, 64 }, 65 { traceId: Utils.currentSelectTrace } 66 ); 67 68export const querySingleFuncNameCycle = ( 69 funcName: string, 70 tIds: string, 71 leftNS: number, 72 rightNS: number 73): Promise<Array<FunctionItem>> => 74 query( 75 'querySingleFuncNameCycle', 76 ` 77 SELECT 78 c.name AS funcName, 79 c.ts - r.start_ts AS cycleStartTime, 80 c.dur AS cycleDur, 81 c.id, 82 t.tid, 83 p.pid, 84 c.ts - r.start_ts + c.dur AS endTime 85 FROM 86 callstack c, trace_range r 87 LEFT JOIN 88 thread t 89 ON 90 c.callid = t.id 91 LEFT JOIN 92 process p 93 ON 94 t.ipid = p.id 95 WHERE 96 c.name = '${funcName}' 97 AND 98 t.tid = ${tIds} 99 AND NOT 100 ((cycleStartTime < ${leftNS}) 101 OR 102 (endTime > ${rightNS})) 103 `, 104 { 105 $funcName: funcName, 106 $tIds: tIds, 107 $leftNS: leftNS, 108 $rightNS: rightNS, 109 } 110 ); 111 112export const queryAllFuncNames = async (traceId?: string): Promise<Array<unknown>> => { 113 let list = await query( 114 'queryIsColorIndex', 115 `select 116 colorIndex 117 from 118 callstack 119 limit 1;`, 120 {}, 121 { traceId: traceId, action: 'exec-buf' } 122 ); 123 let isColorIndex = list.length !== 0 ? true : false; 124 let colorIndexStr = isColorIndex ? ',colorIndex' : ''; 125 let allFuncNamesBuffer = await query( 126 'queryAllFuncNames', 127 `select 128 id, 129 name 130 ${colorIndexStr} 131 from 132 callstack;`, 133 {}, 134 { traceId: traceId, action: 'exec-buf' } 135 ); 136 // @ts-ignore 137 return Utils.convertJSON(allFuncNamesBuffer); 138}; 139 140export const queryProcessAsyncFunc = ( 141 traceRange: { 142 startTs: number; 143 endTs: number; 144 }, 145 traceId?: string 146): //@ts-ignore 147 Promise<Array<unknown>> => 148 query( 149 'queryProcessAsyncFunc', 150 `SELECT 151 A.tid, 152 P.pid, 153 c.ts-${traceRange.startTs} as startTs, 154 c.dur, 155 c.cat, 156 c.id, 157 c.depth, 158 c.argsetid, 159 c.cookie 160 FROM 161 (SELECT id, ts, parent_id, dur, depth, argsetid, cookie, cat from callstack where cookie NOT NULL) c 162 LEFT JOIN thread A ON A.id = c.parent_id 163 LEFT JOIN process P ON P.id = A.ipid 164 WHERE 165 startTs NOT NULL;`, 166 {}, 167 { traceId: traceId } 168 ); 169 170export const queryProcessAsyncFuncCat = ( 171 traceRange: { 172 startTs: number; 173 endTs: number; 174 } 175): Promise<Array<unknown>> => 176 query( 177 'queryProcessAsyncFuncCat', 178 ` 179 select 180 A.tid, 181 P.pid, 182 c.cat as threadName, 183 c.name as funName, 184 c.ts-${traceRange.startTs} as startTs, 185 c.dur, 186 c.depth, 187 c.cookie 188 from 189 (select callid, name, ts, dur, cat, depth, cookie, parent_id from callstack where cookie not null and cat not null and parent_id is null) C 190 left join 191 thread A on A.id = C.callid 192 left join 193 process P on P.id = A.ipid 194 where 195 startTs not null 196 order by cat; 197 `, 198 {} 199 ); 200 201export const getMaxDepthByTid = (traceId?: string): //@ts-ignore 202 Promise<Array<unknown>> => 203 query( 204 'getMaxDepthByTid', 205 `SELECT 206 tid, 207 ipid, 208 maxDepth 209 FROM 210 thread T 211 LEFT JOIN ( 212 SELECT 213 callid, 214 MAX( c.depth + 1 ) AS maxDepth 215 FROM 216 callstack C 217 WHERE 218 c.ts IS NOT NULL 219 AND c.cookie IS NULL 220 GROUP BY 221 callid 222 ) C ON T.id = C.callid 223 WHERE 224 maxDepth NOT NULL`, 225 {}, 226 { traceId: traceId } 227 ); 228 229export const querySearchFuncData = ( 230 funcName: string, 231 tIds: number, 232 leftNS: number, 233 rightNS: number 234): Promise<Array<SearchFuncBean>> => 235 query( 236 'querySearchFuncData', 237 `select 238 c.ts - r.start_ts as startTime, 239 c.dur 240 from 241 callstack c 242 left join 243 thread t 244 on 245 c.callid = t.id 246 left join 247 process p 248 on 249 t.ipid = p.id 250 left join 251 trace_range r 252 where 253 c.name like '${funcName}%' 254 and 255 t.tid = ${tIds} 256 and 257 not ((startTime < ${leftNS}) or (startTime > ${rightNS})); 258 ` 259 ); 260 261export const queryFuncRowData = (funcName: string, tIds: number): Promise<Array<SearchFuncBean>> => 262 query( 263 'queryFuncRowData', 264 `select 265 c.name as funName, 266 c.ts - r.start_ts as startTime, 267 t.tid as tid 268 from 269 callstack c 270 left join 271 thread t 272 on 273 c.callid = t.id 274 left join 275 process p 276 on 277 t.ipid = p.id 278 left join 279 trace_range r 280 where 281 c.name like '${funcName}%' 282 and 283 t.tid = ${tIds} 284 `, 285 { $search: funcName } 286 ); 287 288export const fuzzyQueryFuncRowData = (funcName: string, tIds: number): 289 Promise<Array<SearchFuncBean>> => 290 query( 291 'fuzzyQueryFuncRowData', 292 `select 293 c.name as funName, 294 c.ts - r.start_ts as startTime, 295 c.ts - r.start_ts + c.dur as endTime, 296 t.tid as tid 297 from 298 callstack c 299 left join 300 thread t 301 on 302 c.callid = t.id 303 left join 304 process p 305 on 306 t.ipid = p.id 307 left join 308 trace_range r 309 where 310 c.name like '%${funcName}%' 311 and 312 t.tid = ${tIds} 313 `, 314 { $search: funcName } 315 ); 316 317export const getTabSlicesAsyncFunc = ( 318 asyncNames: string[], 319 asyncPid: number, 320 asyncTid: number | undefined, 321 leftNS: number, 322 rightNS: number 323): //@ts-ignore 324 Promise<Array<unknown>> => { 325 let condition = `${asyncTid !== null && asyncTid !== undefined ? `and A.tid = ${asyncTid}` : ''}`; 326 let sql = ` 327 SELECT 328 c.name AS name, 329 sum( c.dur ) AS wallDuration, 330 count( c.name ) AS occurrences 331 FROM 332 (SELECT id, ts, parent_id, dur, name from callstack where cookie NOT NULL) C, 333 trace_range D 334 LEFT JOIN thread A ON A.id = C.parent_id 335 LEFT JOIN process P ON P.id = A.ipid 336 where 337 C.ts > 0 338 and 339 c.dur >= -1 340 and 341 P.pid = ${asyncPid} 342 and 343 c.name in (${asyncNames.map((it) => '\"' + it + '\"').join(',')}) 344 and 345 not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) ${condition} 346 group by 347 c.name 348 order by 349 wallDuration desc;`; 350 return query<SelectionData>('getTabSlicesAsyncFunc', sql, {}); 351}; 352 353export const getTabDetails = ( 354 asyncNames: Array<string>, 355 asyncPid: Array<number>, 356 funTids: Array<number>, 357 leftNS: number, 358 rightNS: number 359): //@ts-ignore 360 Promise<Array<unknown>> => { 361 let condition = ` 362 and A.tid in (${funTids!.join(',')}) 363 and c.cookie is null 364 ${`and P.pid in (${asyncPid.join(',')})`} 365 ${`and c.name in (${asyncNames.map((it) => '\"' + it + '\"').join(',')})`} 366 `; 367 let sql = ` 368 SELECT 369 c.name AS name, 370 c.dur AS duration, 371 P.pid AS processId, 372 P.name AS process, 373 A.tid AS threadId, 374 A.name AS thread, 375 c.ts - D.start_ts as startNs 376 FROM 377 thread A,trace_range D 378 LEFT JOIN process P ON P.id = A.ipid 379 LEFT JOIN callstack C ON A.id = C.callid 380 where 381 C.ts > 0 382 and 383 c.dur >= -1 384 and 385 not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) ${condition} 386 `; 387 return query('getTabDetails', sql, {}); 388}; 389export const getSfDetails = ( 390 asyncNames: Array<string>, 391 asyncPid: number, 392 asyncTid: number | undefined, 393 leftNS: number, 394 rightNS: number 395): //@ts-ignore 396 Promise<Array<unknown>> => { 397 let condition = ` 398 and c.parent_id not null 399 ${asyncTid !== null && asyncTid !== undefined ? `and A.tid = ${asyncTid}` : ''} 400 ${`and P.pid = ${asyncPid}`} 401 ${`and c.name in (${asyncNames.map((it) => '\"' + it + '\"').join(',')})`} 402 `; 403 let sql = ` 404 SELECT 405 c.name AS name, 406 c.dur AS duration, 407 P.pid AS processId, 408 P.name AS process, 409 A.tid AS threadId, 410 A.name AS thread, 411 c.ts - D.start_ts as startNs 412 FROM 413 (SELECT id, ts, parent_id, dur, name from callstack where cookie NOT NULL) C, 414 trace_range D 415 LEFT JOIN thread A ON A.id = C.parent_id 416 LEFT JOIN process P ON P.id = A.ipid 417 where 418 C.ts > 0 419 and 420 c.dur >= -1 421 and 422 not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) ${condition} 423 `; 424 return query('getSfDetails', sql, {}); 425}; 426export const getGhDetails = ( 427 asyncNames: Array<string>, 428 catName: string, 429 asyncPid: number, 430 leftNS: number, 431 rightNS: number 432): //@ts-ignore 433 Promise<Array<unknown>> => { 434 let sql = ` 435 SELECT 436 c.name AS name, 437 c.dur AS duration, 438 P.pid AS processId, 439 P.name AS process, 440 A.tid AS threadId, 441 A.name AS thread, 442 c.ts - D.start_ts as startNs 443 FROM 444 thread A,trace_range D 445 LEFT JOIN process P ON P.id = A.ipid 446 LEFT JOIN callstack C ON A.id = C.callid 447 where 448 C.ts > 0 449 and 450 c.dur >= -1 451 and 452 c.cookie not null 453 and 454 c.cat not null 455 and 456 c.parent_id is null 457 and 458 P.pid = ${asyncPid} 459 and 460 cat = '${catName}' 461 and 462 c.name in (${asyncNames.map((it) => '\"' + it + '\"').join(',')}) 463 and 464 not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) 465 `; 466 return query('getGhDetails', sql, {}); 467}; 468export const getTabSlicesAsyncCatFunc = ( 469 asyncCatNames: string, 470 asyncCatPid: number, 471 leftNS: number, 472 rightNS: number 473): Promise<Array<unknown>> => 474 query<SelectionData>( 475 'getTabSlicesAsyncCatFunc', 476 ` 477 select 478 c.name as name, 479 sum(c.dur) as wallDuration, 480 count(c.name) as occurrences 481 from 482 thread A, trace_range D 483 left join process P on P.id = A.ipid 484 left join callstack C on A.id = C.callid 485 where 486 C.ts > 0 487 and 488 c.dur >= -1 489 and 490 c.cookie not null 491 and 492 c.cat not null 493 and 494 c.parent_id is null 495 and 496 P.pid = ${asyncCatPid} 497 and 498 c.cat = '${asyncCatNames}' 499 and 500 not ((C.ts - D.start_ts + C.dur < ${leftNS}) or (C.ts - D.start_ts > ${rightNS})) 501 group by 502 c.name 503 order by 504 wallDuration desc;`, 505 { $leftNS: leftNS, $rightNS: rightNS } 506 ); 507 508export const querySearchFunc = (search: string): Promise<Array<SearchFuncBean>> => 509 query( 510 'querySearchFunc', 511 ` 512 select c.cookie, 513 c.id, 514 c.name as funName, 515 c.ts - r.start_ts as startTime, 516 c.dur, 517 c.depth, 518 t.tid, 519 t.name as threadName, 520 p.pid, 521 c.argsetid, 522 'func' as type 523 from callstack c left join thread t on c.callid = t.id left join process p on t.ipid = p.id 524 left join trace_range r 525 where c.name like '%${search}%' and startTime > 0 and cookie IS NULL; 526 `, 527 { $search: search }, 528 { traceId: Utils.currentSelectTrace } 529 ); 530 531export const querySceneSearchFunc = (search: string, processList: Array<string>): 532 Promise<Array<SearchFuncBean>> => 533 query( 534 'querySceneSearchFunc', 535 `select c.cookie, 536 c.id, 537 c.name as funName, 538 c.ts - r.start_ts as startTime, 539 c.dur, 540 c.depth, 541 t.tid, 542 t.name as threadName, 543 p.pid, 544 c.argsetid, 545 'func' as type 546 from callstack c left join thread t on c.callid = t.id left join process p on t.ipid = p.id 547 left join trace_range r 548 where c.name like '%${search}%' ESCAPE '\\' and startTime > 0 and p.pid in (${processList.join(',')}) 549 and cookie IS NULL; 550 `, 551 { $search: search }, 552 { traceId: Utils.currentSelectTrace } 553 ); 554 555export const queryHeapFunction = (fileId: number): Promise<Array<HeapTraceFunctionInfo>> => 556 query( 557 'queryHeapFunction', 558 `SELECT 559 function_index as index , 560 function_id as id , 561 name, 562 script_name as scriptName, 563 script_id as scriptId, 564 line, 565 column 566 FROM js_heap_trace_function_info WHERE file_id = ${fileId}` 567 ); 568 569export const queryHeapTraceNode = ( 570 fileId: number 571): //@ts-ignore 572 Promise<Array<unknown>> => 573 query( 574 'queryHeapTraceNode', 575 `SELECT F.name, 576 F.script_name as scriptName, 577 F.script_id as scriptId, 578 F.column, 579 F.line, 580 N.id, 581 N.function_info_index as functionInfoIndex, 582 N.parent_id as parentId, 583 N.count, 584 N.size, 585 IFNULL( S.live_count, 0 ) AS liveCount, 586 IFNULL( S.live_size, 0 ) AS liveSize 587 FROM 588 js_heap_trace_node N 589 LEFT JOIN ( 590 SELECT 591 trace_node_id as traceNodeId, 592 SUM( self_size ) AS liveSize, 593 count( * ) AS liveCount 594 FROM 595 js_heap_nodes 596 WHERE 597 file_id = ${fileId} 598 AND trace_node_id != 0 599 GROUP BY 600 trace_node_id 601 ) S ON N.id = S.trace_node_id 602 LEFT JOIN js_heap_trace_function_info F ON (F.file_id = N.file_id 603 AND F.function_index = N.function_info_index) 604 WHERE 605 N.file_id = ${fileId} 606 ORDER BY 607 N.id` 608 ); 609 610export const queryTaskPoolOtherRelationData = (ids: Array<number>, tid: number): 611 Promise<Array<FuncStruct>> => { 612 let sqlStr = `select 613 c.ts-D.start_ts as startTs, 614 c.dur, 615 c.name as funName, 616 c.argsetid, 617 c.depth, 618 c.id as id, 619 A.itid as itid, 620 A.ipid as ipid 621 from thread A,trace_range D 622 left join callstack C on A.id = C.callid 623 where startTs not null and c.cookie is null and tid = $tid and c.id in (${ids.join(',')})`; 624 return query('queryTaskPoolOtherRelationData', sqlStr, { $ids: ids, $tid: tid }); 625}; 626 627export const queryTaskPoolRelationData = (ids: Array<number>, tids: Array<number>): 628 Promise<Array<FuncStruct>> => { 629 let sqlStr = `select 630 c.ts-D.start_ts as startTs, 631 c.dur, 632 c.name as funName, 633 c.argsetid, 634 c.depth, 635 c.id as id, 636 A.itid as itid, 637 A.ipid as ipid 638 from thread A,trace_range D 639 left join callstack C on A.id = C.callid 640 where startTs not null and c.cookie is null and c.id in (${ids.join(',')}) and tid in (${tids.join( 641 ',' 642 )})`; 643 return query('queryTaskPoolRelationData', sqlStr, { $ids: ids, $tids: tids }); 644}; 645 646export const queryStatesCut = (tIds: Array<number>, leftNS: number, rightNS: number): 647 Promise<Array<StateGroup>> => 648 query<StateGroup>( 649 'queryBinderByThreadId', 650 ` 651 select 652 B.id, 653 B.pid, 654 B.tid, 655 B.dur, 656 B.cpu, 657 B.state, 658 B.ts - C.start_ts AS ts, 659 B.dur + B.ts as endTs 660 from 661 thread_state AS B,trace_range AS C 662 where 663 B.tid in (${tIds.join(',')}) 664 and 665 not ((B.ts + + ifnull(B.dur,0) < ($leftStartNs + C.start_ts)) 666 or (B.ts + B.dur > ($rightEndNs + C.start_ts))) 667 order by 668 B.pid; 669 `, 670 { 671 $tIds: tIds, 672 $leftStartNs: leftNS, 673 $rightEndNs: rightNS, 674 } 675 ); 676 677export const queryLoopFuncNameCycle = ( 678 funcName: string, 679 tIds: string, 680 leftNS: number, 681 rightNS: number 682): Promise<Array<FuncNameCycle>> => 683 query( 684 'queryLoopFuncNameCycle', 685 ` 686 SELECT 687 c.name AS funcName, 688 c.ts - r.start_ts AS cycleStartTime, 689 0 AS cycleDur, 690 c.id, 691 t.tid, 692 p.pid 693 FROM 694 callstack c, trace_range r 695 LEFT JOIN 696 thread t 697 ON 698 c.callid = t.id 699 LEFT JOIN 700 process p 701 ON 702 t.ipid = p.id 703 WHERE 704 c.name like '${funcName}%' 705 AND 706 t.tid = ${tIds} 707 AND NOT 708 ((cycleStartTime < ${leftNS}) 709 OR 710 (cycleStartTime > ${rightNS})) 711 `, 712 { 713 $funcName: funcName, 714 $tIds: tIds, 715 $leftNS: leftNS, 716 $rightNS: rightNS, 717 } 718 ); 719 720export const querySingleFuncNameCycleStates = ( 721 funcName: string, 722 tIds: string, 723 leftNS: number, 724 rightNS: number 725): Promise<Array<FuncNameCycle>> => 726 query( 727 'querySingleFuncNameCycle', 728 ` 729 SELECT 730 c.name AS funcName, 731 c.ts - r.start_ts AS cycleStartTime, 732 c.dur AS cycleDur, 733 c.id, 734 t.tid, 735 p.pid, 736 c.ts - r.start_ts + c.dur AS endTime 737 FROM 738 callstack c, trace_range r 739 LEFT JOIN 740 thread t 741 ON 742 c.callid = t.id 743 LEFT JOIN 744 process p 745 ON 746 t.ipid = p.id 747 WHERE 748 c.name like '${funcName}%' 749 AND 750 t.tid = ${tIds} 751 AND NOT 752 ((cycleStartTime < ${leftNS}) 753 OR 754 (endTime > ${rightNS})) 755 `, 756 { 757 $funcName: funcName, 758 $tIds: tIds, 759 $leftNS: leftNS, 760 $rightNS: rightNS, 761 } 762 ); 763