blob: 585a1a1c018850503b393e4e8cd9741ca3fb839a [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
junov@google.comf93e7172011-03-31 21:26:24 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * 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.
junov@google.comf93e7172011-03-31 21:26:24 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
junov@google.comf93e7172011-03-31 21:26:24 +000010#ifndef GrBinHashKey_DEFINED
11#define GrBinHashKey_DEFINED
12
13#include "GrTypes.h"
14
15/**
rmistry@google.comd6bab022013-12-02 13:50:38 +000016 * 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).
junov@google.comf93e7172011-03-31 21:26:24 +000019 */
rmistry@google.comd6bab022013-12-02 13:50:38 +000020template<size_t KEY_SIZE>
21class GrBinHashKey {
junov@google.comf93e7172011-03-31 21:26:24 +000022public:
bsalomon@google.com0797c2c2012-12-20 15:13:01 +000023 enum { kKeySize = KEY_SIZE };
24
rmistry@google.comd6bab022013-12-02 13:50:38 +000025 GrBinHashKey() {
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000026 this->reset();
27 }
junov@google.comf93e7172011-03-31 21:26:24 +000028
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000029 void reset() {
30 fHash = 0;
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000031#ifdef SK_DEBUG
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000032 fIsValid = false;
33#endif
junov@google.comf93e7172011-03-31 21:26:24 +000034 }
35
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +000036 void setKeyData(const uint32_t* SK_RESTRICT data) {
rmistry@google.comd6bab022013-12-02 13:50:38 +000037 SK_COMPILE_ASSERT(KEY_SIZE % 4 == 0, key_size_mismatch);
bsalomon@google.com0797c2c2012-12-20 15:13:01 +000038 memcpy(&fData, data, KEY_SIZE);
junov@google.comf7c00f62011-08-18 18:15:16 +000039
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +000040 uint32_t hash = 0;
bsalomon@google.com0797c2c2012-12-20 15:13:01 +000041 size_t len = KEY_SIZE;
junov@google.comf7c00f62011-08-18 18:15:16 +000042 while (len >= 4) {
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +000043 hash += *data++;
rmistry@google.comd6bab022013-12-02 13:50:38 +000044 hash += (hash << 10);
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +000045 hash ^= (hash >> 6);
junov@google.comf7c00f62011-08-18 18:15:16 +000046 len -= 4;
junov@google.comf93e7172011-03-31 21:26:24 +000047 }
rmistry@google.comd6bab022013-12-02 13:50:38 +000048 hash += (hash << 3);
49 hash ^= (hash >> 11);
50 hash += (hash << 15);
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000051#ifdef SK_DEBUG
junov@google.comf7c00f62011-08-18 18:15:16 +000052 fIsValid = true;
53#endif
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +000054 fHash = hash;
junov@google.comf93e7172011-03-31 21:26:24 +000055 }
56
rmistry@google.comd6bab022013-12-02 13:50:38 +000057 bool operator==(const GrBinHashKey<KEY_SIZE>& key) const {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000058 SkASSERT(fIsValid && key.fIsValid);
rmistry@google.comd6bab022013-12-02 13:50:38 +000059 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;
junov@google.comf93e7172011-03-31 21:26:24 +000068 }
69
rmistry@google.comd6bab022013-12-02 13:50:38 +000070 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;
junov@google.comf93e7172011-03-31 21:26:24 +000080 }
81
82 uint32_t getHash() const {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000083 SkASSERT(fIsValid);
junov@google.comf7c00f62011-08-18 18:15:16 +000084 return fHash;
junov@google.comf93e7172011-03-31 21:26:24 +000085 }
86
bsalomon@google.com0797c2c2012-12-20 15:13:01 +000087 const uint8_t* getData() const {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000088 SkASSERT(fIsValid);
rmistry@google.comd6bab022013-12-02 13:50:38 +000089 return reinterpret_cast<const uint8_t*>(fData);
bsalomon@google.com0797c2c2012-12-20 15:13:01 +000090 }
91
junov@google.comf93e7172011-03-31 21:26:24 +000092private:
junov@google.comf7c00f62011-08-18 18:15:16 +000093 uint32_t fHash;
rmistry@google.comd6bab022013-12-02 13:50:38 +000094 uint32_t fData[KEY_SIZE / sizeof(uint32_t)]; // Buffer for key storage.
junov@google.comf93e7172011-03-31 21:26:24 +000095
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000096#ifdef SK_DEBUG
junov@google.comf93e7172011-03-31 21:26:24 +000097public:
98 bool fIsValid;
99#endif
100};
101
102#endif