summaryrefslogtreecommitdiffstats
path: root/tools/aapt/ResourceIdCache.cpp
diff options
context:
space:
mode:
authorAdam Lesinski <adamlesinski@google.com>2014-01-23 18:17:42 -0800
committerAdam Lesinski <adamlesinski@google.com>2014-01-27 10:31:04 -0800
commit282e181b58cf72b6ca770dc7ca5f91f135444502 (patch)
treee313e7ab30ff4679562efa37bde29cfcb9e375d3 /tools/aapt/ResourceIdCache.cpp
parent7023df08f14ec5dee76ac54c03e870f84e297636 (diff)
downloadframeworks_base-282e181b58cf72b6ca770dc7ca5f91f135444502.zip
frameworks_base-282e181b58cf72b6ca770dc7ca5f91f135444502.tar.gz
frameworks_base-282e181b58cf72b6ca770dc7ca5f91f135444502.tar.bz2
Revert "Move frameworks/base/tools/ to frameworks/tools/"
This reverts commit 9f6a119c8aa276432ece4fe2118bd8a3c9b1067e.
Diffstat (limited to 'tools/aapt/ResourceIdCache.cpp')
-rw-r--r--tools/aapt/ResourceIdCache.cpp107
1 files changed, 107 insertions, 0 deletions
diff --git a/tools/aapt/ResourceIdCache.cpp b/tools/aapt/ResourceIdCache.cpp
new file mode 100644
index 0000000..e03f4f6
--- /dev/null
+++ b/tools/aapt/ResourceIdCache.cpp
@@ -0,0 +1,107 @@
+//
+// 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);
+}
+
+}