• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
16import { ColorUtils } from '../../component/trace/base/ColorUtils';
17import {
18  BaseStruct,
19  isFrameContainPoint,
20  ns2x,
21  Render,
22  dataFilterHandler,
23  drawLoadingFrame,
24} from './ProcedureWorkerCommon';
25import { TraceRow } from '../../component/trace/base/TraceRow';
26
27export class DiskIoAbilityRender extends Render {
28  renderMainThread(
29    req: {
30      context: CanvasRenderingContext2D;
31      useCache: boolean;
32      type: string;
33      maxDiskRate: number;
34      maxDiskRateName: string;
35    },
36    diskIoAbilityRow: TraceRow<DiskAbilityMonitorStruct>
37  ): void {
38    let diskIoAbilityList = diskIoAbilityRow.dataList;
39    let diskIoFilter = diskIoAbilityRow.dataListCache;
40    dataFilterHandler(diskIoAbilityList, diskIoFilter, {
41      startKey: 'startNS',
42      durKey: 'dur',
43      startNS: TraceRow.range?.startNS ?? 0,
44      endNS: TraceRow.range?.endNS ?? 0,
45      totalNS: TraceRow.range?.totalNS ?? 0,
46      frame: diskIoAbilityRow.frame,
47      paddingTop: 5,
48      useCache: req.useCache || !(TraceRow.range?.refresh ?? false),
49    });
50    drawLoadingFrame(req.context, diskIoAbilityRow.dataListCache, diskIoAbilityRow);
51    req.context.beginPath();
52    let find = false;
53    for (let re of diskIoFilter) {
54      DiskAbilityMonitorStruct.draw(req.context, re, req.maxDiskRate, diskIoAbilityRow.isHover);
55      if (
56        diskIoAbilityRow.isHover &&
57        re.frame &&
58        isFrameContainPoint(re.frame, diskIoAbilityRow.hoverX, diskIoAbilityRow.hoverY)
59      ) {
60        DiskAbilityMonitorStruct.hoverDiskAbilityStruct = re;
61        find = true;
62      }
63    }
64    if (!find && diskIoAbilityRow.isHover) {
65      DiskAbilityMonitorStruct.hoverDiskAbilityStruct = undefined;
66    }
67    req.context.closePath();
68    let textMetrics = req.context.measureText(req.maxDiskRateName);
69    req.context.globalAlpha = 0.8;
70    req.context.fillStyle = '#f0f0f0';
71    req.context.fillRect(0, 5, textMetrics.width + 8, 18);
72    req.context.globalAlpha = 1;
73    req.context.fillStyle = '#333';
74    req.context.textBaseline = 'middle';
75    req.context.fillText(req.maxDiskRateName, 4, 5 + 9);
76  }
77}
78
79export function diskIoAbility(
80  diskIoAbilityList: Array<any>,
81  res: Array<any>,
82  startNS: number,
83  endNS: number,
84  totalNS: number,
85  frame: any,
86  use: boolean
87) {
88  if (use && res.length > 0) {
89    for (let i = 0; i < res.length; i++) {
90      let diskIoAbilityItem = res[i];
91      if (
92        (diskIoAbilityItem.startNS || 0) + (diskIoAbilityItem.dur || 0) > (startNS || 0) &&
93        (diskIoAbilityItem.startNS || 0) < (endNS || 0)
94      ) {
95        DiskAbilityMonitorStruct.setDiskIOFrame(diskIoAbilityItem, 5, startNS || 0, endNS || 0, totalNS || 0, frame);
96      } else {
97        diskIoAbilityItem.frame = null;
98      }
99    }
100    return;
101  }
102  res.length = 0;
103  setDiskIoAbilityFilter(diskIoAbilityList, res, startNS || 0, endNS || 0, totalNS || 0, frame);
104}
105function setDiskIoAbilityFilter(
106  diskIoAbilityList: Array<any>,
107  res: Array<any>,
108  startNS: number,
109  endNS: number,
110  totalNS: number,
111  frame: any
112) {
113  if (diskIoAbilityList) {
114    for (let index = 0; index < diskIoAbilityList.length; index++) {
115      let item = diskIoAbilityList[index];
116      item.dur =
117        index === diskIoAbilityList.length - 1
118          ? endNS - (item.startNS || 0)
119          : (diskIoAbilityList[index + 1].startNS || 0) - (item.startNS || 0);
120      if ((item.startNS || 0) + (item.dur || 0) > startNS && (item.startNS || 0) < endNS) {
121        DiskAbilityMonitorStruct.setDiskIOFrame(diskIoAbilityList[index], 5, startNS, endNS, totalNS, frame);
122        if (
123          !(
124            index > 0 &&
125            (diskIoAbilityList[index - 1].frame.x || 0) === (diskIoAbilityList[index].frame.x || 0) &&
126            (diskIoAbilityList[index - 1].frame.width || 0) === (diskIoAbilityList[index].frame.width || 0)
127          )
128        ) {
129          res.push(item);
130        }
131      }
132    }
133  }
134}
135export class DiskAbilityMonitorStruct extends BaseStruct {
136  static maxDiskRate: number = 0;
137  static maxDiskRateName: string = '0 KB/S';
138  static hoverDiskAbilityStruct: DiskAbilityMonitorStruct | undefined;
139  static selectDiskAbilityStruct: DiskAbilityMonitorStruct | undefined;
140  value: number | undefined;
141  startNS: number | undefined;
142  dur: number | undefined; //自补充,数据库没有返回
143
144  static draw(
145    diskIoAbilityContext: CanvasRenderingContext2D,
146    diskIoAbilityData: DiskAbilityMonitorStruct,
147    maxDiskRate: number,
148    isHover: boolean
149  ) {
150    if (diskIoAbilityData.frame) {
151      let width = diskIoAbilityData.frame.width || 0;
152      let index = 2;
153      diskIoAbilityContext.fillStyle = ColorUtils.colorForTid(index);
154      diskIoAbilityContext.strokeStyle = ColorUtils.colorForTid(index);
155      if (diskIoAbilityData.startNS === DiskAbilityMonitorStruct.hoverDiskAbilityStruct?.startNS && isHover) {
156        diskIoAbilityContext.lineWidth = 1;
157        diskIoAbilityContext.globalAlpha = 0.6;
158        let drawHeight: number = Math.floor(
159          ((diskIoAbilityData.value || 0) * (diskIoAbilityData.frame.height || 0) * 1.0) / maxDiskRate
160        );
161        let y = diskIoAbilityData.frame.y + diskIoAbilityData.frame.height - drawHeight + 4;
162        diskIoAbilityContext.fillRect(diskIoAbilityData.frame.x, y, width, drawHeight);
163        diskIoAbilityContext.beginPath();
164        diskIoAbilityContext.arc(diskIoAbilityData.frame.x, y, 3, 0, 2 * Math.PI, true);
165        diskIoAbilityContext.fill();
166        diskIoAbilityContext.globalAlpha = 1.0;
167        diskIoAbilityContext.stroke();
168        diskIoAbilityContext.beginPath();
169        diskIoAbilityContext.moveTo(diskIoAbilityData.frame.x + 3, y);
170        diskIoAbilityContext.lineWidth = 3;
171        diskIoAbilityContext.lineTo(diskIoAbilityData.frame.x + width, y);
172        diskIoAbilityContext.stroke();
173      } else {
174        diskIoAbilityContext.globalAlpha = 0.6;
175        diskIoAbilityContext.lineWidth = 1;
176        let drawHeight: number = Math.floor(
177          ((diskIoAbilityData.value || 0) * (diskIoAbilityData.frame.height || 0)) / maxDiskRate
178        );
179        let y = diskIoAbilityData.frame.y + diskIoAbilityData.frame.height - drawHeight + 4;
180        diskIoAbilityContext.fillRect(diskIoAbilityData.frame.x, y, width, drawHeight);
181      }
182    }
183    diskIoAbilityContext.globalAlpha = 1.0;
184    diskIoAbilityContext.lineWidth = 1;
185  }
186
187  static setDiskIOFrame(diskIONode: any, padding: number, startNS: number, endNS: number, totalNS: number, frame: any) {
188    let diskIOStartPointX: number, diskIOEndPointX: number;
189
190    if ((diskIONode.startNS || 0) < startNS) {
191      diskIOStartPointX = 0;
192    } else {
193      diskIOStartPointX = ns2x(diskIONode.startNS || 0, startNS, endNS, totalNS, frame);
194    }
195    if ((diskIONode.startNS || 0) + (diskIONode.dur || 0) > endNS) {
196      diskIOEndPointX = frame.width;
197    } else {
198      diskIOEndPointX = ns2x((diskIONode.startNS || 0) + (diskIONode.dur || 0), startNS, endNS, totalNS, frame);
199    }
200    let frameWidth: number = diskIOEndPointX - diskIOStartPointX <= 1 ? 1 : diskIOEndPointX - diskIOStartPointX;
201    if (!diskIONode.frame) {
202      diskIONode.frame = {};
203    }
204    diskIONode.frame.x = Math.floor(diskIOStartPointX);
205    diskIONode.frame.y = frame.y + padding;
206    diskIONode.frame.width = Math.ceil(frameWidth);
207    diskIONode.frame.height = Math.floor(frame.height - padding * 2);
208  }
209}
210