SkTDynamicHash: pick up GetKey(), Hash() from T by default.
authorcommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 2 Apr 2014 19:17:00 +0000 (19:17 +0000)
committercommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 2 Apr 2014 19:17:00 +0000 (19:17 +0000)
This also has a somewhat obscure technical benefit: it removes the
requirement that GetKey() and Hash() must be functions with external
linkage, which is required when passing a function pointer to a
template.  A future CL that's run into this problem and the obvious
simplification are about 50/50 why I'm sending this CL.

BUG=skia:
DIFFBASE= https://codereview.chromium.org/222343002/
R=bsalomon@google.com, mtklein@google.com

Author: mtklein@chromium.org

Review URL: https://codereview.chromium.org/222473002

git-svn-id: http://skia.googlecode.com/svn/trunk@14028 2bbb7eff-a529-9590-31e7-b0007b416f81

src/core/SkPictureFlat.h
src/core/SkScaledImageCache.cpp
src/core/SkTDynamicHash.h
src/gpu/GrResourceCache.h
src/gpu/GrTMultiMap.h
tests/DynamicHashTest.cpp

index f63b9c1..4928114 100644 (file)
@@ -335,9 +335,10 @@ public:
     }
 
 private:
-    // For SkTDynamicHash.
-    static const SkFlatData& Identity(const SkFlatData& flat) { return flat; }
-    static uint32_t Hash(const SkFlatData& flat) { return flat.checksum(); }
+    struct HashTraits {
+        static const SkFlatData& GetKey(const SkFlatData& flat) { return flat; }
+        static uint32_t Hash(const SkFlatData& flat) { return flat.checksum(); }
+    };
 
     void setIndex(int index) { fIndex = index; }
     uint8_t* data() { return (uint8_t*)this + sizeof(*this); }
@@ -563,7 +564,7 @@ private:
     SkTDArray<const SkFlatData*> fIndexedData;
 
     // For SkFlatData -> cached SkFlatData, which has index().
-    SkTDynamicHash<SkFlatData, SkFlatData, SkFlatData::Identity, SkFlatData::Hash> fHash;
+    SkTDynamicHash<SkFlatData, SkFlatData, SkFlatData::HashTraits> fHash;
 };
 
 typedef SkFlatDictionary<SkPaint, SkPaint::FlatteningTraits> SkPaintDictionary;
index 8320b92..1e37884 100644 (file)
@@ -116,6 +116,9 @@ struct SkScaledImageCache::Rec {
         SkSafeUnref(fMip);
     }
 
+    static const Key& GetKey(const Rec& rec) { return rec.fKey; }
+    static uint32_t Hash(const Key& key) { return key.fHash; }
+
     size_t bytesUsed() const {
         return fMip ? fMip->getSize() : fBitmap.getSize();
     }
@@ -135,21 +138,8 @@ struct SkScaledImageCache::Rec {
 
 #include "SkTDynamicHash.h"
 
-namespace { // can't use static functions w/ template parameters
-const SkScaledImageCache::Key& key_from_rec(const SkScaledImageCache::Rec& rec) {
-    return rec.fKey;
-}
-
-uint32_t hash_from_key(const SkScaledImageCache::Key& key) {
-    return key.fHash;
-}
-
-}  // namespace
-
-class SkScaledImageCache::Hash : public SkTDynamicHash<SkScaledImageCache::Rec,
-                                                       SkScaledImageCache::Key,
-                                                       key_from_rec,
-                                                       hash_from_key> {};
+class SkScaledImageCache::Hash :
+    public SkTDynamicHash<SkScaledImageCache::Rec, SkScaledImageCache::Key> {};
 
 
 ///////////////////////////////////////////////////////////////////////////////
index 0e34270..c9a0b3e 100644 (file)
 #include "SkTemplates.h"
 #include "SkTypes.h"
 
+// Traits requires:
+//   static const Key& GetKey(const T&) { ... }
+//   static uint32_t Hash(const Key&) { ... }
+// We'll look on T for these by default, or you can pass a custom Traits type.
 template <typename T,
           typename Key,
-          const Key& (GetKey)(const T&),
-          uint32_t (Hash)(const Key&),
+          typename Traits = T,
           int kGrowPercent = 75>  // Larger -> more memory efficient, but slower.
 class SkTDynamicHash {
 public:
@@ -227,6 +230,9 @@ private:
         return (index + round + 1) & this->hashMask();
     }
 
+    static const Key& GetKey(const T& t) { return Traits::GetKey(t); }
+    static uint32_t Hash(const Key& key) { return Traits::Hash(key); }
+
     int fCount;     // Number of non Empty(), non Deleted() entries in fArray.
     int fDeleted;   // Number of Deleted() entries in fArray.
     int fCapacity;  // Number of entries in fArray.  Always a power of 2.
index 26423dd..a830918 100644 (file)
@@ -315,10 +315,7 @@ private:
 
     void removeInvalidResource(GrResourceEntry* entry);
 
-    GrTMultiMap<GrResourceEntry,
-                GrResourceKey,
-                GrResourceEntry::GetKey,
-                GrResourceEntry::Hash> fCache;
+    GrTMultiMap<GrResourceEntry, GrResourceKey> fCache;
 
     // We're an internal doubly linked list
     typedef SkTInternalLList<GrResourceEntry> EntryList;
index dfa7e5e..0007a04 100644 (file)
  */
 template <typename T,
           typename Key,
-          const Key& (GetKey)(const T&),
-          uint32_t (Hash)(const Key&)>
+          typename HashTraits=T>
 class GrTMultiMap {
     struct ValueList {
         explicit ValueList(T* value) : fValue(value), fNext(NULL) {}
 
-        static const Key& ListGetKey(const ValueList& e) { return GetKey(*e.fValue); }
-        static uint32_t ListHash(const Key& key) { return Hash(key); }
+        static const Key& GetKey(const ValueList& e) { return HashTraits::GetKey(*e.fValue); }
+        static uint32_t Hash(const Key& key) { return HashTraits::Hash(key); }
         T* fValue;
         ValueList* fNext;
     };
@@ -104,10 +103,7 @@ public:
     int count() const { return fCount; }
 
 private:
-    SkTDynamicHash<ValueList,
-                   Key,
-                   ValueList::ListGetKey,
-                   ValueList::ListHash> fHash;
+    SkTDynamicHash<ValueList, Key> fHash;
     int fCount;
 };
 
index bb9367b..b2da6f3 100644 (file)
@@ -13,12 +13,13 @@ namespace {
 struct Entry {
     int key;
     double value;
+
+    static const int& GetKey(const Entry& entry) { return entry.key; }
+    static uint32_t Hash(const int& key) { return key; }
 };
 
-const int& GetKey(const Entry& entry) { return entry.key; }
-uint32_t GetHash(const int& key) { return key; }
 
-class Hash : public SkTDynamicHash<Entry, int, GetKey, GetHash> {
+class Hash : public SkTDynamicHash<Entry, int> {
 public:
     Hash() : INHERITED() {}
 
@@ -27,7 +28,7 @@ public:
     int countCollisions(const int& key) const { return this->INHERITED::countCollisions(key); }
 
 private:
-    typedef SkTDynamicHash<Entry, int, GetKey, GetHash> INHERITED;
+    typedef SkTDynamicHash<Entry, int> INHERITED;
 };
 
 }  // namespace