-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Expand file tree
/
Copy pathHeapSnapshotFormatter.ts
More file actions
97 lines (82 loc) · 2.45 KB
/
HeapSnapshotFormatter.ts
File metadata and controls
97 lines (82 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import type {AggregatedInfoWithUid} from '../HeapSnapshotManager.js';
import type {DevTools} from '../third_party/index.js';
import {stableIdSymbol} from '../utils/id.js';
export interface FormattedSnapshotEntry {
className: string;
classUid?: number;
count: number;
selfSize: number;
retainedSize: number;
}
function isNodeLike(
item: unknown,
): item is DevTools.HeapSnapshotModel.HeapSnapshotModel.Node {
return (
typeof item === 'object' && item !== null && 'id' in item && 'name' in item
);
}
export class HeapSnapshotFormatter {
#aggregates: Record<string, AggregatedInfoWithUid>;
constructor(aggregates: Record<string, AggregatedInfoWithUid>) {
this.#aggregates = aggregates;
}
static formatNodes(
items: ReadonlyArray<
| DevTools.HeapSnapshotModel.HeapSnapshotModel.Node
| DevTools.HeapSnapshotModel.HeapSnapshotModel.Edge
>,
): string {
const lines: string[] = [];
if (items.length > 0 && isNodeLike(items[0])) {
lines.push('id,name,type,distance,selfSize,retainedSize');
}
for (const item of items) {
if (isNodeLike(item)) {
lines.push(
`${item.id},"${item.name}",${item.type},${item.distance},${item.selfSize},${item.retainedSize}`,
);
}
}
return lines.join('\n');
}
#getSortedAggregates(): AggregatedInfoWithUid[] {
return Object.values(this.#aggregates).sort((a, b) => b.self - a.self);
}
toString(): string {
const sorted = this.#getSortedAggregates();
const lines: string[] = [];
lines.push('uid,className,count,selfSize,maxRetainedSize');
for (const info of sorted) {
const uid = info[stableIdSymbol] ?? '';
lines.push(
`${uid},"${info.name}",${info.count},${info.self},${info.maxRet}`,
);
}
return lines.join('\n');
}
toJSON(): FormattedSnapshotEntry[] {
const sorted = this.#getSortedAggregates();
return sorted.map(info => ({
uid: info[stableIdSymbol],
className: info.name,
count: info.count,
selfSize: info.self,
retainedSize: info.maxRet,
}));
}
static sort(
aggregates: Record<
string,
DevTools.HeapSnapshotModel.HeapSnapshotModel.AggregatedInfo
>,
): Array<
[string, DevTools.HeapSnapshotModel.HeapSnapshotModel.AggregatedInfo]
> {
return Object.entries(aggregates).sort((a, b) => b[1].self - a[1].self);
}
}