diff options
Diffstat (limited to 'tools/aapt2/optimize/ResourcePathShortener.cpp')
-rw-r--r-- | tools/aapt2/optimize/ResourcePathShortener.cpp | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/tools/aapt2/optimize/ResourcePathShortener.cpp b/tools/aapt2/optimize/ResourcePathShortener.cpp index c5df3dd00db9..7ff9bf5aa8df 100644 --- a/tools/aapt2/optimize/ResourcePathShortener.cpp +++ b/tools/aapt2/optimize/ResourcePathShortener.cpp @@ -16,13 +16,14 @@ #include "optimize/ResourcePathShortener.h" -#include <math.h> +#include <set> #include <unordered_set> #include "androidfw/StringPiece.h" #include "ResourceTable.h" #include "ValueVisitor.h" +#include "util/Util.h" static const std::string base64_chars = @@ -50,18 +51,15 @@ std::string ShortenFileName(const android::StringPiece& file_path, int output_le } -// Calculate the optimal hash length such that an average of 10% of resources -// collide in their shortened path. +// Return the optimal hash length such that at most 10% of resources collide in +// their shortened path. // Reference: http://matt.might.net/articles/counting-hash-collisions/ int OptimalShortenedLength(int num_resources) { - int num_chars = 2; - double N = 64*64; // hash space when hash is 2 chars long - double max_collisions = num_resources * 0.1; - while (num_resources - N + N * pow((N - 1) / N, num_resources) > max_collisions) { - N *= 64; - num_chars++; + if (num_resources > 4000) { + return 3; + } else { + return 2; } - return num_chars; } std::string GetShortenedPath(const android::StringPiece& shortened_filename, @@ -74,10 +72,19 @@ std::string GetShortenedPath(const android::StringPiece& shortened_filename, return shortened_path; } +// implement custom comparator of FileReference pointers so as to use the +// underlying filepath as key rather than the integer address. This is to ensure +// determinism of output for colliding files. +struct PathComparator { + bool operator() (const FileReference* lhs, const FileReference* rhs) const { + return lhs->path->compare(*rhs->path); + } +}; + bool ResourcePathShortener::Consume(IAaptContext* context, ResourceTable* table) { // used to detect collisions std::unordered_set<std::string> shortened_paths; - std::unordered_set<FileReference*> file_refs; + std::set<FileReference*, PathComparator> file_refs; for (auto& package : table->packages) { for (auto& type : package->types) { for (auto& entry : type->entries) { @@ -95,6 +102,10 @@ bool ResourcePathShortener::Consume(IAaptContext* context, ResourceTable* table) android::StringPiece res_subdir, actual_filename, extension; util::ExtractResFilePathParts(*file_ref->path, &res_subdir, &actual_filename, &extension); + // Android detects ColorStateLists via pathname, skip res/color* + if (util::StartsWith(res_subdir, "res/color")) + continue; + std::string shortened_filename = ShortenFileName(*file_ref->path, num_chars); int collision_count = 0; std::string shortened_path = GetShortenedPath(shortened_filename, extension, collision_count); |