1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #ifndef GrBinHashKey_DEFINED 11 #define GrBinHashKey_DEFINED 12 13 #include "GrTypes.h" 14 15 /** 16 * GrBinHashKey is a hash key class that can take a data chunk of any predetermined 17 * length. The hash function used is the One-at-a-Time Hash 18 * (http://burtleburtle.net/bob/hash/doobs.html). 19 */ 20 template<size_t KEY_SIZE> 21 class GrBinHashKey { 22 public: 23 enum { kKeySize = KEY_SIZE }; 24 GrBinHashKey()25 GrBinHashKey() { 26 this->reset(); 27 } 28 reset()29 void reset() { 30 fHash = 0; 31 #ifdef SK_DEBUG 32 fIsValid = false; 33 #endif 34 } 35 setKeyData(const uint32_t * SK_RESTRICT data)36 void setKeyData(const uint32_t* SK_RESTRICT data) { 37 SK_COMPILE_ASSERT(KEY_SIZE % 4 == 0, key_size_mismatch); 38 memcpy(&fData, data, KEY_SIZE); 39 40 uint32_t hash = 0; 41 size_t len = KEY_SIZE; 42 while (len >= 4) { 43 hash += *data++; 44 hash += (hash << 10); 45 hash ^= (hash >> 6); 46 len -= 4; 47 } 48 hash += (hash << 3); 49 hash ^= (hash >> 11); 50 hash += (hash << 15); 51 #ifdef SK_DEBUG 52 fIsValid = true; 53 #endif 54 fHash = hash; 55 } 56 57 bool operator==(const GrBinHashKey<KEY_SIZE>& key) const { 58 SkASSERT(fIsValid && key.fIsValid); 59 if (fHash != key.fHash) { 60 return false; 61 } 62 for (size_t i = 0; i < SK_ARRAY_COUNT(fData); ++i) { 63 if (fData[i] != key.fData[i]) { 64 return false; 65 } 66 } 67 return true; 68 } 69 70 bool operator<(const GrBinHashKey<KEY_SIZE>& key) const { 71 SkASSERT(fIsValid && key.fIsValid); 72 for (size_t i = 0; i < SK_ARRAY_COUNT(fData); ++i) { 73 if (fData[i] < key.fData[i]) { 74 return true; 75 } else if (fData[i] > key.fData[i]) { 76 return false; 77 } 78 } 79 return false; 80 } 81 getHash()82 uint32_t getHash() const { 83 SkASSERT(fIsValid); 84 return fHash; 85 } 86 getData()87 const uint8_t* getData() const { 88 SkASSERT(fIsValid); 89 return reinterpret_cast<const uint8_t*>(fData); 90 } 91 92 private: 93 uint32_t fHash; 94 uint32_t fData[KEY_SIZE / sizeof(uint32_t)]; // Buffer for key storage. 95 96 #ifdef SK_DEBUG 97 public: 98 bool fIsValid; 99 #endif 100 }; 101 102 #endif 103