1fb726d48Sopenharmony_ci// Copyright (c) 2021 Huawei Device Co., Ltd.
2fb726d48Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
3fb726d48Sopenharmony_ci// you may not use this file except in compliance with the License.
4fb726d48Sopenharmony_ci// You may obtain a copy of the License at
5fb726d48Sopenharmony_ci//
6fb726d48Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
7fb726d48Sopenharmony_ci//
8fb726d48Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
9fb726d48Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
10fb726d48Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11fb726d48Sopenharmony_ci// See the License for the specific language governing permissions and
12fb726d48Sopenharmony_ci// limitations under the License.
13fb726d48Sopenharmony_ci
14fb726d48Sopenharmony_ciimport { TraficEnum } from './utils/QueryEnum';
15fb726d48Sopenharmony_ci
16fb726d48Sopenharmony_ciinterface SenderParam {
17fb726d48Sopenharmony_ci  params: {
18fb726d48Sopenharmony_ci    frame: { width: number };
19fb726d48Sopenharmony_ci    drawType: number;
20fb726d48Sopenharmony_ci    endNS: number;
21fb726d48Sopenharmony_ci    startNS: number;
22fb726d48Sopenharmony_ci    eventType: number;
23fb726d48Sopenharmony_ci    ipid: number;
24fb726d48Sopenharmony_ci    processes: number[];
25fb726d48Sopenharmony_ci    totalNS: number;
26fb726d48Sopenharmony_ci    trafic: TraficEnum;
27fb726d48Sopenharmony_ci    recordEndNS: number;
28fb726d48Sopenharmony_ci    recordStartNS: number;
29fb726d48Sopenharmony_ci    model: string;
30fb726d48Sopenharmony_ci    isCache: boolean;
31fb726d48Sopenharmony_ci  };
32fb726d48Sopenharmony_ci  id: string;
33fb726d48Sopenharmony_ci  action: string;
34fb726d48Sopenharmony_ci}
35fb726d48Sopenharmony_ci
36fb726d48Sopenharmony_ciinterface NativeMemoryCacheType {
37fb726d48Sopenharmony_ci  maxSize: number;
38fb726d48Sopenharmony_ci  minSize: number;
39fb726d48Sopenharmony_ci  maxDensity: number;
40fb726d48Sopenharmony_ci  minDensity: number;
41fb726d48Sopenharmony_ci  dataList: Array<NativeMemoryChartDataType>;
42fb726d48Sopenharmony_ci}
43fb726d48Sopenharmony_ci
44fb726d48Sopenharmony_ciclass NativeMemoryChartDataType {
45fb726d48Sopenharmony_ci  startTime: number = 0;
46fb726d48Sopenharmony_ci  dur: number = 0;
47fb726d48Sopenharmony_ci  heapSize: number = 0;
48fb726d48Sopenharmony_ci  density: number = 0;
49fb726d48Sopenharmony_ci}
50fb726d48Sopenharmony_ci
51fb726d48Sopenharmony_ciclass NMData {
52fb726d48Sopenharmony_ci  callchainId: number = 0;
53fb726d48Sopenharmony_ci  startTs: number = 0;
54fb726d48Sopenharmony_ci  startTime: number = 0;
55fb726d48Sopenharmony_ci  applyCount: number = 0;
56fb726d48Sopenharmony_ci  applySize: number = 0;
57fb726d48Sopenharmony_ci  releaseCount: number = 0;
58fb726d48Sopenharmony_ci  releaseSize: number = 0;
59fb726d48Sopenharmony_ci  heapSize: number = 0;
60fb726d48Sopenharmony_ci  eventType: number = 0;
61fb726d48Sopenharmony_ci  type: number = 0;
62fb726d48Sopenharmony_ci  ipid: number = 0;
63fb726d48Sopenharmony_ci}
64fb726d48Sopenharmony_ci
65fb726d48Sopenharmony_ciconst dataCache: {
66fb726d48Sopenharmony_ci  normalCache: Map<string, NativeMemoryCacheType>;
67fb726d48Sopenharmony_ci  statisticsCache: Map<string, NativeMemoryCacheType>;
68fb726d48Sopenharmony_ci} = {
69fb726d48Sopenharmony_ci  normalCache: new Map<string, NativeMemoryCacheType>(),
70fb726d48Sopenharmony_ci  statisticsCache: new Map<string, NativeMemoryCacheType>(),
71fb726d48Sopenharmony_ci};
72fb726d48Sopenharmony_ci
73fb726d48Sopenharmony_cilet tempSize: number = 0;
74fb726d48Sopenharmony_cilet tempDensity: number = 0;
75fb726d48Sopenharmony_ci
76fb726d48Sopenharmony_cifunction nativeMemoryChartDataCacheSql(model: string, startNS: number, endNS: number): string {
77fb726d48Sopenharmony_ci  if (model === 'native_hook') {
78fb726d48Sopenharmony_ci    return `select * from (
79fb726d48Sopenharmony_ci                select 
80fb726d48Sopenharmony_ci                    h.start_ts - ${startNS} as startTime,
81fb726d48Sopenharmony_ci                    h.heap_size as heapSize,
82fb726d48Sopenharmony_ci                    (case when h.event_type = 'AllocEvent' then 0 else 1 end) as eventType,
83fb726d48Sopenharmony_ci                    ipid
84fb726d48Sopenharmony_ci                from native_hook h
85fb726d48Sopenharmony_ci                where h.start_ts between ${startNS} and ${endNS}
86fb726d48Sopenharmony_ci                    and (h.event_type = 'AllocEvent' or h.event_type = 'MmapEvent')
87fb726d48Sopenharmony_ci                union all
88fb726d48Sopenharmony_ci                select 
89fb726d48Sopenharmony_ci                    h.end_ts - ${startNS} as startTime,
90fb726d48Sopenharmony_ci                    h.heap_size as heapSize,
91fb726d48Sopenharmony_ci                    (case when h.event_type = 'AllocEvent' then 2 else 3 end) as eventType,
92fb726d48Sopenharmony_ci                    ipid
93fb726d48Sopenharmony_ci                from native_hook h
94fb726d48Sopenharmony_ci                where 
95fb726d48Sopenharmony_ci                  h.start_ts between ${startNS} and ${endNS}
96fb726d48Sopenharmony_ci                  and h.end_ts between ${startNS} and ${endNS}
97fb726d48Sopenharmony_ci                  and (h.event_type = 'AllocEvent' or h.event_type = 'MmapEvent')
98fb726d48Sopenharmony_ci            )
99fb726d48Sopenharmony_ci            order by startTime;`;
100fb726d48Sopenharmony_ci  } else {
101fb726d48Sopenharmony_ci    return `select callchain_id    as callchainId,
102fb726d48Sopenharmony_ci                ts - ${startNS}    as startTs,
103fb726d48Sopenharmony_ci                apply_count        as applyCount,
104fb726d48Sopenharmony_ci                apply_size         as applySize,
105fb726d48Sopenharmony_ci                release_count      as releaseCount,
106fb726d48Sopenharmony_ci                release_size       as releaseSize,
107fb726d48Sopenharmony_ci                ipid,
108fb726d48Sopenharmony_ci                type               
109fb726d48Sopenharmony_ci            from native_hook_statistic
110fb726d48Sopenharmony_ci            where ts between ${startNS} and ${endNS};
111fb726d48Sopenharmony_ci    `;
112fb726d48Sopenharmony_ci  }
113fb726d48Sopenharmony_ci}
114fb726d48Sopenharmony_ci
115fb726d48Sopenharmony_cifunction normalChartDataHandler(data: Array<NMData>, key: string, totalNS: number): void {
116fb726d48Sopenharmony_ci  let nmFilterLen = data.length;
117fb726d48Sopenharmony_ci  let nmFilterLevel = getFilterLevel(nmFilterLen);
118fb726d48Sopenharmony_ci  tempSize = 0;
119fb726d48Sopenharmony_ci  tempDensity = 0;
120fb726d48Sopenharmony_ci  data.map((ne: NMData, index: number): void =>
121fb726d48Sopenharmony_ci    mergeNormalChartData(ne, nmFilterLevel, index === nmFilterLen - 1, key)
122fb726d48Sopenharmony_ci  );
123fb726d48Sopenharmony_ci  let cache = dataCache.normalCache.get(key);
124fb726d48Sopenharmony_ci  if (cache && cache.dataList.length > 0) {
125fb726d48Sopenharmony_ci    cache.dataList[cache.dataList.length - 1].dur = totalNS - cache.dataList[cache.dataList.length - 1].startTime!;
126fb726d48Sopenharmony_ci  }
127fb726d48Sopenharmony_ci}
128fb726d48Sopenharmony_ci
129fb726d48Sopenharmony_cifunction mergeNormalChartData(ne: NMData, filterLevel: number, finish: boolean, key: string): void {
130fb726d48Sopenharmony_ci  let item: NativeMemoryChartDataType = {
131fb726d48Sopenharmony_ci    startTime: ne.startTime,
132fb726d48Sopenharmony_ci    density: 0,
133fb726d48Sopenharmony_ci    heapSize: 0,
134fb726d48Sopenharmony_ci    dur: 0,
135fb726d48Sopenharmony_ci  };
136fb726d48Sopenharmony_ci  if (!dataCache.normalCache.has(key)) {
137fb726d48Sopenharmony_ci    if (ne.eventType === 0 || ne.eventType === 1) {
138fb726d48Sopenharmony_ci      item.density = 1;
139fb726d48Sopenharmony_ci      item.heapSize = ne.heapSize;
140fb726d48Sopenharmony_ci    } else {
141fb726d48Sopenharmony_ci      item.density = -1;
142fb726d48Sopenharmony_ci      item.heapSize = 0 - ne.heapSize;
143fb726d48Sopenharmony_ci    }
144fb726d48Sopenharmony_ci    dataCache.normalCache.set(key, {
145fb726d48Sopenharmony_ci      maxSize: item.heapSize,
146fb726d48Sopenharmony_ci      minSize: item.heapSize,
147fb726d48Sopenharmony_ci      maxDensity: item.density,
148fb726d48Sopenharmony_ci      minDensity: item.density,
149fb726d48Sopenharmony_ci      dataList: [item],
150fb726d48Sopenharmony_ci    });
151fb726d48Sopenharmony_ci  } else {
152fb726d48Sopenharmony_ci    mergeData(item, ne, filterLevel, finish, key);
153fb726d48Sopenharmony_ci  }
154fb726d48Sopenharmony_ci}
155fb726d48Sopenharmony_ci
156fb726d48Sopenharmony_cifunction mergeData(
157fb726d48Sopenharmony_ci  item: NativeMemoryChartDataType,
158fb726d48Sopenharmony_ci  ne: NMData,
159fb726d48Sopenharmony_ci  filterLevel: number,
160fb726d48Sopenharmony_ci  finish: boolean,
161fb726d48Sopenharmony_ci  key: string
162fb726d48Sopenharmony_ci): void {
163fb726d48Sopenharmony_ci  let data = dataCache.normalCache.get(key);
164fb726d48Sopenharmony_ci  if (data) {
165fb726d48Sopenharmony_ci    let last = data.dataList[data.dataList.length - 1];
166fb726d48Sopenharmony_ci    last.dur = item.startTime! - last.startTime!;
167fb726d48Sopenharmony_ci    if (last.dur > filterLevel || finish) {
168fb726d48Sopenharmony_ci      if (ne.eventType === 0 || ne.eventType === 1) {
169fb726d48Sopenharmony_ci        item.density = last.density! + tempDensity + 1;
170fb726d48Sopenharmony_ci        item.heapSize = last.heapSize! + tempSize + ne.heapSize;
171fb726d48Sopenharmony_ci      } else {
172fb726d48Sopenharmony_ci        item.density = last.density! + tempDensity - 1;
173fb726d48Sopenharmony_ci        item.heapSize = last.heapSize! + tempSize - ne.heapSize;
174fb726d48Sopenharmony_ci      }
175fb726d48Sopenharmony_ci      tempDensity = 0;
176fb726d48Sopenharmony_ci      tempSize = 0;
177fb726d48Sopenharmony_ci      data.maxDensity = Math.max(item.density, data.maxDensity);
178fb726d48Sopenharmony_ci      data.minDensity = Math.min(item.density, data.minDensity);
179fb726d48Sopenharmony_ci      data.maxSize = Math.max(item.heapSize, data.maxSize);
180fb726d48Sopenharmony_ci      data.minSize = Math.min(item.heapSize, data.minSize);
181fb726d48Sopenharmony_ci      data.dataList.push(item);
182fb726d48Sopenharmony_ci    } else {
183fb726d48Sopenharmony_ci      if (ne.eventType === 0 || ne.eventType === 1) {
184fb726d48Sopenharmony_ci        tempDensity += 1;
185fb726d48Sopenharmony_ci        tempSize += ne.heapSize;
186fb726d48Sopenharmony_ci      } else {
187fb726d48Sopenharmony_ci        tempDensity -= 1;
188fb726d48Sopenharmony_ci        tempSize -= ne.heapSize;
189fb726d48Sopenharmony_ci      }
190fb726d48Sopenharmony_ci    }
191fb726d48Sopenharmony_ci  }
192fb726d48Sopenharmony_ci}
193fb726d48Sopenharmony_ci
194fb726d48Sopenharmony_cifunction statisticChartHandler(arr: Array<NMData>, key: string, timeArr: number[]): void {
195fb726d48Sopenharmony_ci  let callGroupMap: Map<number, NMData[]> = new Map<number, NMData[]>();
196fb726d48Sopenharmony_ci  let obj: Map<number, NativeMemoryChartDataType> = new Map<number, NativeMemoryChartDataType>();
197fb726d48Sopenharmony_ci  for (let hook of arr) {
198fb726d48Sopenharmony_ci    if (obj.has(hook.startTs)) {
199fb726d48Sopenharmony_ci      let data = obj.get(hook.startTs)!;
200fb726d48Sopenharmony_ci      data.startTime = hook.startTs;
201fb726d48Sopenharmony_ci      data.dur = 0;
202fb726d48Sopenharmony_ci      if (callGroupMap.has(hook.callchainId)) {
203fb726d48Sopenharmony_ci        let calls = callGroupMap.get(hook.callchainId);
204fb726d48Sopenharmony_ci        let last = calls![calls!.length - 1];
205fb726d48Sopenharmony_ci        data.heapSize += hook.applySize - last.applySize - (hook.releaseSize - last.releaseSize);
206fb726d48Sopenharmony_ci        data.density += hook.applyCount - last.applyCount - (hook.releaseCount - last.releaseCount);
207fb726d48Sopenharmony_ci        calls!.push(hook);
208fb726d48Sopenharmony_ci      } else {
209fb726d48Sopenharmony_ci        data.heapSize += hook.applySize - hook.releaseSize;
210fb726d48Sopenharmony_ci        data.density += hook.applyCount - hook.releaseCount;
211fb726d48Sopenharmony_ci        callGroupMap.set(hook.callchainId, [hook]);
212fb726d48Sopenharmony_ci      }
213fb726d48Sopenharmony_ci    } else {
214fb726d48Sopenharmony_ci      let data: NativeMemoryChartDataType = new NativeMemoryChartDataType();
215fb726d48Sopenharmony_ci      data.startTime = hook.startTs;
216fb726d48Sopenharmony_ci      data.dur = 0;
217fb726d48Sopenharmony_ci      if (callGroupMap.has(hook.callchainId)) {
218fb726d48Sopenharmony_ci        let calls = callGroupMap.get(hook.callchainId);
219fb726d48Sopenharmony_ci        let last = calls![calls!.length - 1];
220fb726d48Sopenharmony_ci        data.heapSize = hook.applySize - last.applySize - (hook.releaseSize - last.releaseSize);
221fb726d48Sopenharmony_ci        data.density = hook.applyCount - last.applyCount - (hook.releaseCount - last.releaseCount);
222fb726d48Sopenharmony_ci        calls!.push(hook);
223fb726d48Sopenharmony_ci      } else {
224fb726d48Sopenharmony_ci        data.heapSize = hook.applySize - hook.releaseSize;
225fb726d48Sopenharmony_ci        data.density = hook.applyCount - hook.releaseCount;
226fb726d48Sopenharmony_ci        callGroupMap.set(hook.callchainId, [hook]);
227fb726d48Sopenharmony_ci      }
228fb726d48Sopenharmony_ci      obj.set(hook.startTs, data);
229fb726d48Sopenharmony_ci    }
230fb726d48Sopenharmony_ci  }
231fb726d48Sopenharmony_ci  saveStatisticsCacheMapValue(key, obj, timeArr);
232fb726d48Sopenharmony_ci}
233fb726d48Sopenharmony_ci
234fb726d48Sopenharmony_cifunction saveStatisticsCacheMapValue(
235fb726d48Sopenharmony_ci  key: string,
236fb726d48Sopenharmony_ci  obj: Map<number, NativeMemoryChartDataType>,
237fb726d48Sopenharmony_ci  timeArr: number[]
238fb726d48Sopenharmony_ci): void {
239fb726d48Sopenharmony_ci  let source = Array.from(obj.values());
240fb726d48Sopenharmony_ci  let arr: NativeMemoryChartDataType[] = [];
241fb726d48Sopenharmony_ci  let cache = {
242fb726d48Sopenharmony_ci    maxSize: 0,
243fb726d48Sopenharmony_ci    minSize: 0,
244fb726d48Sopenharmony_ci    maxDensity: 0,
245fb726d48Sopenharmony_ci    minDensity: 0,
246fb726d48Sopenharmony_ci    dataList: arr,
247fb726d48Sopenharmony_ci  };
248fb726d48Sopenharmony_ci  for (let i = 0, len = source.length; i < len; i++) {
249fb726d48Sopenharmony_ci    let startTsIndex = timeArr.findIndex((time) => source[i].startTime === time);
250fb726d48Sopenharmony_ci    let realStartTs = startTsIndex > 0 ? timeArr[startTsIndex - 1] : 0;
251fb726d48Sopenharmony_ci    let item = {
252fb726d48Sopenharmony_ci      startTime: realStartTs,
253fb726d48Sopenharmony_ci      heapSize: i > 0 ? source[i].heapSize + arr[i - 1].heapSize : source[i].heapSize,
254fb726d48Sopenharmony_ci      density: i > 0 ? source[i].density + arr[i - 1].density : source[i].density,
255fb726d48Sopenharmony_ci      dur: source[i].startTime - realStartTs,
256fb726d48Sopenharmony_ci    };
257fb726d48Sopenharmony_ci    arr.push(item);
258fb726d48Sopenharmony_ci    cache.maxSize = Math.max(cache.maxSize, item.heapSize);
259fb726d48Sopenharmony_ci    cache.maxDensity = Math.max(cache.maxDensity, item.density);
260fb726d48Sopenharmony_ci    cache.minSize = Math.min(cache.minSize, item.heapSize);
261fb726d48Sopenharmony_ci    cache.minDensity = Math.min(cache.minDensity, item.density);
262fb726d48Sopenharmony_ci  }
263fb726d48Sopenharmony_ci  source.length = 0;
264fb726d48Sopenharmony_ci  dataCache.statisticsCache.set(key, cache);
265fb726d48Sopenharmony_ci}
266fb726d48Sopenharmony_ci
267fb726d48Sopenharmony_cifunction cacheSumRowData(ipid: number, key: string, timeArr: number[]): void {
268fb726d48Sopenharmony_ci  let ah = dataCache.statisticsCache.get(`${ipid}-1`)?.dataList;
269fb726d48Sopenharmony_ci  let mmap = dataCache.statisticsCache.get(`${ipid}-2`)?.dataList;
270fb726d48Sopenharmony_ci  let arr: NativeMemoryChartDataType[] = [];
271fb726d48Sopenharmony_ci  let sumCache = {
272fb726d48Sopenharmony_ci    maxSize: 0,
273fb726d48Sopenharmony_ci    minSize: 0,
274fb726d48Sopenharmony_ci    maxDensity: 0,
275fb726d48Sopenharmony_ci    minDensity: 0,
276fb726d48Sopenharmony_ci    dataList: arr,
277fb726d48Sopenharmony_ci  };
278fb726d48Sopenharmony_ci  timeArr.unshift(0);
279fb726d48Sopenharmony_ci  timeArr.forEach((time, index) => {
280fb726d48Sopenharmony_ci    let item = {
281fb726d48Sopenharmony_ci      startTime: time,
282fb726d48Sopenharmony_ci      heapSize: 0,
283fb726d48Sopenharmony_ci      density: 0,
284fb726d48Sopenharmony_ci      dur: 0,
285fb726d48Sopenharmony_ci    };
286fb726d48Sopenharmony_ci    let ahItem = ah?.find((it) => it.startTime === time);
287fb726d48Sopenharmony_ci    let mmapItem = mmap?.find((it) => it.startTime === time);
288fb726d48Sopenharmony_ci    if (ahItem) {
289fb726d48Sopenharmony_ci      item.heapSize += ahItem.heapSize;
290fb726d48Sopenharmony_ci      item.density += ahItem.density;
291fb726d48Sopenharmony_ci    }
292fb726d48Sopenharmony_ci    if (mmapItem) {
293fb726d48Sopenharmony_ci      item.heapSize += mmapItem.heapSize;
294fb726d48Sopenharmony_ci      item.density += mmapItem.density;
295fb726d48Sopenharmony_ci    }
296fb726d48Sopenharmony_ci    item.dur = ahItem?.dur || mmapItem?.dur || 0;
297fb726d48Sopenharmony_ci    arr.push(item);
298fb726d48Sopenharmony_ci    sumCache.maxSize = Math.max(sumCache.maxSize, item.heapSize);
299fb726d48Sopenharmony_ci    sumCache.maxDensity = Math.max(sumCache.maxDensity, item.density);
300fb726d48Sopenharmony_ci    sumCache.minSize = Math.min(sumCache.minSize, item.heapSize);
301fb726d48Sopenharmony_ci    sumCache.minDensity = Math.min(sumCache.minDensity, item.density);
302fb726d48Sopenharmony_ci  });
303fb726d48Sopenharmony_ci  dataCache.statisticsCache.set(key, sumCache);
304fb726d48Sopenharmony_ci}
305fb726d48Sopenharmony_ci
306fb726d48Sopenharmony_cifunction cacheNativeMemoryChartData(model: string, totalNS: number, processes: number[], data: Array<NMData>): void {
307fb726d48Sopenharmony_ci  processes.forEach((ipid) => {
308fb726d48Sopenharmony_ci    let processData = data.filter((ne) => ne.ipid === ipid);
309fb726d48Sopenharmony_ci    if (model === 'native_hook') {
310fb726d48Sopenharmony_ci      //正常模式
311fb726d48Sopenharmony_ci      normalChartDataHandler(processData, `${ipid}-0`, totalNS);
312fb726d48Sopenharmony_ci      normalChartDataHandler(
313fb726d48Sopenharmony_ci        processData.filter((ne) => ne.eventType === 0 || ne.eventType === 2),
314fb726d48Sopenharmony_ci        `${ipid}-1`,
315fb726d48Sopenharmony_ci        totalNS
316fb726d48Sopenharmony_ci      );
317fb726d48Sopenharmony_ci      normalChartDataHandler(
318fb726d48Sopenharmony_ci        processData.filter((ne) => ne.eventType === 1 || ne.eventType === 3),
319fb726d48Sopenharmony_ci        `${ipid}-2`,
320fb726d48Sopenharmony_ci        totalNS
321fb726d48Sopenharmony_ci      );
322fb726d48Sopenharmony_ci    } else {
323fb726d48Sopenharmony_ci      //统计模式
324fb726d48Sopenharmony_ci      let timeSet: Set<number> = new Set<number>();
325fb726d48Sopenharmony_ci      let alData: NMData[] = [];
326fb726d48Sopenharmony_ci      let mmapData: NMData[] = [];
327fb726d48Sopenharmony_ci      processData.forEach((ne) => {
328fb726d48Sopenharmony_ci        timeSet.add(ne.startTs);
329fb726d48Sopenharmony_ci        if (ne.type === 0) {
330fb726d48Sopenharmony_ci          alData.push(ne);
331fb726d48Sopenharmony_ci        } else {
332fb726d48Sopenharmony_ci          mmapData.push(ne);
333fb726d48Sopenharmony_ci        }
334fb726d48Sopenharmony_ci      });
335fb726d48Sopenharmony_ci      let timeArr = Array.from(timeSet).sort((a, b) => a - b);
336fb726d48Sopenharmony_ci      statisticChartHandler(alData, `${ipid}-1`, timeArr);
337fb726d48Sopenharmony_ci      statisticChartHandler(mmapData, `${ipid}-2`, timeArr);
338fb726d48Sopenharmony_ci      cacheSumRowData(ipid, `${ipid}-0`, timeArr);
339fb726d48Sopenharmony_ci      timeArr.length = 0;
340fb726d48Sopenharmony_ci      timeSet.clear();
341fb726d48Sopenharmony_ci    }
342fb726d48Sopenharmony_ci    processData.length = 0;
343fb726d48Sopenharmony_ci  });
344fb726d48Sopenharmony_ci}
345fb726d48Sopenharmony_ci
346fb726d48Sopenharmony_cifunction getFilterLevel(len: number): number {
347fb726d48Sopenharmony_ci  if (len > 300_0000) {
348fb726d48Sopenharmony_ci    return 50_0000;
349fb726d48Sopenharmony_ci  } else if (len > 200_0000) {
350fb726d48Sopenharmony_ci    return 30_0000;
351fb726d48Sopenharmony_ci  } else if (len > 100_0000) {
352fb726d48Sopenharmony_ci    return 10_0000;
353fb726d48Sopenharmony_ci  } else if (len > 50_0000) {
354fb726d48Sopenharmony_ci    return 5_0000;
355fb726d48Sopenharmony_ci  } else if (len > 30_0000) {
356fb726d48Sopenharmony_ci    return 2_0000;
357fb726d48Sopenharmony_ci  } else if (len > 15_0000) {
358fb726d48Sopenharmony_ci    return 1_0000;
359fb726d48Sopenharmony_ci  } else {
360fb726d48Sopenharmony_ci    return 0;
361fb726d48Sopenharmony_ci  }
362fb726d48Sopenharmony_ci}
363fb726d48Sopenharmony_ci
364fb726d48Sopenharmony_ciexport function nativeMemoryCacheClear(): void {
365fb726d48Sopenharmony_ci  dataCache.normalCache.clear();
366fb726d48Sopenharmony_ci  dataCache.statisticsCache.clear();
367fb726d48Sopenharmony_ci}
368fb726d48Sopenharmony_ci
369fb726d48Sopenharmony_ciexport function nativeMemoryDataHandler(data: SenderParam, proc: Function): void {
370fb726d48Sopenharmony_ci  if (data.params.isCache) {
371fb726d48Sopenharmony_ci    dataCache.normalCache.clear();
372fb726d48Sopenharmony_ci    dataCache.statisticsCache.clear();
373fb726d48Sopenharmony_ci    let arr: NMData[] = [];
374fb726d48Sopenharmony_ci    let res: Array<
375fb726d48Sopenharmony_ci      | {
376fb726d48Sopenharmony_ci          nativeMemoryNormal: NMData;
377fb726d48Sopenharmony_ci          nativeMemoryStatistic: NMData;
378fb726d48Sopenharmony_ci        }
379fb726d48Sopenharmony_ci      | NMData
380fb726d48Sopenharmony_ci    > = proc(nativeMemoryChartDataCacheSql(data.params.model, data.params.recordStartNS, data.params.recordEndNS));
381fb726d48Sopenharmony_ci    if (data.params.trafic === TraficEnum.ProtoBuffer) {
382fb726d48Sopenharmony_ci      arr = (
383fb726d48Sopenharmony_ci        res as Array<{
384fb726d48Sopenharmony_ci          nativeMemoryNormal: NMData;
385fb726d48Sopenharmony_ci          nativeMemoryStatistic: NMData;
386fb726d48Sopenharmony_ci        }>
387fb726d48Sopenharmony_ci      ).map((item) => {
388fb726d48Sopenharmony_ci        let nm = new NMData();
389fb726d48Sopenharmony_ci        if (data.params.model === 'native_hook') {
390fb726d48Sopenharmony_ci          Object.assign(nm, item.nativeMemoryNormal);
391fb726d48Sopenharmony_ci        } else {
392fb726d48Sopenharmony_ci          Object.assign(nm, item.nativeMemoryStatistic);
393fb726d48Sopenharmony_ci        }
394fb726d48Sopenharmony_ci        return nm;
395fb726d48Sopenharmony_ci      });
396fb726d48Sopenharmony_ci    } else {
397fb726d48Sopenharmony_ci      arr = res as Array<NMData>;
398fb726d48Sopenharmony_ci    }
399fb726d48Sopenharmony_ci    cacheNativeMemoryChartData(data.params.model, data.params.totalNS, data.params.processes, arr);
400fb726d48Sopenharmony_ci    res.length = 0;
401fb726d48Sopenharmony_ci    (self as unknown as Worker).postMessage(
402fb726d48Sopenharmony_ci      {
403fb726d48Sopenharmony_ci        id: data.id,
404fb726d48Sopenharmony_ci        action: data.action,
405fb726d48Sopenharmony_ci        results: 'ok',
406fb726d48Sopenharmony_ci        len: 0,
407fb726d48Sopenharmony_ci      },
408fb726d48Sopenharmony_ci      []
409fb726d48Sopenharmony_ci    );
410fb726d48Sopenharmony_ci  } else {
411fb726d48Sopenharmony_ci    arrayBufferCallback(data, true);
412fb726d48Sopenharmony_ci  }
413fb726d48Sopenharmony_ci}
414fb726d48Sopenharmony_ci
415fb726d48Sopenharmony_cifunction arrayBufferCallback(data: SenderParam, transfer: boolean): void {
416fb726d48Sopenharmony_ci  let cacheKey = `${data.params.ipid}-${data.params.eventType}`;
417fb726d48Sopenharmony_ci  let dataFilter = filterNativeMemoryChartData(
418fb726d48Sopenharmony_ci    data.params.model,
419fb726d48Sopenharmony_ci    data.params.startNS,
420fb726d48Sopenharmony_ci    data.params.endNS,
421fb726d48Sopenharmony_ci    data.params.totalNS,
422fb726d48Sopenharmony_ci    data.params.drawType,
423fb726d48Sopenharmony_ci    data.params.frame,
424fb726d48Sopenharmony_ci    cacheKey
425fb726d48Sopenharmony_ci  );
426fb726d48Sopenharmony_ci  let len = dataFilter.startTime.length;
427fb726d48Sopenharmony_ci  let startTime = new Float64Array(len);
428fb726d48Sopenharmony_ci  let dur = new Float64Array(len);
429fb726d48Sopenharmony_ci  let density = new Int32Array(len);
430fb726d48Sopenharmony_ci  let heapSize = new Float64Array(len);
431fb726d48Sopenharmony_ci  for (let i = 0; i < len; i++) {
432fb726d48Sopenharmony_ci    startTime[i] = dataFilter.startTime[i];
433fb726d48Sopenharmony_ci    dur[i] = dataFilter.dur[i];
434fb726d48Sopenharmony_ci    heapSize[i] = dataFilter.heapSize[i];
435fb726d48Sopenharmony_ci    density[i] = dataFilter.density[i];
436fb726d48Sopenharmony_ci  }
437fb726d48Sopenharmony_ci  let cacheSource = data.params.model === 'native_hook' ? dataCache.normalCache : dataCache.statisticsCache;
438fb726d48Sopenharmony_ci  let cache = cacheSource.get(cacheKey);
439fb726d48Sopenharmony_ci  (self as unknown as Worker).postMessage(
440fb726d48Sopenharmony_ci    {
441fb726d48Sopenharmony_ci      id: data.id,
442fb726d48Sopenharmony_ci      action: data.action,
443fb726d48Sopenharmony_ci      results: transfer
444fb726d48Sopenharmony_ci        ? {
445fb726d48Sopenharmony_ci            startTime: startTime.buffer,
446fb726d48Sopenharmony_ci            dur: dur.buffer,
447fb726d48Sopenharmony_ci            density: density.buffer,
448fb726d48Sopenharmony_ci            heapSize: heapSize.buffer,
449fb726d48Sopenharmony_ci            maxSize: cache!.maxSize,
450fb726d48Sopenharmony_ci            minSize: cache!.minSize,
451fb726d48Sopenharmony_ci            maxDensity: cache!.maxDensity,
452fb726d48Sopenharmony_ci            minDensity: cache!.minDensity,
453fb726d48Sopenharmony_ci          }
454fb726d48Sopenharmony_ci        : {},
455fb726d48Sopenharmony_ci      len: len,
456fb726d48Sopenharmony_ci    },
457fb726d48Sopenharmony_ci    transfer ? [startTime.buffer, dur.buffer, density.buffer, heapSize.buffer] : []
458fb726d48Sopenharmony_ci  );
459fb726d48Sopenharmony_ci}
460fb726d48Sopenharmony_ci
461fb726d48Sopenharmony_ciexport function filterNativeMemoryChartData(
462fb726d48Sopenharmony_ci  model: string,
463fb726d48Sopenharmony_ci  startNS: number,
464fb726d48Sopenharmony_ci  endNS: number,
465fb726d48Sopenharmony_ci  totalNS: number,
466fb726d48Sopenharmony_ci  drawType: number,
467fb726d48Sopenharmony_ci  frame: { width: number },
468fb726d48Sopenharmony_ci  key: string
469fb726d48Sopenharmony_ci): NativeMemoryDataSource {
470fb726d48Sopenharmony_ci  let dataSource = new NativeMemoryDataSource();
471fb726d48Sopenharmony_ci  let cache = model === 'native_hook' ? dataCache.normalCache.get(key) : dataCache.statisticsCache.get(key);
472fb726d48Sopenharmony_ci  if (cache !== undefined) {
473fb726d48Sopenharmony_ci    let data: Map<string, number> = new Map<string, number>();
474fb726d48Sopenharmony_ci    cache!.dataList.reduce((pre, current, index) => {
475fb726d48Sopenharmony_ci      if (current.dur > 0 && current.startTime + current.dur >= startNS && current.startTime <= endNS) {
476fb726d48Sopenharmony_ci        if (dur2Width(current.startTime, current.dur, startNS, endNS || totalNS, frame) >= 1) {
477fb726d48Sopenharmony_ci          //计算绘制宽度 大于 1px,则加入绘制列表
478fb726d48Sopenharmony_ci          dataSource.startTime.push(current.startTime);
479fb726d48Sopenharmony_ci          dataSource.dur.push(current.dur);
480fb726d48Sopenharmony_ci          dataSource.density.push(current.density);
481fb726d48Sopenharmony_ci          dataSource.heapSize.push(current.heapSize);
482fb726d48Sopenharmony_ci        } else {
483fb726d48Sopenharmony_ci          let x = 0;
484fb726d48Sopenharmony_ci          if (current.startTime > startNS && current.startTime < endNS) {
485fb726d48Sopenharmony_ci            x = Math.trunc(ns2x(current.startTime, startNS, endNS, totalNS, frame));
486fb726d48Sopenharmony_ci          } else {
487fb726d48Sopenharmony_ci            x = 0;
488fb726d48Sopenharmony_ci          }
489fb726d48Sopenharmony_ci          let key = `${x}`;
490fb726d48Sopenharmony_ci          let preIndex = pre.get(key);
491fb726d48Sopenharmony_ci          if (preIndex !== undefined) {
492fb726d48Sopenharmony_ci            if (drawType === 0) {
493fb726d48Sopenharmony_ci              pre.set(key, cache!.dataList[preIndex].heapSize > cache!.dataList[index].heapSize ? preIndex : index);
494fb726d48Sopenharmony_ci            } else {
495fb726d48Sopenharmony_ci              pre.set(key, cache!.dataList[preIndex].density > cache!.dataList[index].density ? preIndex : index);
496fb726d48Sopenharmony_ci            }
497fb726d48Sopenharmony_ci          } else {
498fb726d48Sopenharmony_ci            pre.set(key, index);
499fb726d48Sopenharmony_ci          }
500fb726d48Sopenharmony_ci        }
501fb726d48Sopenharmony_ci      }
502fb726d48Sopenharmony_ci      return pre;
503fb726d48Sopenharmony_ci    }, data);
504fb726d48Sopenharmony_ci    setDataSource(data, dataSource, cache);
505fb726d48Sopenharmony_ci  }
506fb726d48Sopenharmony_ci  return dataSource;
507fb726d48Sopenharmony_ci}
508fb726d48Sopenharmony_ci
509fb726d48Sopenharmony_cifunction setDataSource(
510fb726d48Sopenharmony_ci  data: Map<string, number>,
511fb726d48Sopenharmony_ci  dataSource: NativeMemoryDataSource,
512fb726d48Sopenharmony_ci  cache: NativeMemoryCacheType
513fb726d48Sopenharmony_ci): void {
514fb726d48Sopenharmony_ci  Array.from(data.values()).forEach((idx) => {
515fb726d48Sopenharmony_ci    dataSource.startTime.push(cache!.dataList[idx].startTime);
516fb726d48Sopenharmony_ci    dataSource.dur.push(cache!.dataList[idx].dur);
517fb726d48Sopenharmony_ci    dataSource.density.push(cache!.dataList[idx].density);
518fb726d48Sopenharmony_ci    dataSource.heapSize.push(cache!.dataList[idx].heapSize);
519fb726d48Sopenharmony_ci  });
520fb726d48Sopenharmony_ci}
521fb726d48Sopenharmony_ci
522fb726d48Sopenharmony_cifunction ns2x(ns: number, startNS: number, endNS: number, duration: number, rect: { width: number }): number {
523fb726d48Sopenharmony_ci  if (endNS === 0) {
524fb726d48Sopenharmony_ci    endNS = duration;
525fb726d48Sopenharmony_ci  }
526fb726d48Sopenharmony_ci  let xSizeNM: number = ((ns - startNS) * rect.width) / (endNS - startNS);
527fb726d48Sopenharmony_ci  if (xSizeNM < 0) {
528fb726d48Sopenharmony_ci    xSizeNM = 0;
529fb726d48Sopenharmony_ci  } else if (xSizeNM > rect.width) {
530fb726d48Sopenharmony_ci    xSizeNM = rect.width;
531fb726d48Sopenharmony_ci  }
532fb726d48Sopenharmony_ci  return xSizeNM;
533fb726d48Sopenharmony_ci}
534fb726d48Sopenharmony_ci
535fb726d48Sopenharmony_cifunction dur2Width(startTime: number, dur: number, startNS: number, endNS: number, rect: { width: number }): number {
536fb726d48Sopenharmony_ci  let realDur = startTime + dur - Math.max(startTime, startNS);
537fb726d48Sopenharmony_ci  return Math.trunc((realDur * rect.width) / (endNS - startNS));
538fb726d48Sopenharmony_ci}
539fb726d48Sopenharmony_ci
540fb726d48Sopenharmony_ciclass NativeMemoryDataSource {
541fb726d48Sopenharmony_ci  startTime: Array<number>;
542fb726d48Sopenharmony_ci  dur: Array<number>;
543fb726d48Sopenharmony_ci  heapSize: Array<number>;
544fb726d48Sopenharmony_ci  density: Array<number>;
545fb726d48Sopenharmony_ci  constructor() {
546fb726d48Sopenharmony_ci    this.startTime = [];
547fb726d48Sopenharmony_ci    this.dur = [];
548fb726d48Sopenharmony_ci    this.heapSize = [];
549fb726d48Sopenharmony_ci    this.density = [];
550fb726d48Sopenharmony_ci  }
551fb726d48Sopenharmony_ci}
552