blob: d2194e9471c169f82ce33b90be4781c237ebd6c3 [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/**
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000016 * Hash function class that can take a data chunk of any predetermined length. The hash function
17 * used is the One-at-a-Time Hash (http://burtleburtle.net/bob/hash/doobs.html).
18 *
19 * Keys are computed from Entry objects. Entry must be fully ordered by a member:
20 * int compare(const GrTBinHashKey<Entry, ..>& k);
21 * which returns negative if the Entry < k, 0 if it equals k, and positive if k < the Entry.
22 * Additionally, Entry must be flattenable into the key using setKeyData.
23 *
24 * This class satisfies the requirements to be a key for a GrTHashTable.
junov@google.comf93e7172011-03-31 21:26:24 +000025 */
junov@google.comf7c00f62011-08-18 18:15:16 +000026template<typename Entry, size_t KeySize>
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000027class GrTBinHashKey {
junov@google.comf93e7172011-03-31 21:26:24 +000028public:
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000029 GrTBinHashKey() {
30 this->reset();
31 }
junov@google.comf93e7172011-03-31 21:26:24 +000032
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000033 GrTBinHashKey(const GrTBinHashKey<Entry, KeySize>& other) {
junov@google.comf7c00f62011-08-18 18:15:16 +000034 *this = other;
junov@google.comf93e7172011-03-31 21:26:24 +000035 }
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000036
37 GrTBinHashKey<Entry, KeySize>& operator=(const GrTBinHashKey<Entry, KeySize>& other) {
junov@google.comf7c00f62011-08-18 18:15:16 +000038 memcpy(this, &other, sizeof(*this));
39 return *this;
junov@google.comf93e7172011-03-31 21:26:24 +000040 }
41
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000042 ~GrTBinHashKey() {
43 }
44
45 void reset() {
46 fHash = 0;
47#if GR_DEBUG
48 fIsValid = false;
49#endif
junov@google.comf93e7172011-03-31 21:26:24 +000050 }
51
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +000052 void setKeyData(const uint32_t* SK_RESTRICT data) {
junov@google.comf7c00f62011-08-18 18:15:16 +000053 GrAssert(GrIsALIGN4(KeySize));
54 memcpy(&fData, data, KeySize);
55
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +000056 uint32_t hash = 0;
junov@google.comf7c00f62011-08-18 18:15:16 +000057 size_t len = KeySize;
58 while (len >= 4) {
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +000059 hash += *data++;
60 hash += (fHash << 10);
61 hash ^= (hash >> 6);
junov@google.comf7c00f62011-08-18 18:15:16 +000062 len -= 4;
junov@google.comf93e7172011-03-31 21:26:24 +000063 }
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +000064 hash += (fHash << 3);
65 hash ^= (fHash >> 11);
66 hash += (fHash << 15);
junov@google.comf7c00f62011-08-18 18:15:16 +000067#if GR_DEBUG
68 fIsValid = true;
69#endif
bsalomon@google.com6b5fdc12011-12-12 22:35:18 +000070 fHash = hash;
junov@google.comf93e7172011-03-31 21:26:24 +000071 }
72
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000073 int compare(const GrTBinHashKey<Entry, KeySize>& key) const {
junov@google.comf7c00f62011-08-18 18:15:16 +000074 GrAssert(fIsValid && key.fIsValid);
75 return memcmp(fData, key.fData, KeySize);
junov@google.comf93e7172011-03-31 21:26:24 +000076 }
77
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000078 static bool EQ(const Entry& entry, const GrTBinHashKey<Entry, KeySize>& key) {
junov@google.comf93e7172011-03-31 21:26:24 +000079 GrAssert(key.fIsValid);
80 return 0 == entry.compare(key);
81 }
tomhudson@google.com0d3f1fb2011-06-01 19:27:31 +000082
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000083 static bool LT(const Entry& entry, const GrTBinHashKey<Entry, KeySize>& key) {
junov@google.comf93e7172011-03-31 21:26:24 +000084 GrAssert(key.fIsValid);
tomhudson@google.com0d3f1fb2011-06-01 19:27:31 +000085 return entry.compare(key) < 0;
junov@google.comf93e7172011-03-31 21:26:24 +000086 }
87
88 uint32_t getHash() const {
89 GrAssert(fIsValid);
junov@google.comf7c00f62011-08-18 18:15:16 +000090 return fHash;
junov@google.comf93e7172011-03-31 21:26:24 +000091 }
92
93private:
junov@google.comf7c00f62011-08-18 18:15:16 +000094 uint32_t fHash;
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000095 uint8_t fData[KeySize]; // Buffer for key storage
junov@google.comf93e7172011-03-31 21:26:24 +000096
97#if GR_DEBUG
98public:
99 bool fIsValid;
100#endif
101};
102
103#endif