computeHistogram function
Construct the histogram of specific type
given a ProgramInfo.
filter
glob can be provided to skip some of the nodes in the info
:
a string is created which contains library name, class name and function
name for the given node and if this string does not match the filter
glob then this node is ignored.
Implementation
Histogram computeHistogram(ProgramInfo info, HistogramType type,
{String? filter}) {
bool Function(String, String?, String?) matchesFilter;
if (filter != null) {
final re = RegExp(filter.replaceAll('*', '.*'), caseSensitive: false);
matchesFilter =
(lib, cls, fun) => re.hasMatch("$lib::${cls ?? ''}.${fun ?? ''}");
} else {
matchesFilter = (_, __, ___) => true;
}
if (type == HistogramType.byNodeType) {
final Set<int> filteredNodes = {};
if (filter != null) {
info.visit((pkg, lib, cls, fun, node) {
if (matchesFilter(lib, cls, fun)) {
filteredNodes.add(node.id);
}
});
}
final snapshotInfo = info.snapshotInfo!;
return Histogram.fromIterable<Node>(
snapshotInfo.snapshot.nodes.where((n) =>
filter == null ||
filteredNodes.contains(snapshotInfo.ownerOf(n).id)),
sizeOf: (n) {
return n.selfSize;
},
bucketFor: (n) => n.type,
bucketInfo: const BucketInfo(nameComponents: ['Type']));
} else {
final buckets = <String, int>{};
final bucketing = Bucketing._forType[type]!;
info.visit((pkg, lib, cls, fun, node) {
final sz = node.size;
if (sz == null || sz == 0) {
return;
}
if (!matchesFilter(lib, cls, fun)) {
return;
}
final bucket = bucketing.bucketFor(pkg, lib, cls, fun);
buckets[bucket] = (buckets[bucket] ?? 0) + sz;
});
return Histogram._(bucketing, buckets);
}
}