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 { BaseElement, element } from '../../../../../base-ui/BaseElement'; 16import { LitTable } from '../../../../../base-ui/table/lit-table'; 17import { SelectionParam } from '../../../../bean/BoxSelection'; 18import { Utils } from '../../base/Utils'; 19import { log } from '../../../../../log/Log'; 20import { Smaps, TYPE_STRING } from '../../../../bean/SmapsStruct'; 21import { MemoryConfig } from '../../../../bean/MemoryConfig'; 22import { SpSystemTrace } from '../../../SpSystemTrace'; 23import { getTabSmapsData, getTabSmapsSampleData } from '../../../../database/sql/Smaps.sql'; 24@element('tabpane-smaps-sample') 25export class TabPaneSmapsSample extends BaseElement { 26 private tblSmapsSample: LitTable | null | undefined; 27 private sourceSmapsSample: Array<Smaps> = []; 28 private querySmapsSampleResult: Array<Smaps> = []; 29 private isClick = false; 30 private tabTitle: HTMLDivElement | undefined | null; 31 set data(valSmapsSample: SelectionParam) { 32 this.parentElement!.style.overflow = 'unset'; 33 this.isClick = valSmapsSample.smapsType.length === 0; 34 this.init(); 35 this.tblSmapsSample!.loading = true; 36 if (!this.isClick) { 37 if (valSmapsSample.smapsType.length > 0) { 38 this.queryDataByDB(valSmapsSample); 39 } 40 } else { 41 this.setSmaps(valSmapsSample); 42 } 43 } 44 initElements(): void { 45 this.tblSmapsSample = this.shadowRoot?.querySelector<LitTable>('#tb-smaps-record'); 46 this.tabTitle = this.tblSmapsSample!.shadowRoot?.querySelector('.thead') as HTMLDivElement; 47 this.tblSmapsSample!.addEventListener('column-click', (evt) => { 48 // @ts-ignore 49 this.sortByColumn(evt.detail); 50 }); 51 } 52 connectedCallback(): void { 53 super.connectedCallback(); 54 new ResizeObserver(() => { 55 if (this.parentElement?.clientHeight !== 0) { 56 // @ts-ignore 57 this.tblSmapsSample?.shadowRoot?.querySelector('.table').style.height = 58 this.parentElement!.clientHeight - 15 + 'px'; 59 this.tblSmapsSample?.reMeauseHeight(); 60 } 61 }).observe(this.parentElement!); 62 } 63 queryDataByDB(srVal: SelectionParam | unknown): void { 64 // @ts-ignore 65 getTabSmapsData(srVal.leftNs, srVal.rightNs, (MemoryConfig.getInstance().interval * 1000_000) / 5).then( 66 (result) => { 67 log('getTabSmapsData size :' + result.length); 68 this.tblSmapsSample!.loading = false; 69 this.filteredData(result); 70 } 71 ); 72 } 73 setSmaps(data: SelectionParam): void { 74 getTabSmapsSampleData(data.leftNs).then((result) => { 75 this.tblSmapsSample!.loading = false; 76 this.filteredData(result); 77 }); 78 } 79 private init(): void { 80 const thTable = this.tabTitle!.querySelector('.th'); 81 const smapsSampleTblNodes = thTable!.querySelectorAll('div'); 82 if (this.tabTitle!.hasAttribute('sort')) { 83 this.tabTitle!.removeAttribute('sort'); 84 smapsSampleTblNodes.forEach((item) => { 85 item.querySelectorAll('svg').forEach((svg) => { 86 svg.style.display = 'none'; 87 }); 88 }); 89 } 90 } 91 filteredData(result: unknown): void { 92 // @ts-ignore 93 if (result.length !== null && result.length > 0) { 94 // @ts-ignore 95 for (const smaps of result) { 96 smaps.typeName = TYPE_STRING[smaps.type]; 97 smaps.address = smaps.startAddr + ' - ' + smaps.endAddr; 98 smaps.swapStr = Utils.getBinaryByteWithUnit(smaps.swap); 99 smaps.rssStr = Utils.getBinaryByteWithUnit(smaps.rss); 100 smaps.pssStr = Utils.getBinaryByteWithUnit(smaps.pss); 101 smaps.sizeStr = Utils.getBinaryByteWithUnit(smaps.size); 102 smaps.sharedCleanStr = Utils.getBinaryByteWithUnit(smaps.sharedClean); 103 smaps.sharedDirtyStr = Utils.getBinaryByteWithUnit(smaps.sharedDirty); 104 smaps.privateCleanStr = Utils.getBinaryByteWithUnit(smaps.privateClean); 105 smaps.privateDirtyStr = Utils.getBinaryByteWithUnit(smaps.privateDirty); 106 smaps.swapPssStr = Utils.getBinaryByteWithUnit(smaps.swapPss); 107 smaps.time = Utils.getTimeString(smaps.startNs); 108 smaps.path = SpSystemTrace.DATA_DICT.get(smaps.path)?.split('/'); 109 smaps.permission = SpSystemTrace.DATA_DICT.get(smaps.pid)?.split('/'); 110 let resideS = smaps.reside.toFixed(2); 111 if (resideS === '0.00') { 112 smaps.resideStr = '0%'; 113 } else { 114 smaps.resideStr = resideS + '%'; 115 } 116 } 117 // @ts-ignore 118 this.sourceSmapsSample = result; 119 // @ts-ignore 120 this.querySmapsSampleResult = result; 121 this.tblSmapsSample!.recycleDataSource = this.sourceSmapsSample; 122 } else { 123 this.sourceSmapsSample = []; 124 this.querySmapsSampleResult = []; 125 this.tblSmapsSample!.recycleDataSource = []; 126 } 127 } 128 initHtml(): string { 129 return ` 130 <style> 131 :host{ 132 padding: 10px 10px; 133 display: flex; 134 flex-direction: column; 135 } 136 .smaps-record-table{ 137 height: auto; 138 } 139 </style> 140 <lit-table id="tb-smaps-record" class="smaps-record-table" style="overflow: auto"> 141 <lit-table-column order width="100px" title="TimeStamp" data-index="time" key="time" align="flex-start" > 142 </lit-table-column> 143 <lit-table-column order width="150px" title="Type" data-index="typeName" key="typeName" align="flex-start" > 144 </lit-table-column> 145 <lit-table-column order width="150px" title="Path" data-index="path" key="path" align="flex-start" > 146 </lit-table-column> 147 <lit-table-column order width="250px" title="Address Range" data-index="address" key="address" align="flex-start" > 148 </lit-table-column> 149 <lit-table-column order width="150px" title="Rss" data-index="rssStr" key="rssStr" align="flex-start" > 150 </lit-table-column> 151 <lit-table-column order width="150px" title="Pss" data-index="pssStr" key="pssStr" align="flex-start" > 152 </lit-table-column> 153 <lit-table-column width="150px" title="SharedClean" data-index="sharedCleanStr" key="sharedCleanStr" align="flex-start" order> 154 </lit-table-column> 155 <lit-table-column width="150px" title="SharedDirty" data-index="sharedDirtyStr" key="sharedDirtyStr" align="flex-start" order> 156 </lit-table-column> 157 <lit-table-column width="150px" title="PrivateClean" data-index="privateCleanStr" key="privateCleanStr" align="flex-start" order> 158 </lit-table-column> 159 <lit-table-column width="150px" title="PrivateDirty" data-index="privateDirtyStr" key="privateDirtyStr" align="flex-start" order> 160 </lit-table-column> 161 <lit-table-column width="150px" title="Swap" data-index="swapStr" key="swapStr" align="flex-start" order> 162 </lit-table-column> 163 <lit-table-column width="150px" title="SwapPss" data-index="swapPssStr" key="swapPssStr" align="flex-start" order> 164 </lit-table-column> 165 <lit-table-column order width="150px" title="Reside" data-index="resideStr" key="resideStr" align="flex-start" > 166 </lit-table-column> 167 <lit-table-column order width="150px" title="Protection" data-index="permission" key="permission" align="flex-start" > 168 </lit-table-column> 169 </lit-table> 170 `; 171 } 172 sortByColumn(detail: unknown): void { 173 // @ts-ignore 174 function compare(property, sort, type) { 175 return function (aSmapsSample: Smaps, bSmapsSample: Smaps) { 176 if (type === 'number') { 177 // @ts-ignore 178 return sort === 2 179 ? // @ts-ignore 180 parseFloat(bSmapsSample[property]) - parseFloat(aSmapsSample[property]) 181 : // @ts-ignore 182 parseFloat(aSmapsSample[property]) - parseFloat(bSmapsSample[property]); 183 } else { 184 // @ts-ignore 185 if (bSmapsSample[property] > aSmapsSample[property]) { 186 return sort === 2 ? 1 : -1; 187 } else { 188 // @ts-ignore 189 if (bSmapsSample[property] === aSmapsSample[property]) { 190 return 0; 191 } else { 192 return sort === 2 ? -1 : 1; 193 } 194 } 195 } 196 }; 197 } 198 // @ts-ignore 199 if (detail.key === 'rssStr' || detail.key === 'sizeStr' || detail.key === 'resideStr') { 200 // @ts-ignore 201 let key = detail.key.substring(0, detail.key.indexOf('Str')); 202 // @ts-ignore 203 this.sourceSmapsSample.sort(compare(key, detail.sort, 'number')); 204 } else { 205 // @ts-ignore 206 this.sourceSmapsSample.sort(compare(detail.key, detail.sort, 'string')); 207 } 208 this.tblSmapsSample!.recycleDataSource = this.sourceSmapsSample; 209 } 210} 211