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 *  Hash function 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 */
20template<typename Entry, size_t KeySize>
21class GrBinHashKey {
22public:
23    GrBinHashKey()
24        : fHash(0)
25#if GR_DEBUG
26        , fIsValid(false)
27#endif
28    {}
29
30    GrBinHashKey(const GrBinHashKey<Entry, KeySize>& other) {
31        *this = other;
32    }
33    GrBinHashKey<Entry, KeySize>& operator=(const GrBinHashKey<Entry,
34        KeySize>& other) {
35        memcpy(this, &other, sizeof(*this));
36        return *this;
37    }
38
39    ~GrBinHashKey() {
40    }
41
42    void setKeyData(const uint32_t* SK_RESTRICT data) {
43        GrAssert(GrIsALIGN4(KeySize));
44        memcpy(&fData, data, KeySize);
45
46        uint32_t hash = 0;
47        size_t len = KeySize;
48        while (len >= 4) {
49            hash += *data++;
50            hash += (fHash << 10);
51            hash ^= (hash >> 6);
52            len -= 4;
53        }
54        hash += (fHash << 3);
55        hash ^= (fHash >> 11);
56        hash += (fHash << 15);
57#if GR_DEBUG
58        fIsValid = true;
59#endif
60        fHash = hash;
61    }
62
63    int compare(const GrBinHashKey<Entry, KeySize>& key) const {
64        GrAssert(fIsValid && key.fIsValid);
65        return memcmp(fData, key.fData, KeySize);
66    }
67
68    static bool
69    EQ(const Entry& entry, const GrBinHashKey<Entry, KeySize>& key) {
70        GrAssert(key.fIsValid);
71        return 0 == entry.compare(key);
72    }
73
74    static bool
75    LT(const Entry& entry, const GrBinHashKey<Entry, KeySize>& key) {
76        GrAssert(key.fIsValid);
77        return entry.compare(key) < 0;
78    }
79
80    uint32_t getHash() const {
81        GrAssert(fIsValid);
82        return fHash;
83    }
84
85private:
86    uint32_t            fHash;
87    uint8_t             fData[KeySize];  //Buffer for key storage
88
89#if GR_DEBUG
90public:
91    bool                fIsValid;
92#endif
93};
94
95#endif
96