Home | History | Annotate | Download | only in gpu
      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 
     25     GrBinHashKey() {
     26         this->reset();
     27     }
     28 
     29     void reset() {
     30         fHash = 0;
     31 #ifdef SK_DEBUG
     32         fIsValid = false;
     33 #endif
     34     }
     35 
     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 
     82     uint32_t getHash() const {
     83         SkASSERT(fIsValid);
     84         return fHash;
     85     }
     86 
     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