[fx blobstats] Update to account for changed location of package manifests.
Change-Id: I6c10e87659eb040fe852a4b9375df7da5fbe7240
diff --git a/devshell/blobstats.dart b/devshell/blobstats.dart
index d92f3fa..6604096 100644
--- a/devshell/blobstats.dart
+++ b/devshell/blobstats.dart
@@ -45,11 +45,19 @@
}
}
+ Future<String> computeHash(String path) async {
+ return (await Process.run("shasum", [path])).stdout.substring(0, 40);
+ }
+
Future computeBlobs() async {
while (!pendingFiles.isEmpty) {
var file = pendingFiles.removeLast();
var path = file.path;
+ if (path.endsWith("meta.far")) {
+ pendingPackages.add(file);
+ }
+
if (suffix != null && !path.endsWith(suffix)) {
continue;
}
@@ -61,9 +69,7 @@
}
var size = stat.size;
- var hash = (await Process.run("shasum", [path])).stdout.substring(0, 40);
-
- duplicatedSize += size;
+ var hash = await computeHash(path);
var blob = blobsByHash[hash];
if (blob == null) {
@@ -71,11 +77,8 @@
blob.hash = hash;
blob.path = path;
blob.size = size;
- blob.count = 1;
+ blob.count = 0;
blobsByHash[hash] = blob;
- deduplicatedSize += size;
- } else {
- blob.count++;
}
}
}
@@ -133,16 +136,19 @@
print(" $percent% $deduplicatedSize / $duplicatedSize");
}
- void computePackagesInParallel(int jobs) async {
- var manifests = await buildDir
- .list(recursive: true)
- .where((manifest) => manifest.path.endsWith("final_package_manifest"))
- .toList();
- pendingPackages.addAll(manifests);
+ String farToManifest(String farPath) {
+ // Assumes details of //build/package.gni, namely that it generates
+ // <build-dir>/.../<package>.manifest
+ // <build-dir>/.../<package>.meta/meta.far
+ // and puts meta.far into
+ // <build-dir>/blobs.manifest
+ if (!farPath.endsWith(".meta/meta.far")) {
+ throw "Build details have changed";
+ }
+ return farPath.substring(0, farPath.length - ".meta/meta.far".length) + ".manifest";
+ }
- // The part of the system not yet in packages:
- pendingPackages.add(new File(buildDir.path + "blob.manifest"));
-
+ Future computePackagesInParallel(int jobs) async {
var tasks = new List<Future>();
for (var i = 0; i < jobs; i++) {
tasks.add(computePackages());
@@ -152,46 +158,61 @@
void computePackages() async {
while (!pendingPackages.isEmpty) {
- var manifest = pendingPackages.removeLast();
+ File far = pendingPackages.removeLast();
- var pkg = new Package();
- pkg.name = manifest.path.substring(buildDir.path.length);
- pkg.size = 0;
- pkg.proportional = 0;
- pkg.private = 0;
- pkg.blobCount = 0;
- pkg.blobsByPath = new Map<String, Blob>();
+ var package = new Package();
+ package.name = far.path.substring(buildDir.path.length);
+ package.size = 0;
+ package.proportional = 0;
+ package.private = 0;
+ package.blobCount = 0;
+ package.blobsByPath = new Map<String, Blob>();
- for (var line in await manifest.readAsLines()) {
- var file = new File(buildDir.path + line.split("=").last);
- var path = file.path;
+ for (var line in await new File(farToManifest(far.path)).readAsLines()) {
+ var path = line.split("=").last;
if (suffix != null && !path.endsWith(suffix)) {
continue;
}
- if (path.contains("/meta/") ||
- path.endsWith("legacy_flat_exported_dir")) {
- // Why are these in the package manifests but not the final manifest?
- continue;
- }
-
- var hash = (await Process.run("shasum", [path])).stdout.substring(0, 40);
+ var hash = await computeHash(path);
var blob = blobsByHash[hash];
if (blob == null) {
print("$path is in a package manifest but not the final manifest");
continue;
}
- pkg.size += blob.size;
- pkg.proportional += blob.proportional;
- if (blob.count == 1) {
- pkg.private += blob.size;
- }
- pkg.blobCount++;
- pkg.blobsByPath[path] = blob;
+
+ blob.count++;
+ package.blobsByPath[path] = blob;
}
- if (pkg.size != 0) {
- packages.add(pkg);
+ packages.add(package);
+ }
+ }
+
+ void computeStats() {
+ var filteredBlobs = new Map<String, Blob>();
+ blobsByHash.forEach((hash, blob) {
+ if (blob.count == 0) {
+ print("${blob.path} is in the final manifest but not any package manifest");
+ } else {
+ filteredBlobs[hash] = blob;
+ }
+ });
+ blobsByHash = filteredBlobs;
+
+ for (var blob in blobsByHash.values) {
+ duplicatedSize += (blob.size * blob.count);
+ deduplicatedSize += blob.size;
+ }
+
+ for (var package in packages) {
+ for (var blob in package.blobsByPath.values) {
+ package.size += blob.size;
+ package.proportional += blob.proportional;
+ if (blob.count == 1) {
+ package.private += blob.size;
+ }
+ package.blobCount++;
}
}
}
@@ -201,15 +222,15 @@
print("");
print("Packages by proportional (${packages.length})");
print(" Size Prop Private Path");
- for (var pkg in packages) {
+ for (var package in packages) {
var sb = new StringBuffer();
- sb.write(pkg.size.toString().padLeft(9));
+ sb.write(package.size.toString().padLeft(9));
sb.write(" ");
- sb.write(pkg.proportional.toString().padLeft(9));
+ sb.write(package.proportional.toString().padLeft(9));
sb.write(" ");
- sb.write(pkg.private.toString().padLeft(9));
+ sb.write(package.private.toString().padLeft(9));
sb.write(" ");
- sb.write(pkg.name);
+ sb.write(package.name);
print(sb);
}
}
@@ -272,12 +293,11 @@
}
var stats = new BlobStats(await getBuildDir(), suffix);
- await stats.addManifest("packages_blobs.manifest");
await stats.addManifest("blob.manifest");
await stats.computeBlobsInParallel(Platform.numberOfProcessors);
- stats.printBlobs(40);
-
await stats.computePackagesInParallel(Platform.numberOfProcessors);
+ stats.computeStats();
+ stats.printBlobs(40);
stats.printPackages();
await stats.packagesToChromiumBinarySizeTree();
}