Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85e49ba0 authored by Yurii Zubrytskyi's avatar Yurii Zubrytskyi
Browse files

[res] Optimize locale comparison and alias search

1. Locale comparison doesn't need to happen if the locales
   aren't set at all, and an early check skips the function
   call overhead

2. Staging resource aliases only exist for Framework resources,
   and are constrained to a pretty short range. Given that
   the binary search in STL doesn't check for the value to be
   inside the array, most of the alias searches end up hitting
   the worst case with the full log2(n) of halvings before they
   fail to find it. An early check speeds up the resource
   lookups by a whopping 10-15%.

Bug: 345562237
Test: build, boot, atest + performance tests
Change-Id: Ifd2c12c74df4b21a81609102291e6aabe38c2670
parent 8fb681e6
Loading
Loading
Loading
Loading
+22 −19
Original line number Original line Diff line number Diff line
@@ -2650,8 +2650,9 @@ bool ResTable_config::isBetterThan(const ResTable_config& o,
                return (mnc);
                return (mnc);
            }
            }
        }
        }

        // Cheaper to check for the empty locales here before calling the function
        if (isLocaleBetterThan(o, requested)) {
        // as we often can skip it completely.
        if (requested->locale && (locale || o.locale) && isLocaleBetterThan(o, requested)) {
            return true;
            return true;
        }
        }


@@ -7237,37 +7238,39 @@ void DynamicRefTable::addMapping(uint8_t buildPackageId, uint8_t runtimePackageI


status_t DynamicRefTable::lookupResourceId(uint32_t* resId) const {
status_t DynamicRefTable::lookupResourceId(uint32_t* resId) const {
    uint32_t res = *resId;
    uint32_t res = *resId;
    size_t packageId = Res_GETPACKAGE(res) + 1;

    if (!Res_VALIDID(res)) {
    if (!Res_VALIDID(res)) {
        // Cannot look up a null or invalid id, so no lookup needs to be done.
        // Cannot look up a null or invalid id, so no lookup needs to be done.
        return NO_ERROR;
        return NO_ERROR;
    }
    }

    const size_t packageId = Res_GETPACKAGE(res) + 1;
    if (packageId == 0 || (packageId == APP_PACKAGE_ID && mAppAsLib)) {
        // The package ID is 0x00. That means that a shared library is accessing
        // its own local resource.
        // Or if app resource is loaded as shared library, the resource which has
        // app package Id is local resources.
        // so we fix up those resources with the calling package ID.
        *resId = (0xFFFFFF & (*resId)) | (((uint32_t) mAssignedPackageId) << 24);
        return NO_ERROR;
    }
    // All aliases are coming from the framework, and usually have their own separate ID range,
    // skipping the whole binary search is much more efficient than not finding anything.
    if (packageId == SYS_PACKAGE_ID && !mAliasId.empty() &&
            res >= mAliasId.front().first && res <= mAliasId.back().first) {
        const auto alias_it = std::lower_bound(mAliasId.begin(), mAliasId.end(), res,
        const auto alias_it = std::lower_bound(mAliasId.begin(), mAliasId.end(), res,
        [](const AliasMap::value_type& pair, uint32_t val) { return pair.first < val; });
                                               [](const AliasMap::value_type& pair,
                                                  uint32_t val) { return pair.first < val; });
        if (alias_it != mAliasId.end() && alias_it->first == res) {
        if (alias_it != mAliasId.end() && alias_it->first == res) {
            // Rewrite the resource id to its alias resource id. Since the alias resource id is a
            // Rewrite the resource id to its alias resource id. Since the alias resource id is a
            // compile-time id, it still needs to be resolved further.
            // compile-time id, it still needs to be resolved further.
            res = alias_it->second;
            res = alias_it->second;
        }
        }

    }
    if (packageId == SYS_PACKAGE_ID || (packageId == APP_PACKAGE_ID && !mAppAsLib)) {
    if (packageId == SYS_PACKAGE_ID || (packageId == APP_PACKAGE_ID && !mAppAsLib)) {
        // No lookup needs to be done, app and framework package IDs are absolute.
        // No lookup needs to be done, app and framework package IDs are absolute.
        *resId = res;
        *resId = res;
        return NO_ERROR;
        return NO_ERROR;
    }
    }


    if (packageId == 0 || (packageId == APP_PACKAGE_ID && mAppAsLib)) {
        // The package ID is 0x00. That means that a shared library is accessing
        // its own local resource.
        // Or if app resource is loaded as shared library, the resource which has
        // app package Id is local resources.
        // so we fix up those resources with the calling package ID.
        *resId = (0xFFFFFF & (*resId)) | (((uint32_t) mAssignedPackageId) << 24);
        return NO_ERROR;
    }

    // Do a proper lookup.
    // Do a proper lookup.
    uint8_t translatedId = mLookupTable[packageId];
    uint8_t translatedId = mLookupTable[packageId];
    if (translatedId == 0) {
    if (translatedId == 0) {