2 // Copyright 2012 The Android Open Source Project
4 // Manage a resource ID cache.
6 #define LOG_TAG "ResourceIdCache"
8 #include <utils/String16.h>
10 #include "ResourceIdCache.h"
13 static size_t mHits = 0;
14 static size_t mMisses = 0;
15 static size_t mCollisions = 0;
17 static const size_t MAX_CACHE_ENTRIES = 2048;
18 static const android::String16 TRUE16("1");
19 static const android::String16 FALSE16("0");
22 // concatenation of the relevant strings into a single instance
23 android::String16 hashedName;
27 CacheEntry(const android::String16& name, uint32_t resId) : hashedName(name), id(resId) { }
30 static std::map< uint32_t, CacheEntry > mIdMap;
33 // djb2; reasonable choice for strings when collisions aren't particularly important
34 static inline uint32_t hashround(uint32_t hash, int c) {
35 return ((hash << 5) + hash) + c; /* hash * 33 + c */
38 static uint32_t hash(const android::String16& hashableString) {
40 const char16_t* str = hashableString.string();
41 while (int c = *str++) hash = hashround(hash, c);
47 static inline String16 makeHashableName(const android::String16& package,
48 const android::String16& type,
49 const android::String16& name,
51 String16 hashable = String16(name);
54 hashable += (onlyPublic ? TRUE16 : FALSE16);
58 uint32_t ResourceIdCache::lookup(const android::String16& package,
59 const android::String16& type,
60 const android::String16& name,
62 const String16 hashedName = makeHashableName(package, type, name, onlyPublic);
63 const uint32_t hashcode = hash(hashedName);
64 std::map<uint32_t, CacheEntry>::iterator item = mIdMap.find(hashcode);
65 if (item == mIdMap.end()) {
72 if (hashedName == (*item).second.hashedName) {
74 return (*item).second.id;
79 mIdMap.erase(hashcode);
83 // returns the resource ID being stored, for callsite convenience
84 uint32_t ResourceIdCache::store(const android::String16& package,
85 const android::String16& type,
86 const android::String16& name,
89 if (mIdMap.size() < MAX_CACHE_ENTRIES) {
90 const String16 hashedName = makeHashableName(package, type, name, onlyPublic);
91 const uint32_t hashcode = hash(hashedName);
92 mIdMap[hashcode] = CacheEntry(hashedName, resId);
97 void ResourceIdCache::dump() {
98 printf("ResourceIdCache dump:\n");
99 printf("Size: %zd\n", mIdMap.size());
100 printf("Hits: %zd\n", mHits);
101 printf("Misses: %zd\n", mMisses);
102 printf("(Collisions: %zd)\n", mCollisions);