1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15//  VM Tracker Gpu Memory泳道图
16import type { SnapshotStruct } from '../ui-worker/ProcedureWorkerSnapshot';
17import { query } from '../SqlLite';
18import { GpuMemory, GpuMemoryComparison } from '../../bean/AbilityMonitor';
19import type { MemoryConfig } from '../../bean/MemoryConfig';
20
21export const queryGpuMemoryData = (processId: number): Promise<Array<SnapshotStruct>> =>
22  query(
23    'queryGpuMemorySampsData',
24    `SELECT
25    (A.ts - B.start_ts) as startNs,
26    sum(A.used_gpu_size) as value,
27    A.ipid as ipid
28    FROM memory_process_gpu A,trace_range B
29    WHERE
30    $pid = A.ipid
31    AND A.ts < B.end_ts
32    GROUP by A.ts;`,
33    { $pid: processId }
34  );
35
36// 判断VM Tracker Gpu Memory泳道图是否有数据
37export const queryisExistsGpuMemoryData = (processId: number): Promise<Array<SnapshotStruct>> =>
38  query(
39    'queryisExistsGpuMemoryData',
40    `SELECT EXISTS (
41      SELECT 1
42      FROM memory_process_gpu A, trace_range B
43      WHERE $pid = A.ipid
44      AND A.ts < B.end_ts
45      GROUP BY A.ts
46   ) AS data_exists`,
47    { $pid: processId }
48  );
49
50//VM Tracker SkiaGpuMemory 框选
51export const getTabGpuMemoryData = (
52  leftNs: number,
53  rightNs: number,
54  processId: number,
55  dur: number
56): Promise<Array<GpuMemory>> =>
57  query<GpuMemory>(
58    'getTabGpuMemoryData',
59    `SELECT  
60      (S.ts-TR.start_ts) as startNs,
61      gpu_name_id as gpuNameId,
62      T.tid as threadId,
63      T.name as threadName,
64      MAX(S.used_gpu_size) as maxSize,
65      MIN(S.used_gpu_size) as minSize,
66      Avg(S.used_gpu_size) as avgSize
67      from trace_range as TR,memory_process_gpu as S
68      left join thread as T on T.itid=S.itid
69      where
70       $leftNS <= startNs + ${dur}
71      and
72      $rightNS >= startNs
73      and
74        $pid = S.ipid
75      group by gpu_name_id,threadId
76              `,
77    { $leftNS: leftNs, $rightNS: rightNs, $pid: processId }
78  );
79
80//VM Tracker SkiaGpuMemory 点选
81export const getTabGpuMemoryVMTrackerClickData = (startNs: number, processId: number):
82  Promise<Array<GpuMemory>> =>
83  query<GpuMemory>(
84    'getTabGpuMemoryVMTrackerClickData',
85    `SELECT
86    (S.ts-TR.start_ts) as startNs,
87    S.used_gpu_size as size,
88    T.tid as threadId,
89    T.name as threadName,
90    A.data as gpuName
91    from trace_range as TR,memory_process_gpu as S
92    left join thread as T on T.itid=S.itid
93    left join data_dict as A on A.id=S.gpu_name_id
94    WHERE
95    startNs = ${startNs}
96    AND
97    $pid = S.ipid
98              `,
99    { $startNs: startNs, $pid: processId }
100  );
101
102//VM Tracker Gpu Memory 点选比较
103export const getTabGpuMemoryVmTrackerComparisonData = (
104  startNs: number,
105  processId: number
106): Promise<Array<GpuMemoryComparison>> =>
107  query<GpuMemoryComparison>(
108    'getTabGpuMemoryVmTrackerComparisonData',
109    `SELECT
110    (S.ts-TR.start_ts) as startNs,
111    sum(S.used_gpu_size) as value,
112    T.tid as threadId,
113    T.name as threadName,
114    S.gpu_name_id as gpuNameId
115    from trace_range as TR,memory_process_gpu as S
116    left join thread as T on T.itid=S.itid
117    WHERE
118    startNs = ${startNs}
119    AND
120    $pid = S.ipid
121                `,
122    { $startNs: startNs, $pid: processId }
123  );
124
125export const queryMemFilterIdMaxValue = (): Promise<Array<{ filterId: number; maxValue: number }>> => {
126  return query(
127    'queryMemFilterIdMaxValue',
128    `select filter_id as filterId,max(value) maxValue from process_measure group by filter_id;`
129  );
130};
131
132export const getTabVirtualMemoryType = (startTime: number, endTime: number): Promise<Array<string>> =>
133  query(
134    'getTabVirtualMemoryType',
135    `
136    SELECT type from paged_memory_sample s,trace_range t
137     WHERE s.end_ts >= $startTime + t.start_ts 
138     and s.start_ts <= $endTime + t.start_ts 
139     group by type`,
140    { $startTime: startTime, $endTime: endTime }
141  );
142
143export const queryNativeMemoryRealTime = (): //@ts-ignore
144  Promise<Array<unknown>> =>
145  query(
146    'queryNativeMemoryRealTime',
147    `select cs.ts,cs.clock_name from datasource_clockid dc 
148    left join clock_snapshot cs on dc.clock_id = cs.clock_id 
149    where data_source_name = 'memory-plugin' or data_source_name = 'nativehook'
150`,
151    {}
152  );
153
154export const queryJsMemoryData = (): //@ts-ignore
155  Promise<Array<unknown>> => query('queryJsMemoryData',
156    'SELECT 1 WHERE EXISTS(SELECT 1 FROM js_heap_nodes)');
157
158export const queryVmTrackerShmData = (
159  iPid: number
160): //@ts-ignore
161  Promise<Array<unknown>> =>
162  query(
163    'queryVmTrackerShmData',
164    `SELECT (A.ts - B.start_ts) as startNs,
165      sum(A.size) as value 
166    FROM
167      memory_ashmem A,trace_range B 
168    where
169      A.ipid = ${iPid}
170      AND A.ts < B.end_ts
171    and
172      flag = 0
173    GROUP by A.ts`,
174    {}
175  );
176export const queryVmTrackerShmSelectionData = (
177  startNs: number,
178  ipid: number
179): //@ts-ignore
180  Promise<Array<unknown>> =>
181  query(
182    'queryVmTrackerShmSelectionData',
183    `SELECT (A.ts - B.start_ts) as startNS,A.ipid,
184             A.fd,A.size,A.adj,A.ashmem_name_id as name,
185             A.ashmem_id as id,A.time,A.purged,A.ref_count as count,
186             A.flag
187             FROM memory_ashmem A,trace_range B 
188             where startNS = ${startNs} and ipid = ${ipid};`,
189    {}
190  );
191export const queryMemoryConfig = async (): Promise<Array<MemoryConfig>> => {
192  let keyList = await query(
193    'queryIsColorIndex',
194    `select
195        key
196      from
197        trace_config`,
198    {},
199  );
200  //@ts-ignore
201  let keySql = keyList && keyList.length > 0 && keyList.some(entry => entry.key === 'ipid') ? "AND key = 'ipid'" : '';
202  return query(
203    'queryMemoryConfiig',
204    `SELECT ipid as iPid, process.pid AS pid,
205    process.name AS processName,
206    (
207      SELECT value 
208      FROM trace_config 
209      WHERE trace_source = 'memory_config' AND key = 'sample_interval') AS interval
210  FROM
211    trace_config
212    LEFT JOIN process ON value = ipid
213  WHERE
214    trace_source = 'memory_config'
215    ${keySql}
216    ;`
217  );
218};
219
220// VM Tracker Purgeable泳道图
221export const queryPurgeableProcessData = (
222  ipid: number,
223  isPin?: boolean
224): //@ts-ignore
225  Promise<Array<unknown>> => {
226  const pinSql = isPin ? ' AND a.ref_count > 0' : '';
227  const names = isPin ? " ('mem.purg_pin')" : "('mem.purg_sum')";
228  return query(
229    'queryPurgeableProcessData',
230    `SELECT startNs, sum( value ) AS value 
231    FROM
232        (SELECT
233            m.ts - tr.start_ts AS startNs,
234            sum(m.value) AS value
235        FROM
236            process_measure m,
237            trace_range tr
238            LEFT JOIN process_measure_filter f ON f.id = m.filter_id
239        WHERE
240            m.ts < tr.end_ts
241            AND f.name = ${names}
242            AND f.ipid = ${ipid}
243        GROUP BY m.ts
244        UNION ALL
245        SELECT
246            a.ts - tr.start_ts AS startNs,
247            sum( a.pss ) AS value 
248        FROM
249            memory_ashmem a,
250            trace_range tr 
251        WHERE
252            a.ts < tr.end_ts
253            AND a.flag = 0
254            AND a.ipid = ${ipid}
255            ${pinSql}
256            GROUP BY a.ts) 
257        GROUP BY startNs`
258  );
259};
260
261export const queryVirtualMemory = (): //@ts-ignore
262  Promise<Array<unknown>> =>
263  query('queryVirtualMemory',
264    `select 
265    id,
266    name 
267    from sys_event_filter where type='sys_virtual_memory_filter'`);
268
269export const queryVirtualMemoryData = (
270  filterId: number
271): //@ts-ignore
272  Promise<Array<unknown>> =>
273  query(
274    'queryVirtualMemoryData',
275    `select ts-${window.recordStartNS} as startTime,value,filter_id as filterID 
276    from sys_mem_measure where filter_id=$filter_id`,
277    { $filter_id: filterId }
278  );
279
280export const queryTraceMemory = (): Promise<
281  Array<{
282    maxNum: string;
283    minNum: string;
284    avgNum: string;
285    name: string;
286    processName: string;
287  }>
288> =>
289  query(
290    'queryTraceMemory',
291    `
292    select
293        max(value) as maxNum,
294        min(value) as minNum,
295        avg(value) as avgNum,
296        filter.name as name,
297        p.name as processName
298        from process_measure
299        left join process_measure_filter as filter on filter.id= filter_id
300        left join process as p on p.id = filter.ipid
301    where 
302    filter_id > 0 
303    and 
304    filter.name = 'mem.rss.anon' 
305    group by 
306    filter_id 
307    order by 
308    avgNum desc`
309  );
310
311export const queryTraceMemoryTop = (): Promise<
312  Array<{
313    maxNum: string;
314    minNum: string;
315    avgNum: string;
316    name: string;
317    processName: string;
318  }>
319> =>
320  query(
321    'queryTraceMemoryTop',
322    `
323    select
324        max(value) as maxNum,
325        min(value) as minNum,
326        avg(value) as avgNum,
327        f.name as name,
328        p.name as processName
329        from process_measure
330        left join process_measure_filter as f on f.id= filter_id
331        left join process as p on p.id = f.ipid
332    where
333    filter_id > 0
334    and
335    f.name = 'mem.rss.anon'
336    group by
337    filter_id
338    order by
339    avgNum desc limit 10`
340  );
341
342export const queryTraceMemoryUnAgg = (): Promise<
343  Array<{
344    processName: string;
345    name: string;
346    value: string;
347    ts: string;
348  }>
349> =>
350  query(
351    'queryTraceMemoryUnAgg',
352    `
353    select
354        p.name as processName,
355        group_concat(filter.name) as name,
356        cast(group_concat(value) as varchar) as value,
357        cast(group_concat(ts) as varchar) as ts
358        from process_measure m
359        left join process_measure_filter as filter on filter.id= m.filter_id
360        left join process as p on p.id = filter.ipid
361        where 
362        filter.name = 'mem.rss.anon' 
363        or 
364        filter.name = 'mem.rss.file' 
365        or 
366        filter.name = 'mem.swap' 
367        or 
368        filter.name = 'oom_score_adj'
369    group by 
370    p.name,filter.ipid 
371    order by 
372    filter.ipid`
373  );
374
375export const queryMemoryMaxData = (
376  memoryName: string
377): //@ts-ignore
378  Promise<Array<unknown>> =>
379  query(
380    'queryMemoryMaxData',
381    `SELECT ifnull(max(m.value),0) as maxValue,
382            filter_id 
383            from sys_mem_measure m 
384            WHERE m.filter_id =
385            (SELECT id FROM sys_event_filter WHERE name = $memoryName)
386`,
387    { $memoryName: memoryName }
388  );
389
390export const getTabPaneVirtualMemoryStatisticsData = (
391  leftNs: number,
392  rightNs: number
393): //@ts-ignore
394  Promise<Array<unknown>> =>
395  query(
396    'getTabPaneVirtualMemoryStatisticsData',
397    `
398    select p.pid,
399       t.tid,
400       ifnull(p.name,'Process') as pname,
401       ifnull(t.name,'Thread') as tname,
402       f.type,
403       f.ipid,
404       f.itid,
405       count(f.ipid) as count,
406       sum(dur) as allDuration,
407       min(dur) as minDuration,
408       max(dur) as maxDuration,
409       avg(dur) as avgDuration
410    from paged_memory_sample as f 
411    left join process as p on f.ipid=p.ipid left join thread as t on f.itid=t.itid
412    where f.end_ts >= $leftNs
413    and f.start_ts <= $rightNs
414    group by f.type,f.ipid,f.itid
415    order by f.type;
416`,
417    { $leftNs: leftNs, $rightNs: rightNs }
418  );
419
420export const getFileSysVirtualMemoryChartData = (): //@ts-ignore
421  Promise<Array<unknown>> =>
422  query(
423    'getFileSysVirtualMemoryChartData',
424    `
425    select
426       (A.start_ts -B.start_ts) as startNS,
427       (A.end_ts - B.start_ts) as endNS,
428       dur as dur
429    from paged_memory_sample A,trace_range B
430    where startNS > 0
431    order by A.start_ts;`,
432    {}
433  );
434
435export const hasFileSysData = (): //@ts-ignore
436  Promise<Array<unknown>> =>
437  query(
438    'hasFileSysData',
439    `
440    select 
441        fsCount,
442        vmCount,
443        ioCount from
444        (select count(1) as fsCount from file_system_sample s,trace_range t where (s.start_ts between t.start_ts and t.end_ts) or (s.end_ts between t.start_ts and t.end_ts) )
445        ,(select count(1) as vmCount from paged_memory_sample s,trace_range t where (s.start_ts between t.start_ts and t.end_ts) or (s.end_ts between t.start_ts and t.end_ts) )
446        ,(select count(1) as ioCount from bio_latency_sample s,trace_range t where (s.start_ts between t.start_ts and t.end_ts) or (s.end_ts between t.start_ts and t.end_ts) );
447    `,
448    {}
449  );
450
451export const queryEbpfSamplesCount = (
452  startTime: number,
453  endTime: number,
454  ipids: number[]
455): //@ts-ignore
456  Promise<Array<unknown>> =>
457  query(
458    'queryEbpfSamplesCount',
459    `
460    select
461    fsCount,
462    vmCount 
463    from
464    (select count(1) as fsCount from file_system_sample s,trace_range t 
465    where s.end_ts between $startTime + t.start_ts and $endTime + t.start_ts ${ipids.length > 0 ? `and s.ipid in (${ipids.join(',')})` : ''
466    })
467,(select count(1) as vmCount from paged_memory_sample s,trace_range t 
468where s.end_ts between $startTime + t.start_ts and $endTime + t.start_ts ${ipids.length > 0 ? `and s.ipid in (${ipids.join(',')})` : ''
469    });
470`,
471    { $startTime: startTime, $endTime: endTime }
472  );
473
474export const queryisExistsShmData = (
475  iPid: number
476): //@ts-ignore
477  Promise<Array<unknown>> =>
478  query(
479    'queryisExistsShmData',
480    `SELECT EXISTS (
481        SELECT 1
482        FROM memory_ashmem A,trace_range B 
483        where A.ipid = ${iPid}
484        AND A.ts < B.end_ts
485        AND flag = 0
486        GROUP BY A.ts
487    ) AS data_exists`,
488    {}
489  );
490
491export const queryVmTrackerShmSizeData = (
492  leftNs: number,
493  rightNs: number,
494  iPid: number,
495  dur: number
496): //@ts-ignore
497  Promise<Array<unknown>> =>
498  query(
499    'queryVmTrackerShmSizeData',
500    `SELECT ( A.ts - B.start_ts ) AS startNS,
501        A.flag,
502        avg( A.size ) AS avg,
503        max( A.size ) AS max,
504        min( A.size ) AS min,
505        sum( A.size ) AS sum 
506      FROM
507        memory_ashmem A,
508        trace_range B 
509      WHERE 
510        startNS <= ${rightNs}  and (startNS+ ${dur}) >=${leftNs}
511        AND ipid = ${iPid}`,
512    {}
513  );
514
515export const queryisExistsPurgeableData = (
516  ipid: number,
517  isPin?: boolean
518): //@ts-ignore
519  Promise<Array<unknown>> => {
520  const pinSql = isPin ? ' AND a.ref_count > 0' : '';
521  const names = isPin ? " ('mem.purg_pin')" : "('mem.purg_sum')";
522  return query(
523    'queryisExistsPurgeableData',
524    `SELECT EXISTS (
525        SELECT 1
526        FROM
527          (SELECT 1
528          FROM
529              process_measure m,
530              trace_range tr
531              LEFT JOIN process_measure_filter f ON f.id = m.filter_id
532          WHERE
533              m.ts < tr.end_ts
534              AND f.name = ${names}
535              AND f.ipid = ${ipid}
536          UNION ALL
537          SELECT 1
538          FROM
539              memory_ashmem a,
540              trace_range tr
541          WHERE
542              a.ts < tr.end_ts
543              AND a.flag = 0
544              AND a.ipid = ${ipid}
545              ${pinSql})
546        ) AS data_exists`
547  );
548};
549