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

Commit 217fe28d authored by Ricardo Cerqueira's avatar Ricardo Cerqueira Committed by Gerrit Code Review
Browse files

Merge "Cache resource ID lookups in aapt" into mr1-staging

parents a97412e4 d20108d0
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ LOCAL_SRC_FILES := \
	StringPool.cpp \
	StringPool.cpp \
	XMLNode.cpp \
	XMLNode.cpp \
	ResourceFilter.cpp \
	ResourceFilter.cpp \
	ResourceIdCache.cpp \
	ResourceTable.cpp \
	ResourceTable.cpp \
	Images.cpp \
	Images.cpp \
	Resource.cpp \
	Resource.cpp \
+107 −0
Original line number Original line Diff line number Diff line
//
// Copyright 2012 The Android Open Source Project
//
// Manage a resource ID cache.

#define LOG_TAG "ResourceIdCache"

#include <utils/String16.h>
#include <utils/Log.h>
#include "ResourceIdCache.h"
#include <map>
using namespace std;


static size_t mHits = 0;
static size_t mMisses = 0;
static size_t mCollisions = 0;

static const size_t MAX_CACHE_ENTRIES = 2048;
static const android::String16 TRUE16("1");
static const android::String16 FALSE16("0");

struct CacheEntry {
    // concatenation of the relevant strings into a single instance
    android::String16 hashedName;
    uint32_t id;

    CacheEntry() {}
    CacheEntry(const android::String16& name, uint32_t resId) : hashedName(name), id(resId) { }
};

static map< uint32_t, CacheEntry > mIdMap;


// djb2; reasonable choice for strings when collisions aren't particularly important
static inline uint32_t hashround(uint32_t hash, int c) {
    return ((hash << 5) + hash) + c;    /* hash * 33 + c */
}

static uint32_t hash(const android::String16& hashableString) {
    uint32_t hash = 5381;
    const char16_t* str = hashableString.string();
    while (int c = *str++) hash = hashround(hash, c);
    return hash;
}

namespace android {

static inline String16 makeHashableName(const android::String16& package,
        const android::String16& type,
        const android::String16& name,
        bool onlyPublic) {
    String16 hashable = String16(name);
    hashable += type;
    hashable += package;
    hashable += (onlyPublic ? TRUE16 : FALSE16);
    return hashable;
}

uint32_t ResourceIdCache::lookup(const android::String16& package,
        const android::String16& type,
        const android::String16& name,
        bool onlyPublic) {
    const String16 hashedName = makeHashableName(package, type, name, onlyPublic);
    const uint32_t hashcode = hash(hashedName);
    map<uint32_t, CacheEntry>::iterator item = mIdMap.find(hashcode);
    if (item == mIdMap.end()) {
        // cache miss
        mMisses++;
        return 0;
    }

    // legit match?
    if (hashedName == (*item).second.hashedName) {
        mHits++;
        return (*item).second.id;
    }

    // collision
    mCollisions++;
    mIdMap.erase(hashcode);
    return 0;
}

// returns the resource ID being stored, for callsite convenience
uint32_t ResourceIdCache::store(const android::String16& package,
        const android::String16& type,
        const android::String16& name,
        bool onlyPublic,
        uint32_t resId) {
    if (mIdMap.size() < MAX_CACHE_ENTRIES) {
        const String16 hashedName = makeHashableName(package, type, name, onlyPublic);
        const uint32_t hashcode = hash(hashedName);
        mIdMap[hashcode] = CacheEntry(hashedName, resId);
    }
    return resId;
}

void ResourceIdCache::dump() {
    printf("ResourceIdCache dump:\n");
    printf("Size: %ld\n", mIdMap.size());
    printf("Hits:   %ld\n", mHits);
    printf("Misses: %ld\n", mMisses);
    printf("(Collisions: %ld)\n", mCollisions);
}

}
+30 −0
Original line number Original line Diff line number Diff line
//
// Copyright 2012 The Android Open Source Project
//
// Manage a resource ID cache.

#ifndef RESOURCE_ID_CACHE_H
#define RESOURCE_ID_CACHE_H

namespace android {
class android::String16;

class ResourceIdCache {
public:
    static uint32_t lookup(const android::String16& package,
            const android::String16& type,
            const android::String16& name,
            bool onlyPublic);

    static uint32_t store(const android::String16& package,
            const android::String16& type,
            const android::String16& name,
            bool onlyPublic,
            uint32_t resId);

    static void dump(void);
};

}

#endif
+10 −5
Original line number Original line Diff line number Diff line
@@ -9,6 +9,7 @@


#include "XMLNode.h"
#include "XMLNode.h"
#include "ResourceFilter.h"
#include "ResourceFilter.h"
#include "ResourceIdCache.h"


#include <androidfw/ResourceTypes.h>
#include <androidfw/ResourceTypes.h>
#include <utils/ByteOrder.h>
#include <utils/ByteOrder.h>
@@ -1999,6 +2000,9 @@ uint32_t ResourceTable::getResId(const String16& package,
                                 const String16& name,
                                 const String16& name,
                                 bool onlyPublic) const
                                 bool onlyPublic) const
{
{
    uint32_t id = ResourceIdCache::lookup(package, type, name, onlyPublic);
    if (id != 0) return id;     // cache hit

    sp<Package> p = mPackages.valueFor(package);
    sp<Package> p = mPackages.valueFor(package);
    if (p == NULL) return 0;
    if (p == NULL) return 0;


@@ -2017,11 +2021,10 @@ uint32_t ResourceTable::getResId(const String16& package,
        }
        }
        
        
        if (Res_INTERNALID(rid)) {
        if (Res_INTERNALID(rid)) {
            return rid;
            return ResourceIdCache::store(package, type, name, onlyPublic, rid);
        }
        }
        return Res_MAKEID(p->getAssignedId()-1,
        return ResourceIdCache::store(package, type, name, onlyPublic,
                          Res_GETTYPE(rid),
                Res_MAKEID(p->getAssignedId()-1, Res_GETTYPE(rid), Res_GETENTRY(rid)));
                          Res_GETENTRY(rid));
    }
    }


    sp<Type> t = p->getTypes().valueFor(type);
    sp<Type> t = p->getTypes().valueFor(type);
@@ -2030,7 +2033,9 @@ uint32_t ResourceTable::getResId(const String16& package,
    if (c == NULL) return 0;
    if (c == NULL) return 0;
    int32_t ei = c->getEntryIndex();
    int32_t ei = c->getEntryIndex();
    if (ei < 0) return 0;
    if (ei < 0) return 0;
    return getResId(p, t, ei);

    return ResourceIdCache::store(package, type, name, onlyPublic,
            getResId(p, t, ei));
}
}


uint32_t ResourceTable::getResId(const String16& ref,
uint32_t ResourceTable::getResId(const String16& ref,