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