blob: 06ff93180855f806d1e3af22260ce65c969ed151 [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
robertphillips3d533ac2014-07-20 09:40:00 -070013#include "SkChecksum.h"
junov@google.comf93e7172011-03-31 21:26:24 +000014#include "GrTypes.h"
15
16/**
robertphillips3d533ac2014-07-20 09:40:00 -070017 * GrMurmur3HashKey is a hash key class that can take a data chunk of any predetermined
18 * length. It uses the Murmur3 hash function. It is intended to be used with
19 * SkTDynamicHash (where GrBinHashKey is for GrTHashTable).
20 */
21template<size_t KEY_SIZE_IN_BYTES>
22class GrMurmur3HashKey {
23public:
24 GrMurmur3HashKey() {
25 this->reset();
26 }
27
28 void reset() {
29 fHash = 0;
30#ifdef SK_DEBUG
31 fIsValid = false;
32#endif
33 }
34
35 void setKeyData(const uint32_t* data) {
36 SK_COMPILE_ASSERT(KEY_SIZE_IN_BYTES % 4 == 0, key_size_mismatch);
37 memcpy(fData, data, KEY_SIZE_IN_BYTES);
38
39 fHash = SkChecksum::Murmur3(fData, KEY_SIZE_IN_BYTES);
40#ifdef SK_DEBUG
41 fIsValid = true;
42#endif
43 }
44
45 bool operator==(const GrMurmur3HashKey& other) const {
46 if (fHash != other.fHash) {
47 return false;
48 }
49
50 return !memcmp(fData, other.fData, KEY_SIZE_IN_BYTES);
51 }
52
53 uint32_t getHash() const {
54 SkASSERT(fIsValid);
55 return fHash;
56 }
57
58 const uint8_t* getData() const {
59 SkASSERT(fIsValid);
60 return reinterpret_cast<const uint8_t*>(fData);
61 }
62
63private:
64 uint32_t fHash;
65 uint32_t fData[KEY_SIZE_IN_BYTES / sizeof(uint32_t)]; // Buffer for key storage.
66
67#ifdef SK_DEBUG
68public:
69 bool fIsValid;
70#endif
71};
72
73/**
rmistry@google.comd6bab022013-12-02 13:50:38 +000074 * GrBinHashKey is a hash key class that can take a data chunk of any predetermined
75 * length. The hash function used is the One-at-a-Time Hash
76 * (http://burtleburtle.net/bob/hash/doobs.html).
junov@google.comf93e7172011-03-31 21:26:24 +000077 */
rmistry@google.comd6bab022013-12-02 13:50:38 +000078template<size_t KEY_SIZE>
79class GrBinHashKey {
junov@google.comf93e7172011-03-31 21:26:24 +000080public:
bsalomon@google.com0797c2c2012-12-20 15:13:01 +000081 enum { kKeySize = KEY_SIZE };
82
rmistry@google.comd6bab022013-12-02 13:50:38 +000083 GrBinHashKey() {
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000084 this->reset();
85 }
junov@google.comf93e7172011-03-31 21:26:24 +000086
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000087 void reset() {
88 fHash = 0;
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000089#ifdef SK_DEBUG
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000090 fIsValid = false;
91#endif
junov@google.comf93e7172011-03-31 21:26:24 +000092 }
93
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +000094 void setKeyData(const uint32_t* SK_RESTRICT data) {
rmistry@google.comd6bab022013-12-02 13:50:38 +000095 SK_COMPILE_ASSERT(KEY_SIZE % 4 == 0, key_size_mismatch);
bsalomon@google.com0797c2c2012-12-20 15:13:01 +000096 memcpy(&fData, data, KEY_SIZE);
junov@google.comf7c00f62011-08-18 18:15:16 +000097
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +000098 uint32_t hash = 0;
bsalomon@google.com0797c2c2012-12-20 15:13:01 +000099 size_t len = KEY_SIZE;
junov@google.comf7c00f62011-08-18 18:15:16 +0000100 while (len >= 4) {
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +0000101 hash += *data++;
rmistry@google.comd6bab022013-12-02 13:50:38 +0000102 hash += (hash << 10);
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +0000103 hash ^= (hash >> 6);
junov@google.comf7c00f62011-08-18 18:15:16 +0000104 len -= 4;
junov@google.comf93e7172011-03-31 21:26:24 +0000105 }
rmistry@google.comd6bab022013-12-02 13:50:38 +0000106 hash += (hash << 3);
107 hash ^= (hash >> 11);
108 hash += (hash << 15);
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000109#ifdef SK_DEBUG
junov@google.comf7c00f62011-08-18 18:15:16 +0000110 fIsValid = true;
111#endif
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +0000112 fHash = hash;
junov@google.comf93e7172011-03-31 21:26:24 +0000113 }
114
rmistry@google.comd6bab022013-12-02 13:50:38 +0000115 bool operator==(const GrBinHashKey<KEY_SIZE>& key) const {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000116 SkASSERT(fIsValid && key.fIsValid);
rmistry@google.comd6bab022013-12-02 13:50:38 +0000117 if (fHash != key.fHash) {
118 return false;
119 }
120 for (size_t i = 0; i < SK_ARRAY_COUNT(fData); ++i) {
121 if (fData[i] != key.fData[i]) {
122 return false;
123 }
124 }
125 return true;
junov@google.comf93e7172011-03-31 21:26:24 +0000126 }
127
rmistry@google.comd6bab022013-12-02 13:50:38 +0000128 bool operator<(const GrBinHashKey<KEY_SIZE>& key) const {
129 SkASSERT(fIsValid && key.fIsValid);
130 for (size_t i = 0; i < SK_ARRAY_COUNT(fData); ++i) {
131 if (fData[i] < key.fData[i]) {
132 return true;
133 } else if (fData[i] > key.fData[i]) {
134 return false;
135 }
136 }
137 return false;
junov@google.comf93e7172011-03-31 21:26:24 +0000138 }
139
140 uint32_t getHash() const {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000141 SkASSERT(fIsValid);
junov@google.comf7c00f62011-08-18 18:15:16 +0000142 return fHash;
junov@google.comf93e7172011-03-31 21:26:24 +0000143 }
144
bsalomon@google.com0797c2c2012-12-20 15:13:01 +0000145 const uint8_t* getData() const {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000146 SkASSERT(fIsValid);
rmistry@google.comd6bab022013-12-02 13:50:38 +0000147 return reinterpret_cast<const uint8_t*>(fData);
bsalomon@google.com0797c2c2012-12-20 15:13:01 +0000148 }
149
junov@google.comf93e7172011-03-31 21:26:24 +0000150private:
junov@google.comf7c00f62011-08-18 18:15:16 +0000151 uint32_t fHash;
rmistry@google.comd6bab022013-12-02 13:50:38 +0000152 uint32_t fData[KEY_SIZE / sizeof(uint32_t)]; // Buffer for key storage.
junov@google.comf93e7172011-03-31 21:26:24 +0000153
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000154#ifdef SK_DEBUG
junov@google.comf93e7172011-03-31 21:26:24 +0000155public:
156 bool fIsValid;
157#endif
158};
159
160#endif