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
}
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); }
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;
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();
}
#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> {};
///////////////////////////////////////////////////////////////////////////////
#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:
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.
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;
*/
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;
};
int count() const { return fCount; }
private:
- SkTDynamicHash<ValueList,
- Key,
- ValueList::ListGetKey,
- ValueList::ListHash> fHash;
+ SkTDynamicHash<ValueList, Key> fHash;
int fCount;
};
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() {}
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