Optimize filter/alias rebuilding in AssetManager2

+ make the default member of ByteBucketArray static

Bug: 237583012
Test: build + UTs

Change-Id: I94af279b7e496488b23bd12f071f5fcc7738c194
This commit is contained in:
Yurii Zubrytskyi
2022-11-03 00:08:49 -07:00
parent fbdfba51b3
commit 59dab3ba29
4 changed files with 49 additions and 32 deletions

View File

@@ -22,6 +22,7 @@
#include <iterator>
#include <map>
#include <set>
#include <span>
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
@@ -207,23 +208,30 @@ void AssetManager2::BuildDynamicRefTable() {
}
// Now assign the runtime IDs so that we have a build-time to runtime ID map.
const auto package_groups_end = package_groups_.end();
for (auto iter = package_groups_.begin(); iter != package_groups_end; ++iter) {
const std::string& package_name = iter->packages_[0].loaded_package_->GetPackageName();
for (auto iter2 = package_groups_.begin(); iter2 != package_groups_end; ++iter2) {
iter2->dynamic_ref_table->addMapping(String16(package_name.c_str(), package_name.size()),
iter->dynamic_ref_table->mAssignedPackageId);
// Add the alias resources to the dynamic reference table of every package group. Since
// staging aliases can only be defined by the framework package (which is not a shared
// library), the compile-time package id of the framework is the same across all packages
// that compile against the framework.
for (const auto& package : iter->packages_) {
for (const auto& entry : package.loaded_package_->GetAliasResourceIdMap()) {
iter2->dynamic_ref_table->addAlias(entry.first, entry.second);
}
}
DynamicRefTable::AliasMap aliases;
for (const auto& group : package_groups_) {
const std::string& package_name = group.packages_[0].loaded_package_->GetPackageName();
const auto name_16 = String16(package_name.c_str(), package_name.size());
for (auto&& inner_group : package_groups_) {
inner_group.dynamic_ref_table->addMapping(name_16,
group.dynamic_ref_table->mAssignedPackageId);
}
for (const auto& package : group.packages_) {
const auto& package_aliases = package.loaded_package_->GetAliasResourceIdMap();
aliases.insert(package_aliases.begin(), package_aliases.end());
}
}
if (!aliases.empty()) {
// Add the alias resources to the dynamic reference table of every package group. Since
// staging aliases can only be defined by the framework package (which is not a shared
// library), the compile-time package id of the framework is the same across all packages
// that compile against the framework.
for (auto& group : std::span(package_groups_.data(), package_groups_.size() - 1)) {
group.dynamic_ref_table->setAliases(aliases);
}
package_groups_.back().dynamic_ref_table->setAliases(std::move(aliases));
}
}
@@ -1347,18 +1355,17 @@ base::expected<uint32_t, NullOrIOError> AssetManager2::GetResourceId(
void AssetManager2::RebuildFilterList() {
for (PackageGroup& group : package_groups_) {
for (ConfiguredPackage& impl : group.packages_) {
// Destroy it.
impl.filtered_configs_.~ByteBucketArray();
// Re-create it.
new (&impl.filtered_configs_) ByteBucketArray<FilteredConfigGroup>();
impl.filtered_configs_.clear();
// Create the filters here.
impl.loaded_package_->ForEachTypeSpec([&](const TypeSpec& type_spec, uint8_t type_id) {
FilteredConfigGroup& group = impl.filtered_configs_.editItemAt(type_id - 1);
FilteredConfigGroup* group = nullptr;
for (const auto& type_entry : type_spec.type_entries) {
if (type_entry.config.match(configuration_)) {
group.type_entries.push_back(&type_entry);
if (!group) {
group = &impl.filtered_configs_.editItemAt(type_id - 1);
}
group->type_entries.push_back(&type_entry);
}
}
});

View File

@@ -7074,7 +7074,7 @@ void DynamicRefTable::addMapping(uint8_t buildPackageId, uint8_t runtimePackageI
}
void DynamicRefTable::addAlias(uint32_t stagedId, uint32_t finalizedId) {
mAliasId[stagedId] = finalizedId;
mAliasId[stagedId] = finalizedId;
}
status_t DynamicRefTable::lookupResourceId(uint32_t* resId) const {

View File

@@ -31,9 +31,15 @@ namespace android {
template <typename T>
class ByteBucketArray {
public:
ByteBucketArray() : default_() { memset(buckets_, 0, sizeof(buckets_)); }
ByteBucketArray() {
memset(buckets_, 0, sizeof(buckets_));
}
~ByteBucketArray() {
clear();
}
void clear() {
for (size_t i = 0; i < kNumBuckets; i++) {
if (buckets_[i] != NULL) {
delete[] buckets_[i];
@@ -84,7 +90,7 @@ class ByteBucketArray {
enum { kNumBuckets = 16, kBucketSize = 16 };
T* buckets_[kNumBuckets];
T default_;
static inline const T default_ = {};
};
} // namespace android

View File

@@ -1882,6 +1882,10 @@ public:
void addMapping(uint8_t buildPackageId, uint8_t runtimePackageId);
using AliasMap = std::map<uint32_t, uint32_t>;
void setAliases(AliasMap aliases) {
mAliasId = std::move(aliases);
}
void addAlias(uint32_t stagedId, uint32_t finalizedId);
// Returns whether or not the value must be looked up.
@@ -1896,12 +1900,12 @@ public:
return mEntries;
}
private:
uint8_t mAssignedPackageId;
uint8_t mLookupTable[256];
KeyedVector<String16, uint8_t> mEntries;
bool mAppAsLib;
std::map<uint32_t, uint32_t> mAliasId;
private:
uint8_t mLookupTable[256];
uint8_t mAssignedPackageId;
bool mAppAsLib;
KeyedVector<String16, uint8_t> mEntries;
AliasMap mAliasId;
};
bool U16StringToInt(const char16_t* s, size_t len, Res_value* outValue);